summaryrefslogtreecommitdiff
path: root/sys/arch/zaurus
diff options
context:
space:
mode:
authorUwe Stuehler <uwe@cvs.openbsd.org>2005-05-02 02:45:30 +0000
committerUwe Stuehler <uwe@cvs.openbsd.org>2005-05-02 02:45:30 +0000
commited68d0255b03fd320dbfad42ca84b1256419ec87 (patch)
treefb0c7da52f7b2be5443f5287e8f49ea0b32ac27a /sys/arch/zaurus
parent64cb74f62cc1c60bccfa61b3d8384f2f134b918e (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.c153
-rw-r--r--sys/arch/zaurus/zaurus/zaurus_machdep.c17
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;