diff options
author | Uwe Stuehler <uwe@cvs.openbsd.org> | 2005-05-02 02:45:30 +0000 |
---|---|---|
committer | Uwe Stuehler <uwe@cvs.openbsd.org> | 2005-05-02 02:45:30 +0000 |
commit | ed68d0255b03fd320dbfad42ca84b1256419ec87 (patch) | |
tree | fb0c7da52f7b2be5443f5287e8f49ea0b32ac27a /sys/arch/zaurus | |
parent | 64cb74f62cc1c60bccfa61b3d8384f2f134b918e (diff) |
Load the symbol table to the end of data/bss, and account for it when
setting up the kernel page table. Makes ddb more usable (when used
together with an unrotated console :)
Diffstat (limited to 'sys/arch/zaurus')
-rw-r--r-- | sys/arch/zaurus/stand/zbsdmod/zbsdmod.c | 153 | ||||
-rw-r--r-- | sys/arch/zaurus/zaurus/zaurus_machdep.c | 17 |
2 files changed, 146 insertions, 24 deletions
diff --git a/sys/arch/zaurus/stand/zbsdmod/zbsdmod.c b/sys/arch/zaurus/stand/zbsdmod/zbsdmod.c index 7a183a3bd5a..c8e80d20083 100644 --- a/sys/arch/zaurus/stand/zbsdmod/zbsdmod.c +++ b/sys/arch/zaurus/stand/zbsdmod/zbsdmod.c @@ -1,4 +1,4 @@ -/* $OpenBSD: zbsdmod.c,v 1.6 2005/03/29 19:44:12 uwe Exp $ */ +/* $OpenBSD: zbsdmod.c,v 1.7 2005/05/02 02:45:29 uwe Exp $ */ /* * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de> @@ -60,10 +60,16 @@ static int isopen; static loff_t position; /* Outcast local variables to avoid stack usage in elf32bsdboot(). */ +static int cpsr; static unsigned int sz; static int i; -static vaddr_t minv; +static vaddr_t minv, maxv, posv; +static vaddr_t elfv, shpv; static int *addr; +static vaddr_t *esymp; +static Elf_Shdr *shp; +static Elf_Off off; +static int havesyms; /* The maximum size of a kernel image is restricted to 5MB. */ static int bsdimage[1310720]; /* XXX use kmalloc() */ @@ -76,7 +82,6 @@ static char bootargs[BOOTARGS_BUFSIZ]; void elf32bsdboot(void) { - int cpsr; #define elf ((Elf32_Ehdr *)bsdimage) #define phdr ((Elf32_Phdr *)((char *)elf + elf->e_phoff)) @@ -85,12 +90,14 @@ elf32bsdboot(void) elf->e_ident[EI_CLASS] != ELFCLASS32) return; - __asm__ volatile ("mrs %0, cpsr_all" : "=r" (cpsr)); - cpsr |= 0xc0; /* set FI */ - __asm__ volatile ("msr cpsr_all, %0" :: "r" (cpsr)); - minv = (vaddr_t)~0; + maxv = (vaddr_t)0; + posv = (vaddr_t)0; + esymp = 0; + /* + * Get min and max addresses used by the loaded kernel. + */ for (i = 0; i < elf->e_phnum; i++) { if (phdr[i].p_type != PT_LOAD || @@ -104,23 +111,139 @@ elf32bsdboot(void) * XXX: Assume first address is lowest */ if (IS_TEXT(phdr[i]) || IS_DATA(phdr[i])) { - sz = phdr[i].p_filesz; - while (sz > 0) { - sz--; - ((char *)phdr[i].p_vaddr)[sz] = - (((char *)elf) + phdr[i].p_offset)[sz]; - if (minv > phdr[i].p_vaddr) - minv = phdr[i].p_vaddr; - } + posv = phdr[i].p_vaddr; + if (minv > posv) + minv = posv; + posv += phdr[i].p_filesz; + if (maxv < posv) + maxv = posv; } + if (IS_DATA(phdr[i]) && IS_BSS(phdr[i])) { + posv += phdr[i].p_memsz; + if (maxv < posv) + maxv = posv; + } + /* + * 'esym' is the first word in the .data section, + * and marks the end of the symbol table. + */ + if (IS_DATA(phdr[i]) && !IS_BSS(phdr[i])) + esymp = (vaddr_t *)phdr[i].p_vaddr; } + __asm__ volatile ("mrs %0, cpsr_all" : "=r" (cpsr)); + cpsr |= 0xc0; /* set FI */ + __asm__ volatile ("msr cpsr_all, %0" :: "r" (cpsr)); + + /* + * Copy the boot arguments. + */ sz = BOOTARGS_BUFSIZ; while (sz > 0) { sz--; ((char *)minv - BOOTARGS_BUFSIZ)[sz] = bootargs[sz]; } + /* + * Set up pointers to copied ELF and section headers. + */ +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) + elfv = maxv = roundup(maxv, sizeof(long)); + maxv += sizeof(Elf_Ehdr); + + sz = elf->e_shnum * sizeof(Elf_Shdr); + shp = (Elf_Shdr *)((vaddr_t)elf + elf->e_shoff); + shpv = maxv; + maxv += roundup(sz, sizeof(long)); + + /* + * Now load the symbol sections themselves. Make sure the + * sections are aligned, and offsets are relative to the + * copied ELF header. Don't bother with string tables if + * there are no symbol sections. + */ + off = roundup((sizeof(Elf_Ehdr) + sz), sizeof(long)); + for (havesyms = i = 0; i < elf->e_shnum; i++) + if (shp[i].sh_type == SHT_SYMTAB) + havesyms = 1; + for (i = 0; i < elf->e_shnum; i++) { + if (shp[i].sh_type == SHT_SYMTAB || + shp[i].sh_type == SHT_STRTAB) { + if (havesyms) { + sz = shp[i].sh_size; + while (sz > 0) { + sz--; + ((char *)maxv)[sz] = + ((char *)elf + + shp[i].sh_offset)[sz]; + } + } + maxv += roundup(shp[i].sh_size, sizeof(long)); + shp[i].sh_offset = off; + off += roundup(shp[i].sh_size, sizeof(long)); + } + } + + /* + * Copy the ELF and section headers. + */ + sz = sizeof(Elf_Ehdr); + while (sz > 0) { + sz--; + ((char *)elfv)[sz] = ((char *)elf)[sz]; + } + sz = elf->e_shnum * sizeof(Elf_Shdr); + while (sz > 0) { + sz--; + ((char *)shpv)[sz] = ((char *)shp)[sz]; + } + + /* + * Frob the copied ELF header to give information relative + * to elfv. + */ + ((Elf_Ehdr *)elfv)->e_phoff = 0; + ((Elf_Ehdr *)elfv)->e_shoff = sizeof(Elf_Ehdr); + ((Elf_Ehdr *)elfv)->e_phentsize = 0; + ((Elf_Ehdr *)elfv)->e_phnum = 0; + + /* + * Tell locore.S where the symbol table ends, and arrange + * to skip esym when loading the data section. + */ + if (esymp != 0) + *esymp = (vaddr_t)maxv; + for (i = 0; esymp != 0 && i < elf->e_phnum; i++) { + if (phdr[i].p_type != PT_LOAD || + (phdr[i].p_flags & (PF_W|PF_R|PF_X)) == 0) + continue; + if (phdr[i].p_vaddr == (vaddr_t)esymp) { + phdr[i].p_vaddr = (vaddr_t)((char *)phdr[i].p_vaddr + sizeof(long)); + phdr[i].p_offset = (vaddr_t)((char *)phdr[i].p_offset + sizeof(long)); + phdr[i].p_filesz -= sizeof(long); + break; + } + } + + /* + * Load text and data. + */ + for (i = 0; i < elf->e_phnum; i++) { + + if (phdr[i].p_type != PT_LOAD || + (phdr[i].p_flags & (PF_W|PF_R|PF_X)) == 0) + continue; + + if (IS_TEXT(phdr[i]) || IS_DATA(phdr[i])) { + sz = phdr[i].p_filesz; + while (sz > 0) { + sz--; + ((char *)phdr[i].p_vaddr)[sz] = + (((char *)elf) + phdr[i].p_offset)[sz]; + } + } + } + addr = (int *)(elf->e_entry); __asm__ volatile ( "mov r0, %0;" diff --git a/sys/arch/zaurus/zaurus/zaurus_machdep.c b/sys/arch/zaurus/zaurus/zaurus_machdep.c index f771cfe2d79..ffcf3e41763 100644 --- a/sys/arch/zaurus/zaurus/zaurus_machdep.c +++ b/sys/arch/zaurus/zaurus/zaurus_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: zaurus_machdep.c,v 1.13 2005/04/11 03:22:59 uwe Exp $ */ +/* $OpenBSD: zaurus_machdep.c,v 1.14 2005/05/02 02:45:29 uwe Exp $ */ /* $NetBSD: lubbock_machdep.c,v 1.2 2003/07/15 00:25:06 lukem Exp $ */ /* @@ -547,6 +547,7 @@ initarm(void *arg) pv_addr_t kernel_l1pt; paddr_t memstart; psize_t memsize; + extern u_int32_t esym; /* &_end if no symbols are loaded */ #if 0 int led_data = 0; @@ -917,11 +918,12 @@ initarm(void *arg) printf("Mapping kernel\n"); #endif - /* Now we fill in the L2 pagetable for the kernel static code/data */ + /* Now we fill in the L2 pagetable for the kernel static code/data + * and the symbol table. */ { - extern char etext[], _end[]; + extern char etext[]; size_t textsize = (u_int32_t) etext - KERNEL_TEXT_BASE; - size_t totalsize = (u_int32_t) _end - KERNEL_TEXT_BASE; + size_t totalsize = esym - KERNEL_TEXT_BASE; u_int logical; textsize = (textsize + PGOFSET) & ~PGOFSET; @@ -932,7 +934,7 @@ initarm(void *arg) logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical, physical_start + logical, textsize, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); - logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical, + pmap_map_chunk(l1pagetable, KERNEL_BASE + logical, physical_start + logical, totalsize - textsize, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); } @@ -999,11 +1001,8 @@ initarm(void *arg) * variables. */ { - extern char _end[]; - physical_freestart = physical_start + - (((((u_int32_t) _end) + PGOFSET) & ~PGOFSET) - - KERNEL_BASE); + (((esym + PGOFSET) & ~PGOFSET) - KERNEL_BASE); physical_freeend = physical_end; free_pages = (physical_freeend - physical_freestart) / PAGE_SIZE; |