On Mon, 3 Apr 2000, Mike Klar wrote:
> Mike Galbraith wrote:
>
> > On Sun, 2 Apr 2000, Mike Klar wrote:
> >
> > > .. I ran into the same
> > > problem while testing initrd recently, and the kernel decided
> > not to load
> > > the initrd image because initrd start address was >= top of
> > memory. Same
> > > line of code oopsed. In fact, loading the kernel with
> > root=/dev/ram without
> > > providing an initrd at all did the same thing.
> >
> > Greetings,
> >
> > Can you show me how you generated such an initrd load failure?
>
> Sure. I probably should have at least mentioned what I was using as a
> bootloader... 8^)
>
> These tests were done on a K6-2/450 system with 196MB DRAM, using
> 2.3.99-pre4-2 (.config below), but I expect the behavior has been similar
> for the last few versions. The ramdisk.img referenced below was the rescue
> root image from some distribution or other, probably SuSE 6.1, it does not
> have a linuxrc on it.
>
> initrd load refusal happened using linload from DOS, with a 4MB
> _uncompressed_ initrd image, while limiting the memory size to 12MB:
>
> linload zimage initrd=radisk.img root=/dev/ram mem=12MB
>
> Apparently, linload decided to put the initrd image starting at 12MB, which
> the kernel didn't take too kindly to, since as far as it knew, that was top
> of memory. Interestingly enough, the same command with the same ramdisk
> image, but compressed, seemed to put the initrd where the kernel could find
> it (but then it runs into a different problem later on, with bdflush).
The problem appears to be that when passing MEM=foo, that the bootloader
may set it up so that the initrd exactly fits (loadlin does).. ergo the
check in arch/i386/kernel/setup.c fails no matter what MEM is set to.
Below are two patches. The first fixes the above, and prevents oops
(fwtw) on ramdisk load failure. The second is a proposed fix for the
//FIXME in init/main.c and also removes a __init/__setup pair which
is also in rd.c.
Here, with MEM=12M, I have too little ram left to load a 3.7mb initrd
(uncompressed) because it basically ooms the box.. but that's another
story. It seems to be fine for anything larger.
-Mike
Diff1:
--- linux-2.3.99pre4-4/arch/i386/kernel/setup.c.org Wed Apr 5 09:12:00 2000
+++ linux-2.3.99pre4-4/arch/i386/kernel/setup.c Thu Apr 6 15:21:44 2000
@@ -727,7 +727,7 @@
#ifdef CONFIG_BLK_DEV_INITRD
if (LOADER_TYPE && INITRD_START) {
- if (INITRD_START + INITRD_SIZE < (max_low_pfn << PAGE_SHIFT)) {
+ if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
reserve_bootmem(INITRD_START, INITRD_SIZE);
initrd_start =
INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
--- linux-2.3.99pre4-4/drivers/block/rd.c.org Sat Mar 25 10:24:45 2000
+++ linux-2.3.99pre4-4/drivers/block/rd.c Thu Apr 6 15:21:44 2000
@@ -326,7 +326,7 @@
}
#endif
- if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS)
+ if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS || !inode->i_bdev)
return -ENXIO;
/*
Diff2:
--- linux-2.3.99pre4-4/init/main.c.org Sat Mar 25 10:24:55 2000
+++ linux-2.3.99pre4-4/init/main.c Thu Apr 6 15:23:46 2000
@@ -510,16 +510,14 @@
kmem_cache_init();
sti();
calibrate_delay();
-#if 0000
#ifdef CONFIG_BLK_DEV_INITRD
- // FIXME, use the bootmem.h interface.
- if (initrd_start && !initrd_below_start_ok && initrd_start < memory_start) {
+ if (initrd_start && !initrd_below_start_ok &&
+ initrd_start < min_low_pfn << PAGE_SHIFT) {
printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
- "disabling it.\n",initrd_start,memory_start);
+ "disabling it.\n",initrd_start,min_low_pfn << PAGE_SHIFT);
initrd_start = 0;
}
#endif
-#endif /* 0000 */
mem_init();
kmem_cache_sizes_init();
#ifdef CONFIG_PROC_FS
@@ -572,14 +570,6 @@
return execve(shell, argv, envp_init);
}
-static int __init no_initrd(char *s)
-{
- mount_initrd = 0;
- return 1;
-}
-
-__setup("noinitrd", no_initrd);
-
#endif
struct task_struct *child_reaper = &init_task;
--- linux-2.3.99pre4-4/mm/bootmem.c.org Sat Mar 25 10:23:43 2000
+++ linux-2.3.99pre4-4/mm/bootmem.c Thu Apr 6 15:21:44 2000
@@ -24,6 +24,7 @@
* true for the boot process anyway)
*/
unsigned long max_low_pfn;
+unsigned long min_low_pfn;
/* return the number of _pages_ that will be allocated for the boot bitmap */
unsigned long __init bootmem_bootmap_pages (unsigned long pages)
@@ -282,6 +283,7 @@
unsigned long __init init_bootmem (unsigned long start, unsigned long pages)
{
max_low_pfn = pages;
+ min_low_pfn = start;
return(init_bootmem_core(NODE_DATA(0)->bdata, start, 0, pages));
}
--- linux-2.3.99pre4-4/include/linux/bootmem.h.org Sun Mar 26 09:06:37 2000
+++ linux-2.3.99pre4-4/include/linux/bootmem.h Thu Apr 6 15:21:44 2000
@@ -14,6 +14,7 @@
*/
extern unsigned long max_low_pfn;
+extern unsigned long min_low_pfn;
/*
* node_bootmem_map is a map pointer - the bits represent all physical
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Fri Apr 07 2000 - 21:00:16 EST