Hi All,
I am undertaking a little project at home to get Linux running on a custom x86 (AMD SC520) based board. The board is pretty simple, just the CPU some RAM and Flash, a couple of Ethernet (Realtek 8100B) ports and some other miscellaneous custom hardware (don't need to worry about this for now). This board is in no way shape or form a mini-PC
The whole point of doing the Linux port is a kind of 'because its there' thing. I had some (very little as it turns out) free time, so I decided to give it a go.
After having a good look around, I ended up choosing U-Boot as a boot loader (in which case you would assume my question is really for the U-Boot list and not coreboot - please read on). Unfortunately, U-Boot's x86 support at the time was very stagnant. No work had been done on the x86 port since about mid 2003 and several non-x86 patches had pretty much completely clobbered it to the point it would not even compile. I've been working on U-Boot now since July 2008 and have been pushing patches back in to the point where U-Boot has a good, stable, x86 implementation.
I have now arrived at my next hurdle - Getting a Linux Kernel running.
I'm having difficulty finding any real information on the sequence of events that need to be gone through in the x86 embedded environment to get the kernel up and running. Even coreboot seems a little light-on (I have seen mention of the Linux Kernel being a legitimate payload, but no obvious instruction on how this is configured and how it works). But so far, the coreboot community appears to be the closest thing to an x86 embedded Linux community that I can find.
I suppose I have a couple of questions to start of with that I hope someone here can answer:
0) Is there a good repository of information regarding embedded Linux in the x86 (not PC!!!!) architecture 1) The boot-loader (both U-Boot and coreboot) put the x86 staight into Protected Mode - Does the CPU need to be put back into Real Mode before entering the Linux Kernel (in order to allow the Kernel to put the CPU into Protected Mode) 2) Which Kernel image should I use (vmlinux, vmlinux.bin, bzImage etc) 3) Can I copy the compiled Kernel image directly into RAM simply perform a 'Jump' into it 5) Can I run x86 Linux without needed any kind of BIOS emulation? 4) Are these the right questions to ask? Are there 'better' questions I should be asking?
Hopefully someone can answer some of these and/or point me towards some good technical information.
Regards,
Graeme
Disclaimer: I could easily have botched the answers to your questions. Maybe someone will know the best way to load Linux from Uboot, but I don't.
I've found that people more readily correct misinformation than volunteer information, so I hope this gets you somewhere :)
I suppose I have a couple of questions to start of with that I hope someone here can answer:
The best answer to your questions is probably something like: It depends on your boot loader.
Coreboot initializes the hardware and then loads its payload. That payload could be a BIOS (SeaBIOS), a boot loader (FILO, Grub, Linux-As-Bootloader, elfboot...), a Linux kernel, memtest, coreinfo, ...
This gives you the flexibility to load the kernel over the network, from a disk...
You can check out buildrom to see how some payloads are built. It gets out of date quickly, but it is faster than starting from scratch.
- Is there a good repository of information regarding embedded Linux in the x86 (not PC!!!!) architecture
I would choose a boot loader and go from there.
- The boot-loader (both U-Boot and coreboot) put the x86 staight into Protected Mode - Does the CPU need to be put back into Real Mode before entering the Linux Kernel (in order to allow the Kernel to put the CPU into Protected Mode)
Our terminology is conflicting here, since we don't call Coreboot a boot-loader, but hopefully what I'm saying still makes sense. The boot-loader will do this if it needs to.
- Which Kernel image should I use (vmlinux, vmlinux.bin, bzImage etc)
- Can I copy the compiled Kernel image directly into RAM simply perform a 'Jump' into it
- Can I run x86 Linux without needed any kind of BIOS emulation?
- Are these the right questions to ask? Are there 'better' questions I should be asking?
If you want to use Coreboot, the first question is probably "Which bootloader do I want to use?"
All the rest will be answered by the documentation for that bootloader.
Thanks, Myles
On Fri, Jan 29, 2010 at 10:50 AM, Myles Watson mylesgw@gmail.com wrote:
Disclaimer: I could easily have botched the answers to your questions. Maybe someone will know the best way to load Linux from Uboot, but I don't.
I theory this would be the U-Boot mailing list, but in this case, I am on my own there. U-Boot (and the Embedded Linux Development Kit (EDLK) which is also written by DENX Software Engineering) is geared towards ARM and PPC architectures. Both these architectures have very strong embedded communities and therefore much better access to the information I am seeking
I've found that people more readily correct misinformation than volunteer information, so I hope this gets you somewhere :)
I suppose I have a couple of questions to start of with that I hope someone here can answer:
The best answer to your questions is probably something like: It depends on your boot loader.
In this regard, the 'Boot Loader' is U-Boot. I suppose to clear up some confusion, you could probably think of U-Boot and Coreboot as 'Boot Strappers' rather than 'Boot Loaders' - They both start from power-up of the CPU and hardware, initialise core hardware services (like SDRAM etc) and execute a payload. U-Boot is capable of executing stand-alone payloads as well as the Linux Kernel just like Coreboot.
Coreboot initializes the hardware and then loads its payload. That payload could be a BIOS (SeaBIOS), a boot loader (FILO, Grub, Linux-As-Bootloader, elfboot...), a Linux kernel, memtest, coreinfo, ...
This gives you the flexibility to load the kernel over the network, from a disk...
You can check out buildrom to see how some payloads are built. It gets out of date quickly, but it is faster than starting from scratch.
OK, I'll see if the buildrom code sheds any more light on how Linux is started from Coreboot.
- Is there a good repository of information regarding embedded Linux in the x86 (not PC!!!!) architecture
I would choose a boot loader and go from there.
In this case, I have no 'Boot Loader' (GRUB, LILO etc) and nor do I want one
- The boot-loader (both U-Boot and coreboot) put the x86 staight into Protected Mode - Does the CPU need to be put back into Real Mode before entering the Linux Kernel (in order to allow the Kernel to put the CPU into Protected Mode)
Our terminology is conflicting here, since we don't call Coreboot a boot-loader, but hopefully what I'm saying still makes sense. The boot-loader will do this if it needs to.
As mentioned earlier, U-Boot and Coreboot are the same in this regard
- Which Kernel image should I use (vmlinux, vmlinux.bin, bzImage etc)
- Can I copy the compiled Kernel image directly into RAM simply perform a 'Jump' into it
- Can I run x86 Linux without needed any kind of BIOS emulation?
- Are these the right questions to ask? Are there 'better' questions I should be asking?
If you want to use Coreboot, the first question is probably "Which bootloader do I want to use?"
My question is, how does Coreboot launch the Linux Kernel as a payload without the intervention of a Boot-Loader
All the rest will be answered by the documentation for that bootloader.
Thanks, Myles
Thanks for your reply Myles - Every little tidbit of information gets my that tiny bit closer to my goal - I have patience ;)
Regards,
Graeme
Graeme Russ wrote:
- Is there a good repository of information regarding embedded Linux in the x86 (not PC!!!!) architecture
Maybe linux-embedded@vger.kernel.org.
- The boot-loader (both U-Boot and coreboot) put the x86 staight into Protected Mode - Does the CPU need to be put back into Real Mode before entering the Linux Kernel (in order to allow the Kernel to put the CPU into Protected Mode)
It depends.
- Which Kernel image should I use (vmlinux, vmlinux.bin, bzImage etc)
It depends. :)
- Can I copy the compiled Kernel image directly into RAM simply perform a 'Jump' into it
Yes, in some cases.
- Can I run x86 Linux without needed any kind of BIOS emulation?
Yes.
- Are these the right questions to ask?
I think so.
Graeme Russ wrote:
It depends on your boot loader.
In this regard, the 'Boot Loader' is U-Boot.
And since you're on your own there you need to look at what other bootloaders to.
OK, I'll see if the buildrom code sheds any more light on how Linux is started from Coreboot.
I doubt it will. Instead, look at mkelfImage, Syslinux and wraplinux:
http://www.coreboot.org/Mkelfimage http://syslinux.zytor.com/wiki/index.php/The_Syslinux_Project http://www.kernel.org/pub/linux/utils/boot/wraplinux/
mkelfImage adds glue between coreboot and Linux. Maybe vmlinux could be started directly by the coreboot ELF loader, but it's not verified.
There's also the DOS-based loadlin program, for another data point.
Of the above, mkelfImage explicitly does *not* rely on BIOS in any way, while all other bootloaders and indeed many OSes out there have a hard requirement on one BIOS interface or other for x86. You may find the same to be true for Linux, and that you're forced to generate legacy BIOS data structures, to please the kernel. :(
I would choose a boot loader and go from there.
In this case, I have no 'Boot Loader' (GRUB, LILO etc) and nor do I want one
But you need parts of one, so the question is what to start from.
//Peter
Am 29.01.2010 08:07, schrieb Peter Stuge:
mkelfImage adds glue between coreboot and Linux. Maybe vmlinux could be started directly by the coreboot ELF loader, but it's not verified.
Close, but not quite. Linux requires a table with some runtime values around. So at least a small wrapper that fills this table will be necessary, I think.
But it should be possible to be more efficient than mkelfimage, by amending the vmlinux image with another code fragment that fills the table and jumps to the real entry point, and retargeting the entry point. At least, it will spare you a copy operation or two.
Patrick
Patrick Georgi wrote:
Maybe vmlinux could be started directly by the coreboot ELF loader
Close, but not quite. Linux requires a table with some runtime values around. So at least a small wrapper that fills this table will be necessary, I think.
And Linux does not want to fill the table using cbtables.
But it should be possible to be more efficient than mkelfimage, by amending the vmlinux image with another code fragment that fills the table and jumps to the real entry point, and retargeting the entry point. At least, it will spare you a copy operation or two.
Alternatively, maybe something libpayload based which reads vmlinux from CBFS?
It's tempting to have the table filling code in coreboot itself..
//Peter
Last time we did this, at Sandia last summer, we just used mkelfimage to make the image, pointed the Kconfig-based build at the elf image, and it all worked. This was on the Kontron board.
Further, you should in the Kconfig-based build just be able to point coreboot at a kernel elf image (vmlinux, say) and it should work. Only big issue is that linuxbios was designed from 1999 on to enter at the 32-bit entry bit, not the 16-bit entry point. It's always been pretty easy to do, however, since from the very beginning linuxbios/coreboot had "load a kernel" as a primary goal.
ron
OK, I'm getting a little closer (I think)...
I have managed to coerce U-Boot into processing a bzImage and loading what appears to be the correct data @ 0x10000. According to this (http://en.wikipedia.org/wiki/File:Linux-kernel-vmlinux.png) I think that is all about right.
Doing a memory dump from 0x10000 gives:
00010000: 57e58955 ec835356 085d8b18 560c758b U..WVS....]..u.V 00010010: 000220e8 6a585f00 025e6806 cee80004 . ..._Xj.h^..... 00010020: e8000000 00000083 6850595a 0004027f ........ZYPh.... 00010030: 0000bc68 2404c700 0004029d 0000b0e8 h......$........
The disassembly of which is:
push ebp
mov ebp, esp
push edi
push esi
push ebx
sub esp, 18h
mov ebx, [ebp+8]
mov esi, [ebp+0Ch]
push esi
call near ptr 235h
pop edi
pop eax
push 6
push 4025Eh
call near ptr 0F1h
call near ptr 0ABh
pop edx
pop ecx
push eax
push 4027Fh
push 0BCh
mov dword ptr [esp], 4029Dh
So it looks like legit code (setting up a stack frame etc)
But where to go from here?
Regards,
Graeme
Graeme Russ wrote:
I have managed to coerce U-Boot into processing a bzImage and loading what appears to be the correct data @ 0x10000.
..
So it looks like legit code (setting up a stack frame etc) But where to go from here?
Did you look at what the stub added by mkelfImage does? You need to do the same. After that; mov ebx, 0x10000; jmp ebx
//Peter
Graeme Russ wrote:
OK, I'm getting a little closer (I think)...
I have managed to coerce U-Boot into processing a bzImage and loading what appears to be the correct data @ 0x10000. According to this (http://en.wikipedia.org/wiki/File:Linux-kernel-vmlinux.png) I think that is all about right.
But where to go from here?
A quick update - I think I'm getting even closer.
U-Boot had some primitive BIOS Interrupt Service Routines and a Real Mode bootstrap that I had not correctly enabled during my development work (very embarrassing). I think I have these going now. I put a little bit of code which dumps some pretty basic info when a BIOS IRQ is initiated. So far I have seen instances of IRQ15, IRQ16 and IRQ10 before the system resets - I doubt this can be random code execution.
Digging deeper...
Regards,
Graeme
Graeme Russ wrote:
A quick update - I think I'm getting even closer.
Did you get some traction on the mkelfImage path too?
U-Boot had some primitive BIOS Interrupt Service Routines and a Real Mode bootstrap
..
So far I have seen instances of IRQ15, IRQ16 and IRQ10
Sounds like the kernel is running then.
Digging deeper...
arch/x86/boot/header.S calls arch/x86/boot/main.c
//Peter