initrd problem
Background:
I'm trying to get 2.6.11 to run on a MIPS Malta board with Yamon. The kernel that comes with the board is 2.4.18 with an embedded ramdisk that runs some scripts to install RPMS via NFS or CD-ROM. The kernel is converted to s-records via objcopy(1), and loaded into memory via tftp. I want to do something similar with 2.6.latest.
Problem:
On or about Nov 21 of last year, the CONFIG_EMBEDDED_RAMDISK disappeared.
http://www.linux-mips.org/archives/linux-mips/2004-11/msg00135.html
In it's place it is suggested to use the tools in arch/mips/boot, so I tried it. I can cross-compile the kernel, and I get an ELF vmlinux. I can convert it to ecoff with elf2ecoff, and attach an initrd image with addinitrd. The problem begins here. I end up with an ecoff format kernel which is not recognized by objcopy(1), and therefore no s-records.
It seems there is a program called gensrec that would do the job, but google doesn't want to tell me where to get it. Some IRIX binary perhaps?
Solution?
Should I put CONFIG_EMBEDDED_RAMDISK and its ilk back into my kernel, or write an ELF version of addinitrd? Other ideas?
Thanks in advance.
Quoted 12 lines · Ed Martini
Background:
I'm trying to get 2.6.11 to run on a MIPS Malta board with Yamon. The kernel that comes with the board is 2.4.18 with an embedded ramdisk that runs some scripts to install RPMS via NFS or CD-ROM. The kernel is converted to s-records via objcopy(1), and loaded into memory via tftp. I want to do something similar with 2.6.latest.
Problem:
On or about Nov 21 of last year, the
CONFIG_EMBEDDED_RAMDISKdisappeared.http://www.linux-mips.org/archives/linux-mips/2004-11/msg00135.html
In it's place it is suggested to use the tools in
arch/mips/boot, so I tried it. I can cross-compile the kernel, and I get an ELF vmlinux. I can convert it to ecoff with elf2ecoff, and attach an initrd image with addinitrd. The problem begins here. I end up with an ecoff format kernel which is not recognized by objcopy(1), and therefore no s-records.
Quoted 7 lines
It seems there is a program called gensrec that would do the job, but google doesn't want to tell me where to get it. Some IRIX binary perhaps?
Solution?
Should I put
CONFIG_EMBEDDED_RAMDISKand its ilk back into my kernel, or write an ELF version of addinitrd? Other ideas?Thanks in advance.
The future is purportedly in the feature known as initramfs. See the file Documentation/early-userpace/README for more details on how that is supposed to work.
That said, I tried initramfs a few times, but either due to lack of understanding, or broken support code in 2.6.10, I couldn't get it to properly load an initrd bundled in, so I forward-ported a patch I wrote that originally fixed CONFIG_EMBEDDED_RAMDISK to work with any ABI to 2.6.10, and it worked rather well. I'm sticking with this method until I find more/better docs on how to use initramfs properly.
If you're interested, the patch I use can be found here:
http://dev.gentoo.org/~kumba/mips/misc/misc-2.6.10-add-ramdisk-back.patch [2.6.10]
http://dev.gentoo.org/~kumba/mips/misc/misc-2.6.11-add-ramdisk-back.patch [2.6.11]
--Kumba
Signature · 1 line
"Such is oft the course of deeds that move the wheels of the world: small hands do them because they must, while the eyes of the great are elsewhere." --Elrond
Quoted 10 lines · Ed Martini
I'm trying to get 2.6.11 to run on a MIPS Malta board with Yamon. The kernel that comes with the board is 2.4.18 with an embedded ramdisk that runs some scripts to install RPMS via NFS or CD-ROM. The kernel is converted to s-records via objcopy(1), and loaded into memory via tftp. I want to do something similar with 2.6.latest.
Problem:
On or about Nov 21 of last year, the
CONFIG_EMBEDDED_RAMDISKdisappeared.
Quoted 7 lines
http://www.linux-mips.org/archives/linux-mips/2004-11/msg00135.html
In it's place it is suggested to use the tools in
arch/mips/boot, so I tried it. I can cross-compile the kernel, and I get an ELF vmlinux. I can convert it to ecoff with elf2ecoff, and attach an initrd image with addinitrd. The problem begins here. I end up with an ecoff format kernel which is not recognized by objcopy(1), and therefore no s-records.
I guess that was an act of desperation - YAMON needs SRECs to be happy but doesn't know anything about SRECs.
Quoted 2 lines
It seems there is a program called gensrec that would do the job, but google doesn't want to tell me where to get it. Some IRIX binary perhaps?
make vmlinux.srec; the resulting file will be in arch/mips/boot/vmlinux.srec.
Quoted 2 lines
Should I put
CONFIG_EMBEDDED_RAMDISKand its ilk back into my kernel, or write an ELF version of addinitrd? Other ideas?
Things vanish for a reason ... Try CONFIG_INITRAMFS_SOURCE instead.
Ralf
Quoted 11 lines · Ralf Baechle
Quoted 3 lines · Ed Martini
Should I put
CONFIG_EMBEDDED_RAMDISKand its ilk back into my kernel, or write an ELF version of addinitrd? Other ideas?Things vanish for a reason ... Try
CONFIG_INITRAMFS_SOURCEinstead.Ralf
Ok. Then let's get rid of it completly, and provide a replacement that works.
There were vestiges of embedded initrd in the ld script that were confusing when trying to sort things out. That, in conjunction with Documentation/initrd.txt made it hard to discover early user space and initramfs when coming from the old world (2.4).
Also, unless you move the location of .init.ramfs, it gets freed twice, leading to a panic.
From the documentation alone it's impossible to figure out how to build your initramfs. In various places the docs refer to the initial executable as /linuxrc, /kinit, /init, and possibly others. If you read init/main.c you see that for an initramfs, your initial process will be started from /init.
arch/mips/kernel/vmlinux.lds.S 2005-03-15 14:34:00.339164936 -0800 renamed from arch/mips/kernel/vmlinux.lds.S 2005-03-15 13:41:51.000000000 -0800 +7 -11
@@ -54,13 +54,6 @@ *(.data) - /* Align the initial ramdisk image (INITRD) on page boundaries. */ - . = ALIGN(4096); - __rd_start = .; - *(.initrd) - . = ALIGN(4096); - __rd_end = .; - CONSTRUCTORS } _gp = . + 0x8000;
@@ -82,6 +75,13 @@ _edata = .; /* End of data section */ + /* Align the initial ramfs image on page boundaries. */ + /* It will be freed by init/initramfs.c */ + . = ALIGN(4096); + __initramfs_start = .; + .init.ramfs : { *(.init.ramfs) } + __initramfs_end = .; + /* will be freed after init */ . = ALIGN(4096); /* Init code and data */ __init_begin = .;
@@ -118,10 +118,6 @@ .con_initcall.init : { *(.con_initcall.init) } __con_initcall_end = .; SECURITY_INIT - . = ALIGN(4096); - __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } - __initramfs_end = .; . = ALIGN(32); __per_cpu_start = .; .data.percpu : { *(.data.percpu) }
Quoted 2 lines · Ed Martini
Ok. Then let's get rid of it completly, and provide a replacement that works.
Way to go.
Quoted 4 lines
There were vestiges of embedded initrd in the ld script that were confusing when trying to sort things out. That, in conjunction with
Documentation/initrd.txtmade it hard to discover early user space and initramfs when coming from the old world (2.4).
Correct and I've applied that part of your patch already while thinking about the problem you describe below.
Quoted 2 lines
Also, unless you move the location of .init.ramfs, it gets freed twice, leading to a panic.
Interesting one. When I tested the code recently it did work for me and it shouldn't have changed since. The way this is supposed to work is by setting the page_count to 1 by using set_page_count and unmarking the page as reserved, so after that point a free_page should actually succeed - even if done twice as you've observed, first in populate_rootfs then once more in free_initmem.
It seems a frighteningly bad idea though since it relies on no memory from the initrd range being allocated between the two calls - or it would end being freed by force, in use or not. On startup Linux tends to allocate memory starting from high address towards low addresses which must be why we usually get away with this one.
Quoted 5 lines
From the documentation alone it's impossible to figure out how to build your initramfs. In various places the docs refer to the initial executable as /linuxrc, /kinit, /init, and possibly others. If you read
init/main.cyou see that for an initramfs, your initial process will be started from /init.
I guess I read the code so I didn't notice the lacking qualities of the documentation ...
Ralf
initrd/initramfs problem
What fails is when CONFIG_BLK_DEV_INITRD and CONFIG_INITRAMFS_SOURCE are both set. I realize (now) that I don't need initrd at all, and initramfs works fine by itself, as you have tested. It seems that the kernel may need some exclusion between these two mechanisms while the difference is sorted out.
I'm not totally up on Kconfig files, but maybe something like this in drivers/block/Kconfig:
config INITRAMFS_SOURCE
string "Initramfs source file(s)"
default ""
depends on BLK_DEV_INITRD=n
Regarding the documenation it would have been helpful to me if Documentation/initrd.txt had a reference to Documentation/early-userspace/README. I'm not sure who maintains that directory, or I'd send a suggestion. tldp.org?
THX
Ed Martini
Original context: http://www.linux-mips.org/archives/linux-mips/2005-03/index.html
Quoted 33 lines · Ralf Baechle
Quoted 3 lines · Ed Martini
Also, unless you move the location of .init.ramfs, it gets freed twice, leading to a panic.
Interesting one. When I tested the code recently it did work for me and it shouldn't have changed since. The way this is supposed to work is by setting the
page_countto 1 by usingset_page_countand unmarking the page as reserved, so after that point afree_pageshould actually succeed - even if done twice as you've observed, first inpopulate_rootfsthen once more infree_initmem.It seems a frighteningly bad idea though since it relies on no memory from the initrd range being allocated between the two calls - or it would end being freed by force, in use or not. On startup Linux tends to allocate memory starting from high address towards low addresses which must be why we usually get away with this one.
Quoted 3 lines
From the documentation alone it's impossible to figure out how to build your initramfs. In various places the docs refer to the initial executable as /linuxrc, /kinit, /init, and possibly others. If you read
init/main.cyou see that for an initramfs, your initial process will be started from /init.I guess I read the code so I didn't notice the lacking qualities of the documentation ...
Ralf
initrd/initramfs problem
In reply to Ralf BaechleWhat fails is when CONFIG_BLK_DEV_INITRD and CONFIG_INITRAMFS_SOURCE are both set. I realize (now) that I don't need initrd at all, and initramfs works fine by itself, as you have tested. It seems that the kernel may need some exclusion between these two mechanisms while the difference is sorted out.
I'm not totally up on Kconfig files, but maybe something like this in drivers/block/Kconfig:
config INITRAMFS_SOURCE
string "Initramfs source file(s)"
default ""
depends on BLK_DEV_INITRD=n
Regarding the documenation it would have been helpful to me if Documentation/initrd.txt had a reference to Documentation/early-userspace/README. I'm not sure who maintains that directory, or I'd send a suggestion. tldp.org?
THX
Ed Martini
Original context: http://www.linux-mips.org/archives/linux-mips/2005-03/index.html
Quoted 32 lines · Ralf Baechle
Quoted 3 lines · Ed Martini
Also, unless you move the location of .init.ramfs, it gets freed twice, leading to a panic.
Interesting one. When I tested the code recently it did work for me and it shouldn't have changed since. The way this is supposed to work is by setting the
page_countto 1 by usingset_page_countand unmarking the page as reserved, so after that point afree_pageshould actually succeed - even if done twice as you've observed, first inpopulate_rootfsthen once more infree_initmem.It seems a frighteningly bad idea though since it relies on no memory from the initrd range being allocated between the two calls - or it would end being freed by force, in use or not. On startup Linux tends to allocate memory starting from high address towards low addresses which must be why we usually get away with this one.
Quoted 3 lines
From the documentation alone it's impossible to figure out how to build your initramfs. In various places the docs refer to the initial executable as /linuxrc, /kinit, /init, and possibly others. If you read
init/main.cyou see that for an initramfs, your initial process will be started from /init.I guess I read the code so I didn't notice the lacking qualities of the documentation ...
Ralf
Observations on LLSC and SMP
In reply to Ralf BaechleIn include/asm-mips/ atomic.h, bitops.h and system.h there are a bunch of inline functions which contain this logic:
if (cpu_has_llsc && R10000_LLSC_WAR) {
__asm__ (stuff)
} else if (cpu_has_llsc) {
__asm__ (other stuff)
} else {
C lang stuff;
}My two observations relate to both code size and runtime performance. These observations don't affect my situation, so I'm not inclined to spend a bunch of time on it, but maybe someone else is interested. This should be especially interesting since these inline functions are used all over the kernel, so it might actually make a marginally significant difference.
I suppose there's a reason this code is the way it is. If so, feel free to ignore me or flame away.
1. If the first part of the if were an ifdef instead it would result in a code size reduction as well as a runtime performance gain.
2. In atomic.h the "C lang stuff" is wrapped with a spinlock. In the SMP case the spinlock will result in code that contains ll and sc instructions, so I infer that there are no SMP system configs that use CPUs that don't have the ll and sc instructions.
Paranoid version:
-----
if (cpu_has_llsc) {
#ifdef R10000_LLSC_WAR
__asm__ (stuff)
#else
__asm__ (other stuff)
#endif
} else {
#ifdef CONFIG_SMP
panic("SMP on CPUs with no LLSC is broken\n");
#else
C lang stuff;
#endif
}-----
Most efficient version:
-----
#ifndef CONFIG_SMP
if (cpu_has_llsc)
#endif
{
#ifdef R10000_LLSC_WAR
__asm__ (stuff)
#else
__asm__ (other stuff)
#endif
}-----
Re: Observations on LLSC and SMP
Quoted 2 lines · Ed Martini
1. If the first part of the if were an ifdef instead it would result in a code size reduction as well as a runtime performance gain.
You should spend a little time playing with an optimizing compiler. They're capable of working out when a condition will always be false.
Quoted 4 lines
2. In
atomic.hthe "C lang stuff" is wrapped with a spinlock. In the SMP case the spinlock will result in code that contains ll and sc instructions, so I infer that there are no SMP system configs that use CPUs that don't have the ll and sc instructions.
That's correct. It is not practical to implement SMP without a mutex primitive.
Signature · 2 lines
Daniel Jacobowitz CodeSourcery, LLC
Re: Observations on LLSC and SMP
Quoted 10 lines · Daniel Jacobowitz
Quoted 3 lines · Ed Martini
1. If the first part of the if were an ifdef instead it would result in a code size reduction as well as a runtime performance gain.
You should spend a little time playing with an optimizing compiler. They're capable of working out when a condition will always be false.
Yes, but in the case where R10000_LLSC_WAR is true, but cpu_has_llsc returns false there are still two wasted tests, and two blocks of code that the compiler can't optimize out.
Re: Observations on LLSC and SMP
Quoted 10 lines · Ed Martini
Quoted 8 lines · Daniel Jacobowitz
Quoted 4 lines · Ed Martini
1. If the first part of the if were an ifdef instead it would result in a code size reduction as well as a runtime performance gain.
Quoted 7 lines
Quoted 4 lines
You should spend a little time playing with an optimizing compiler. They're capable of working out when a condition will always be false.
Yes, but in the case where
R10000_LLSC_WARis true, butcpu_has_llscreturns false there are still two wasted tests, and two blocks of code that the compiler can't optimize out.
Not only is cpu_has_llsc often a constant, R10000_LLSC_WAR will never be true if the CPU does not have LL/SC.
Signature · 2 lines
Daniel Jacobowitz CodeSourcery, LLC