summaryrefslogtreecommitdiffstats
path: root/sys/mips
diff options
context:
space:
mode:
authorgonzo <gonzo@FreeBSD.org>2012-03-15 05:29:51 +0000
committergonzo <gonzo@FreeBSD.org>2012-03-15 05:29:51 +0000
commit2a1b02c38986e95f47315ac6e0d2334ce2d6addf (patch)
treee2b2a934e81167d570f4763b947edb32ee8ee12a /sys/mips
parent9be115302d79f2ba9bf63e3aba1c82d4130492d5 (diff)
downloadFreeBSD-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.c50
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;
OpenPOWER on IntegriCloud