IDEA: Linux kernel and pcbios compatibility...

Joshua Wise joshua at joshuawise.com
Fri Dec 19 22:47:01 CET 2003


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Friday 19 December 2003 7:15 pm, Eric W. Biederman wrote:
> Yes we are reaching the point where we can converge on some of these
> things. LAB might be the right framework.  And if it is something good it
> will save me the trouble of starting my own project.   But it takes more
> than a hyper active 2 year old to convince me.  It might take a hyperactive
> 2 year old to remind me about interesting ideas though.
Right, well then you should see it in action. If you're in the Boston area 
sometime soon I can give you a demo on an iPAQ, perhaps.

> > If you can have it in the kernel you can have it in LAB. LAB's command
> > line API is really easy - I've ported userland apps (mtderase) to LAB in
> > sub-10 minutes.
> By and large I don't want a command line interface.  I don't want a
> hardware monitor.  I want a configurable but non-interactive boot.
Right, that's where our autoboot stuff comes in. You can have it mount a 
partition by default, do whatever you want by default if no key has been 
struck on the serial line within 3 seconds.

> Compression wise there is not a difference between bzImage and zImage. 
> zImage on x86 has a 640K limit because it loads below 1MB.  bzImage breaks
> that ancient barrier.
Right, I just read about that. Mea culpa.

> > 512k is with a few ARM-specific drivers, and jffs2. It does not have
> > networking. This is with kernel 2.6.
> Hmm.  I am pretty certain I have gotten 2.6 down some smaller.  Our
> practical limit with LinuxBIOS etc is in the neighborhood of 384KB.
I've done 2.4 in 256k, but it's rather useless like that. If you do not plan 
to load modules at runtime, you can shave a good bit more off of it. If you 
write bzip2 compression support (or upport the stuff from kernel 2.4), you 
can shave even more off of it. I've pulled off 50k with bzip2 (not actually 
written the code, just did a bzip2 -9 < piggy > piggy.bz2). If you don't plan 
to have a framebuffer, you can shave some off of it. If you don't plan to 
have jffs2 you can shave a lot more off. Little tidbits here and there make 
the world go 'round.

> Well I think I have run finally convinced to use the MTD drivers...
> Mostly I prefer to flash from a production kernel rather than a
> bootloader, there are more recover options but anyway.
Ah yes, the ancient problem. Instead of read/modify/erase/write, it often 
turns into read/modify/erase/poweroff. That's Bad.

> I will see.  Does LAB restrict it's kernel to a very small subset of
> memory?  Or do you use something like kexec?
To boot a secondary kernel I use some code I wrote called armboot, although 
it's not very arm specific. It does something like this:

1) Load the new kernel into a contiguous vmalloced block.
2) We allocate 64k for a list of things that need to be relocated. We call 
this a pointer of type "struct physlist", which is 32 bytes. It has four 
ints: the new address, the old address, the block size, and whether this is 
the last block.
2) In blocks of the maximum kmalloc size (these blocks have to be contiguous), 
we kmalloc space for the kernel, and memcpy the kernel into those blocks. We 
then fill in a struct physlist, and move on to the next struct physlist. We 
can do this because kmalloc is always contiguous, and we can always map it 
with virt_to_phys().
3) We set up another kmalloced block for the tagged list of boot parameters 
that you need on ARM.
4) We set up one more kmalloced block and copy an assembler function into it, 
to make sure we don't wipe ourself out while relocating.
5) We flush our data caches.
6) We call the relocated assembler function, which turns off the MMU, jumps 
into the relocated assembler function's physical address, and does actual 
relocating. Then we jump into our newly moved zImage. Confused yet?
7) If at any point we failed, the system could be in an inconsistent state. 
You will want to panic() if you fail, because you're leaking memory like a 
sieve, and if you failed there's probably something bigger wrong.

This looks more difficult than it actually is. The C segment is only about 170 
lines, and the assembler bit is 90 lines. 

The reason that this works is that kmalloc should allocate from the top of 
memory down. You need a fair bit of ram - say, 8MB - to prevent the tail from 
running over other important structures, such as the list of addresses to 
relocate. But it seems to work well enough, and it looks like it should be 
fairly portable. The important code is in handhelds.org cvs, module 
linux/kernel26, files drivers/bootldr/armboot.c and 
drivers/bootldr/armboot-asm.S.

> Eric
/joshua

- -- 
Joshua Wise | www.joshuawise.com
GPG Key     | 0xEA80E0B3
Quote       | <lilo> I akilled *@* by mistake
In memoriam | Whiskers the hamster, 2001 - Dec 15, 2003
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)

iD8DBQE/48dQPn9tWOqA4LMRAqg8AJ4tEJmyHQ5gb9c/Mj401uhRQxSvSwCeL/mD
0uiImbJ4XRrQ4avT9bVyhRE=
=krn6
-----END PGP SIGNATURE-----




More information about the coreboot mailing list