diff options
author | gonzo <gonzo@FreeBSD.org> | 2012-03-15 05:29:51 +0000 |
---|---|---|
committer | gonzo <gonzo@FreeBSD.org> | 2012-03-15 05:29:51 +0000 |
commit | 2a1b02c38986e95f47315ac6e0d2334ce2d6addf (patch) | |
tree | e2b2a934e81167d570f4763b947edb32ee8ee12a /sys/mips | |
parent | 9be115302d79f2ba9bf63e3aba1c82d4130492d5 (diff) | |
download | FreeBSD-src-2a1b02c38986e95f47315ac6e0d2334ce2d6addf.zip FreeBSD-src-2a1b02c38986e95f47315ac6e0d2334ce2d6addf.tar.gz |
Fill out fake preload structure to let userland tools like pmc(3) know
about kernel module base address and actual size
Diffstat (limited to 'sys/mips')
-rw-r--r-- | sys/mips/mips/machdep.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index 8a9fabe..21b85c5 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -380,6 +380,56 @@ mips_vector_init(void) void mips_postboot_fixup(void) { + static char fake_preload[256]; + caddr_t preload_ptr = (caddr_t)&fake_preload[0]; + size_t size = 0; + + /* + * Provide kernel module file information + */ + *(uint32_t*)(preload_ptr + size) = MODINFO_NAME; + size += sizeof(uint32_t); + *(uint32_t*)(preload_ptr + size) = strlen("kernel") + 1; + size += sizeof(uint32_t); + strcpy((char*)(preload_ptr + size), "kernel"); + size += strlen("kernel") + 1; + size = roundup(size, sizeof(u_long)); + + *(uint32_t*)(preload_ptr + size) = MODINFO_TYPE; + size += sizeof(uint32_t); + *(uint32_t*)(preload_ptr + size) = strlen("elf kernel") + 1; + size += sizeof(uint32_t); + strcpy((char*)(preload_ptr + size), "elf kernel"); + size += strlen("elf kernel") + 1; + size = roundup(size, sizeof(u_long)); + + *(uint32_t*)(preload_ptr + size) = MODINFO_ADDR; + size += sizeof(uint32_t); + *(uint32_t*)(preload_ptr + size) = sizeof(vm_offset_t); + size += sizeof(uint32_t); + *(vm_offset_t*)(preload_ptr + size) = KERNLOADADDR; + size += sizeof(vm_offset_t); + size = roundup(size, sizeof(u_long)); + + *(uint32_t*)(preload_ptr + size) = MODINFO_SIZE; + size += sizeof(uint32_t); + *(uint32_t*)(preload_ptr + size) = sizeof(size_t); + size += sizeof(uint32_t); + *(vm_offset_t*)(preload_ptr + size) = (size_t)&end - KERNLOADADDR; + size = roundup(size, sizeof(u_long)); + size += sizeof(size_t); + + /* End marker */ + *(uint32_t*)(preload_ptr + size) = 0; + size += sizeof(uint32_t); + *(uint32_t*)(preload_ptr + size) = 0; + size += sizeof(uint32_t); + + KASSERT((size < sizeof(fake_preload)), + ("fake preload size is more thenallocated")); + + preload_metadata = (void *)fake_preload; + #ifdef DDB Elf_Size *trampoline_data = (Elf_Size*)kernel_kseg0_end; Elf_Size symtabsize = 0; |