> > Could you send me the output of 'insmod -v -m freemware.o' ?
> Sections: Size Address Align
> .this 0000004c c2822000 2**2
> .rodata 00000829 c282204c 2**0
> __ex_table 00000010 c2822878 2**2
> .text 00003b05 c2822888 2**2
> .data 00000000 c2826390 2**2
> .kstrtab 0000000a c2826390 2**0
> .bss 000004c8 c282639c 2**2
Argh! It appears that recent insmod versions rearrange the section
sequence for some reason ... I'm starting to think that using the
linker script hack is a bad idea. Could you try the modified version
of retrieve_monitor_pages below, which doesn't rely on any linker
script at all?
Please apply this patch to the current CVS version, re-run ./configure
and delete the host-linux.ld file (to make sure it isn't used).
After running 'insmod -v -m freemware.o', check out the output
produced by the printk, and make sure that every page containing
any module code/data (according to the insmod map) is indeed
among those mapped by this routine.
Bye,
Ulrich
diff -ur freemware/kernel/Makefile fmw-uw/kernel/Makefile
--- freemware/kernel/Makefile Tue Dec 28 19:41:36 1999
+++ fmw-uw/kernel/Makefile Thu Dec 30 21:52:39 1999
@@ -30,7 +30,7 @@
# extra kernel CFLAGS and LDFLAGS for each host OS
KCFLAGS_LINUX = -D__KERNEL__ -I/usr/src/linux/include -DCPU=586 -DMODULE
-KLDFLAGS_LINUX = -r -T$(srcdir)/host-linux.ld
+KLDFLAGS_LINUX = -r
KCFLAGS_BEOS =
KLDFLAGS_BEOS = -nostdlib /boot/develop/lib/x86/_KERNEL_
diff -ur freemware/kernel/host-linux.c fmw-uw/kernel/host-linux.c
--- freemware/kernel/host-linux.c Tue Dec 28 19:39:08 1999
+++ fmw-uw/kernel/host-linux.c Thu Dec 30 21:51:13 1999
@@ -532,34 +532,29 @@
void
retrieve_monitor_pages(void)
{
- /* These symbols are defined by the host-linux.ld linker script */
- extern int freemware_start, freemware_end;
-
- int start_addr = (int)&freemware_start, end_addr = (int)&freemware_end;
- int start_page = start_addr >> 12, end_page = ((end_addr-1) >> 12) + 1;
- int n_pages = end_page - start_page;
- int i;
- u32 host_cr3;
- pageEntry_t *host_pgd;
-
- printk(KERN_WARNING "freemware: start: %08x end: %08x: init: %08x pages: %d\n",
- start_addr, end_addr, (unsigned)init_module, n_pages);
-
- if (n_pages > FMW_MAX_MONITOR_PAGES)
- {
- printk(KERN_WARNING "freemware: FMW_MAX_MONITOR_PAGES is too small!\n");
- return;
- }
-
- monitor_pages.start_addr = start_addr;
- monitor_pages.end_addr = end_addr;
- monitor_pages.n_pages = n_pages;
+ /*
+ * Retrieve start address and size of this module.
+ *
+ * Note that with old kernels, we cannot access the module info (size),
+ * hence we rely on the fact that Linux lets at least one page of
+ * virtual address space unused after the end of the module.
+ */
+#ifdef THIS_MODULE
+ int start_page = ((u32)THIS_MODULE) >> 12;
+ int n_pages = ((THIS_MODULE->size - 1) >> 12) + 1;
+#else
+ int start_page = ((u32)&mod_use_count_) >> 12;
+ int n_pages = FMW_MAX_MONITOR_PAGES + 1; /* Size determined below */
+#endif
/*
* Grrr. There doesn't seem to be an exported mechanism to retrieve
* the physical pages underlying a vmalloc()'ed area. We do it the
* hard way ...
*/
+ pageEntry_t *host_pgd;
+ u32 host_cr3;
+ int i;
asm volatile("movl %%cr3, %0" : "=r" (host_cr3));
host_pgd = (pageEntry_t *)(phys_to_virt(host_cr3 & ~0xfff));
@@ -570,12 +565,30 @@
pageEntry_t *pde = host_pgd + (virt_addr >> 22);
pageEntry_t *pte = (pageEntry_t *)phys_to_virt(pde->base << 12)
+ ((virt_addr >> 12) & 0x3ff);
+
+ /* If page isn't present, assume end of module */
+ if ( !pde->P || ! pte->P )
+ {
+ n_pages = i;
+ break;
+ }
+ /* Abort if our page list is too small */
+ if (i >= FMW_MAX_MONITOR_PAGES)
+ {
+ printk(KERN_WARNING "freemware: FMW_MAX_MONITOR_PAGES is too small!\n");
+ return;
+ }
+
monitor_pages.page[i] = pte->base << 12;
- //printk(KERN_WARNING "freemware: vm %08lx..%08lx -> page %08lx\n",
- // virt_addr, virt_addr + PAGE_SIZE-1, pte->base);
+ printk(KERN_WARNING "freemware: vm %08lx..%08lx -> page %08lx\n",
+ virt_addr, virt_addr + PAGE_SIZE-1, pte->base);
}
+
+ monitor_pages.start_addr = start_page << 12;
+ monitor_pages.end_addr = (start_page + n_pages) << 12;
+ monitor_pages.n_pages = n_pages;
}
void
--
Ulrich Weigand,
IMMD 1, Universitaet Erlangen-Nuernberg,
Martensstr. 3, D-91058 Erlangen, Phone: +49 9131 85-7688