* Enable dynamically linked kernel. This involves adding a self-relocator
to locore to process the @fptr relocations in the dynamic executable. * Don't initialise the timer until *after* we install the timecounter to avoid a race between timecounter initialisation and hardclock. * Tidy up bootinfo somewhat including adding sanity checks for when the kernel is loaded without a recognisable bootinfo.
This commit is contained in:
parent
ed1e8460bd
commit
0b02d706db
@ -105,7 +105,7 @@ SYSTEM_CFILES= vnode_if.c hints.c env.c config.c
|
||||
SYSTEM_SFILES= $S/$M/$M/locore.s
|
||||
SYSTEM_DEP= Makefile ${SYSTEM_OBJS}
|
||||
SYSTEM_OBJS= locore.o vnode_if.o ${OBJS} hints.o env.o config.o \
|
||||
# hack.So ski can't cope with dynamic relocs
|
||||
hack.So
|
||||
SYSTEM_LD= @${LD} ${FMT} -Bdynamic -T $S/conf/ldscript.$M \
|
||||
-export-dynamic -dynamic-linker /red/herring \
|
||||
-o ${.TARGET} -X ${SYSTEM_OBJS} vers.o
|
||||
|
@ -180,8 +180,6 @@ cpu_initclocks()
|
||||
* XXX we should call SAL_FREQ_BASE_INTERVAL_TIMER here.
|
||||
*/
|
||||
cycles_per_sec = 70000000;
|
||||
ia64_set_itm(ia64_get_itc() + (cycles_per_sec + hz/2) / hz);
|
||||
ia64_set_itv(240); /* highest priority class */
|
||||
|
||||
freq = cycles_per_sec;
|
||||
last_time = ia64_get_itc();
|
||||
@ -191,6 +189,9 @@ cpu_initclocks()
|
||||
ia64_timecounter.tc_frequency = freq;
|
||||
tc_init(&ia64_timecounter);
|
||||
|
||||
ia64_set_itm(ia64_get_itc() + (cycles_per_sec + hz/2) / hz);
|
||||
ia64_set_itv(240); /* highest priority class */
|
||||
|
||||
stathz = 128;
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include <sys/ucontext.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/mutex.h>
|
||||
#include <machine/elf.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
@ -139,3 +140,14 @@ ASSYM(KSTACK_PAGES, KSTACK_PAGES);
|
||||
|
||||
ASSYM(SIZEOF_TRAPFRAME, sizeof(struct trapframe));
|
||||
ASSYM(SIZEOF_PCB, sizeof(struct pcb));
|
||||
|
||||
ASSYM(DT_NULL, DT_NULL);
|
||||
ASSYM(DT_RELA, DT_RELA);
|
||||
ASSYM(DT_RELASZ, DT_RELASZ);
|
||||
ASSYM(DT_SYMTAB, DT_SYMTAB);
|
||||
ASSYM(DT_SYMENT, DT_SYMENT);
|
||||
ASSYM(DT_RELAENT, DT_RELAENT);
|
||||
ASSYM(R_IA64_NONE, R_IA64_NONE);
|
||||
ASSYM(R_IA64_DIR64LSB, R_IA64_DIR64LSB);
|
||||
ASSYM(R_IA64_FPTR64LSB, R_IA64_FPTR64LSB);
|
||||
ASSYM(R_IA64_REL64LSB, R_IA64_REL64LSB);
|
||||
|
@ -98,6 +98,12 @@ ENTRY(__start, 1)
|
||||
;;
|
||||
mov ar.rsc=3 // turn rse back on
|
||||
;;
|
||||
alloc r16=ar.pfs,0,0,1,0
|
||||
;;
|
||||
movl out0=0 // we are linked at the right address
|
||||
;; // we just need to process fptrs
|
||||
br.call.sptk.many rp=_reloc
|
||||
;;
|
||||
br.call.sptk.many rp=ia64_init
|
||||
|
||||
/*
|
||||
@ -219,3 +225,129 @@ EXPORT(intrcnt)
|
||||
.fill INTRCNT_COUNT + 1, 8, 0
|
||||
EXPORT(eintrcnt)
|
||||
.text
|
||||
|
||||
// in0: image base
|
||||
STATIC_ENTRY(_reloc, 1)
|
||||
alloc loc0=ar.pfs,1,2,0,0
|
||||
mov loc1=rp
|
||||
;;
|
||||
movl r15=@gprel(_DYNAMIC) // find _DYNAMIC etc.
|
||||
movl r2=@gprel(fptr_storage)
|
||||
movl r3=@gprel(fptr_storage_end)
|
||||
;;
|
||||
add r15=r15,gp // relocate _DYNAMIC etc.
|
||||
add r2=r2,gp
|
||||
add r3=r3,gp
|
||||
;;
|
||||
1: ld8 r16=[r15],8 // read r15->d_tag
|
||||
;;
|
||||
ld8 r17=[r15],8 // and r15->d_val
|
||||
;;
|
||||
cmp.eq p6,p0=DT_NULL,r16 // done?
|
||||
(p6) br.cond.dpnt.few 2f
|
||||
;;
|
||||
cmp.eq p6,p0=DT_RELA,r16
|
||||
;;
|
||||
(p6) add r18=r17,in0 // found rela section
|
||||
;;
|
||||
cmp.eq p6,p0=DT_RELASZ,r16
|
||||
;;
|
||||
(p6) mov r19=r17 // found rela size
|
||||
;;
|
||||
cmp.eq p6,p0=DT_SYMTAB,r16
|
||||
;;
|
||||
(p6) add r20=r17,in0 // found symbol table
|
||||
;;
|
||||
(p6) setf.sig f8=r20
|
||||
;;
|
||||
cmp.eq p6,p0=DT_SYMENT,r16
|
||||
;;
|
||||
(p6) setf.sig f9=r17 // found symbol entry size
|
||||
;;
|
||||
cmp.eq p6,p0=DT_RELAENT,r16
|
||||
;;
|
||||
(p6) mov r22=r17 // found rela entry size
|
||||
;;
|
||||
br.sptk.few 1b
|
||||
|
||||
2:
|
||||
ld8 r15=[r18],8 // read r_offset
|
||||
;;
|
||||
ld8 r16=[r18],8 // read r_info
|
||||
add r15=r15,in0 // relocate r_offset
|
||||
;;
|
||||
ld8 r17=[r18],8 // read r_addend
|
||||
sub r19=r19,r22 // update relasz
|
||||
|
||||
extr.u r23=r16,0,32 // ELF64_R_TYPE(r16)
|
||||
;;
|
||||
cmp.eq p6,p0=R_IA64_NONE,r23
|
||||
(p6) br.cond.dpnt.few 3f
|
||||
;;
|
||||
cmp.eq p6,p0=R_IA64_DIR64LSB,r23
|
||||
;;
|
||||
(p6) br.cond.dptk.few 4f
|
||||
;;
|
||||
cmp.eq p6,p0=R_IA64_FPTR64LSB,r23
|
||||
;;
|
||||
(p6) br.cond.dptk.few 5f
|
||||
;;
|
||||
cmp.eq p6,p0=R_IA64_REL64LSB,r23
|
||||
;;
|
||||
(p6) br.cond.dptk.few 4f
|
||||
;;
|
||||
|
||||
3: cmp.ltu p6,p0=0,r19 // more?
|
||||
(p6) br.cond.dptk.few 2b // loop
|
||||
|
||||
mov r8=0 // success return value
|
||||
;;
|
||||
br.cond.sptk.few 9f // done
|
||||
|
||||
4:
|
||||
ld8 r16=[r15] // read value
|
||||
;;
|
||||
add r16=r16,in0 // relocate it
|
||||
;;
|
||||
st8 [r15]=r16 // and store it back
|
||||
br.cond.sptk.few 3b
|
||||
|
||||
5:
|
||||
extr.u r23=r16,32,32 // ELF64_R_SYM(r16)
|
||||
;;
|
||||
setf.sig f10=r23 // so we can multiply
|
||||
;;
|
||||
xma.lu f10=f10,f9,f8 // f10=symtab + r_sym*syment
|
||||
;;
|
||||
getf.sig r16=f10
|
||||
mov r8=1 // failure return value
|
||||
;;
|
||||
cmp.geu p6,p0=r2,r3 // space left?
|
||||
(p6) br.cond.dpnt.few 9f // bail out
|
||||
|
||||
st8 [r15]=r2 // install fptr
|
||||
add r16=8,r16 // address of st_value
|
||||
;;
|
||||
ld8 r16=[r16] // read symbol value
|
||||
;;
|
||||
add r16=r16,in0 // relocate symbol value
|
||||
;;
|
||||
st8 [r2]=r16,8 // write fptr address
|
||||
;;
|
||||
st8 [r2]=gp,8 // write fptr gp
|
||||
br.cond.sptk.few 3b
|
||||
|
||||
9:
|
||||
mov ar.pfs=loc0
|
||||
mov rp=loc1
|
||||
;;
|
||||
br.ret.sptk.few rp
|
||||
|
||||
END(_reloc)
|
||||
|
||||
.data
|
||||
.align 16
|
||||
|
||||
fptr_storage:
|
||||
.space 4096*16 // XXX
|
||||
fptr_storage_end:
|
||||
|
@ -98,6 +98,12 @@ ENTRY(__start, 1)
|
||||
;;
|
||||
mov ar.rsc=3 // turn rse back on
|
||||
;;
|
||||
alloc r16=ar.pfs,0,0,1,0
|
||||
;;
|
||||
movl out0=0 // we are linked at the right address
|
||||
;; // we just need to process fptrs
|
||||
br.call.sptk.many rp=_reloc
|
||||
;;
|
||||
br.call.sptk.many rp=ia64_init
|
||||
|
||||
/*
|
||||
@ -219,3 +225,129 @@ EXPORT(intrcnt)
|
||||
.fill INTRCNT_COUNT + 1, 8, 0
|
||||
EXPORT(eintrcnt)
|
||||
.text
|
||||
|
||||
// in0: image base
|
||||
STATIC_ENTRY(_reloc, 1)
|
||||
alloc loc0=ar.pfs,1,2,0,0
|
||||
mov loc1=rp
|
||||
;;
|
||||
movl r15=@gprel(_DYNAMIC) // find _DYNAMIC etc.
|
||||
movl r2=@gprel(fptr_storage)
|
||||
movl r3=@gprel(fptr_storage_end)
|
||||
;;
|
||||
add r15=r15,gp // relocate _DYNAMIC etc.
|
||||
add r2=r2,gp
|
||||
add r3=r3,gp
|
||||
;;
|
||||
1: ld8 r16=[r15],8 // read r15->d_tag
|
||||
;;
|
||||
ld8 r17=[r15],8 // and r15->d_val
|
||||
;;
|
||||
cmp.eq p6,p0=DT_NULL,r16 // done?
|
||||
(p6) br.cond.dpnt.few 2f
|
||||
;;
|
||||
cmp.eq p6,p0=DT_RELA,r16
|
||||
;;
|
||||
(p6) add r18=r17,in0 // found rela section
|
||||
;;
|
||||
cmp.eq p6,p0=DT_RELASZ,r16
|
||||
;;
|
||||
(p6) mov r19=r17 // found rela size
|
||||
;;
|
||||
cmp.eq p6,p0=DT_SYMTAB,r16
|
||||
;;
|
||||
(p6) add r20=r17,in0 // found symbol table
|
||||
;;
|
||||
(p6) setf.sig f8=r20
|
||||
;;
|
||||
cmp.eq p6,p0=DT_SYMENT,r16
|
||||
;;
|
||||
(p6) setf.sig f9=r17 // found symbol entry size
|
||||
;;
|
||||
cmp.eq p6,p0=DT_RELAENT,r16
|
||||
;;
|
||||
(p6) mov r22=r17 // found rela entry size
|
||||
;;
|
||||
br.sptk.few 1b
|
||||
|
||||
2:
|
||||
ld8 r15=[r18],8 // read r_offset
|
||||
;;
|
||||
ld8 r16=[r18],8 // read r_info
|
||||
add r15=r15,in0 // relocate r_offset
|
||||
;;
|
||||
ld8 r17=[r18],8 // read r_addend
|
||||
sub r19=r19,r22 // update relasz
|
||||
|
||||
extr.u r23=r16,0,32 // ELF64_R_TYPE(r16)
|
||||
;;
|
||||
cmp.eq p6,p0=R_IA64_NONE,r23
|
||||
(p6) br.cond.dpnt.few 3f
|
||||
;;
|
||||
cmp.eq p6,p0=R_IA64_DIR64LSB,r23
|
||||
;;
|
||||
(p6) br.cond.dptk.few 4f
|
||||
;;
|
||||
cmp.eq p6,p0=R_IA64_FPTR64LSB,r23
|
||||
;;
|
||||
(p6) br.cond.dptk.few 5f
|
||||
;;
|
||||
cmp.eq p6,p0=R_IA64_REL64LSB,r23
|
||||
;;
|
||||
(p6) br.cond.dptk.few 4f
|
||||
;;
|
||||
|
||||
3: cmp.ltu p6,p0=0,r19 // more?
|
||||
(p6) br.cond.dptk.few 2b // loop
|
||||
|
||||
mov r8=0 // success return value
|
||||
;;
|
||||
br.cond.sptk.few 9f // done
|
||||
|
||||
4:
|
||||
ld8 r16=[r15] // read value
|
||||
;;
|
||||
add r16=r16,in0 // relocate it
|
||||
;;
|
||||
st8 [r15]=r16 // and store it back
|
||||
br.cond.sptk.few 3b
|
||||
|
||||
5:
|
||||
extr.u r23=r16,32,32 // ELF64_R_SYM(r16)
|
||||
;;
|
||||
setf.sig f10=r23 // so we can multiply
|
||||
;;
|
||||
xma.lu f10=f10,f9,f8 // f10=symtab + r_sym*syment
|
||||
;;
|
||||
getf.sig r16=f10
|
||||
mov r8=1 // failure return value
|
||||
;;
|
||||
cmp.geu p6,p0=r2,r3 // space left?
|
||||
(p6) br.cond.dpnt.few 9f // bail out
|
||||
|
||||
st8 [r15]=r2 // install fptr
|
||||
add r16=8,r16 // address of st_value
|
||||
;;
|
||||
ld8 r16=[r16] // read symbol value
|
||||
;;
|
||||
add r16=r16,in0 // relocate symbol value
|
||||
;;
|
||||
st8 [r2]=r16,8 // write fptr address
|
||||
;;
|
||||
st8 [r2]=gp,8 // write fptr gp
|
||||
br.cond.sptk.few 3b
|
||||
|
||||
9:
|
||||
mov ar.pfs=loc0
|
||||
mov rp=loc1
|
||||
;;
|
||||
br.ret.sptk.few rp
|
||||
|
||||
END(_reloc)
|
||||
|
||||
.data
|
||||
.align 16
|
||||
|
||||
fptr_storage:
|
||||
.space 4096*16 // XXX
|
||||
fptr_storage_end:
|
||||
|
@ -386,17 +386,24 @@ ia64_init()
|
||||
|
||||
/* OUTPUT NOW ALLOWED */
|
||||
|
||||
/*
|
||||
* Gross and disgusting hack. The bootinfo is written into
|
||||
* memory at a fixed address.
|
||||
*/
|
||||
bootinfo = *(struct bootinfo *) 0xe000000000508000;
|
||||
if (bootinfo.bi_magic != BOOTINFO_MAGIC
|
||||
|| bootinfo.bi_version != 1) {
|
||||
bzero(&bootinfo, sizeof(bootinfo));
|
||||
bootinfo.bi_kernend = (vm_offset_t) round_page(_end);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the beginning and end of the kernel.
|
||||
*/
|
||||
kernstart = trunc_page(kernel_text);
|
||||
#ifdef DDBxx
|
||||
ksym_start = (void *)bootinfo.bi_symtab;
|
||||
ksym_end = (void *)bootinfo.bi_esymtab;
|
||||
kernend = (vm_offset_t)round_page(ksym_end);
|
||||
#else
|
||||
kernend = (vm_offset_t)round_page(_end);
|
||||
#endif
|
||||
/* But if the bootstrap tells us otherwise, believe it! */
|
||||
if (bootinfo.bi_kernend)
|
||||
kernend = round_page(bootinfo.bi_kernend);
|
||||
@ -606,74 +613,10 @@ ia64_init()
|
||||
/*
|
||||
* Look at arguments passed to us and compute boothowto.
|
||||
*/
|
||||
boothowto = 0;
|
||||
boothowto = bootinfo.bi_boothowto;
|
||||
#ifdef KADB
|
||||
boothowto |= RB_KDB;
|
||||
#endif
|
||||
/* boothowto |= RB_KDB | RB_GDB; */
|
||||
for (p = bootinfo.bi_flags; p && *p != '\0'; p++) {
|
||||
/*
|
||||
* Note that we'd really like to differentiate case here,
|
||||
* but the Ia64 AXP Architecture Reference Manual
|
||||
* says that we shouldn't.
|
||||
*/
|
||||
switch (*p) {
|
||||
case 'a': /* autoboot */
|
||||
case 'A':
|
||||
boothowto &= ~RB_SINGLE;
|
||||
break;
|
||||
|
||||
#ifdef DEBUG
|
||||
case 'c': /* crash dump immediately after autoconfig */
|
||||
case 'C':
|
||||
boothowto |= RB_DUMP;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(DDB)
|
||||
case 'd': /* break into the kernel debugger ASAP */
|
||||
case 'D':
|
||||
boothowto |= RB_KDB;
|
||||
break;
|
||||
case 'g': /* use kernel gdb */
|
||||
case 'G':
|
||||
boothowto |= RB_GDB;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'h': /* always halt, never reboot */
|
||||
case 'H':
|
||||
boothowto |= RB_HALT;
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case 'm': /* mini root present in memory */
|
||||
case 'M':
|
||||
boothowto |= RB_MINIROOT;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'n': /* askname */
|
||||
case 'N':
|
||||
boothowto |= RB_ASKNAME;
|
||||
break;
|
||||
|
||||
case 's': /* single-user (default, supported for sanity) */
|
||||
case 'S':
|
||||
boothowto |= RB_SINGLE;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
case 'V':
|
||||
boothowto |= RB_VERBOSE;
|
||||
bootverbose = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unrecognized boot flag '%c'.\n", *p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Catch case of boot_verbose set in environment.
|
||||
@ -681,10 +624,12 @@ ia64_init()
|
||||
if ((p = getenv("boot_verbose")) != NULL) {
|
||||
if (strcmp(p, "yes") == 0 || strcmp(p, "YES") == 0) {
|
||||
boothowto |= RB_VERBOSE;
|
||||
bootverbose = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (boothowto & RB_VERBOSE)
|
||||
bootverbose = 1;
|
||||
|
||||
/*
|
||||
* Force single-user for a while.
|
||||
*/
|
||||
|
@ -41,9 +41,13 @@
|
||||
* (u_long), then the bootinfo
|
||||
*/
|
||||
|
||||
#define BOOTINFO_MAGIC 0xdeadbeeffeedface
|
||||
|
||||
struct bootinfo {
|
||||
char bi_flags[64]; /* boot flags */
|
||||
u_int64_t bi_magic; /* BOOTINFO_MAGIC */
|
||||
u_int64_t bi_version; /* version 1 */
|
||||
char bi_kernel[64]; /* name of booted kernel */
|
||||
u_int64_t bi_boothowto; /* value for boothowto */
|
||||
u_int64_t bi_systab; /* pa of EFI system table */
|
||||
u_int64_t bi_memmap; /* pa of EFI memory map */
|
||||
u_int64_t bi_memmap_size; /* size of EFI memory map */
|
||||
|
Loading…
x
Reference in New Issue
Block a user