Gabe Black wrote:
#2 has already largely been addressed in the Exynos, Tegra and Beaglebone ports.
Is that once in each port or once in the entire tree?
//Peter
On Friday, January 03, 2014 10:25:46 PM Peter Stuge wrote:
Gabe Black wrote:
#2 has already largely been addressed in the Exynos, Tegra and Beaglebone ports.
Is that once in each port or once in the entire tree?
Once in each port.
There were three parts to that #2, repeated below for reference.
2. It presents a whole new set of problems that need to be addressed. For example, how do we load different stages of the boot process from a media that is not memory-mapped? How do we handle devices with limited amounts of Cache- as-RAM (SRAM in this case)? How do we adjust our payload ecosystem to accommodate loading the OS kernel?
Hung-Te, an engineer at Google, has reworked the CBFS infrastructure so that you can plug different "media" into it which know how to load things for that platform. On x86 platforms it's just memory mapped. On all the ARM platforms I mentioned except for beaglebone, the SPI driver is plugged in which will load stages, CBFS meta data, etc., on request. The SOC in a beaglebone can load the non-masked firmware from lots of places including downloading it over the network, but on the beaglebone its wired up either to get it from either the eMMC or the SD card. I played a trick which avoided having to have an eMMC driver in the bootblock by making the masked ROM load enough of CBFS into SRAM so that the "media" could just adjust the ROM stage in place slightly and run it from there. I wasn't able to work on beaglebone much after that, but to flesh it out it would need an eMMC/SD driver and that would need to be interfaced with CBFS as a type of "media". The CBFS support is for the whole tree, and the "media" support is per board or maybe SOC.
That's how to load things off of non-memory mapped media. As far as how to work in limited pre-memory storage that hasn't really been a problem. There isn't a lot of space, but it's generally not been that hard to fit in the limits of the chips we've worked with so far. In my in depth but relatively short experience with U-Boot over the last few years it tends to be pretty monolithic and large comparatively, and so I don't think we would have too much trouble fitting in their footprint.
As far as payloads, that needs some work. We've focused on the depthcharge payload since we've been developing for chromebooks. I have no interest in turning depthcharge into a general purpose bootloader, and I think people would be better served by having something like a grub for ARM anyway. There are several complications here, though.
1. There is much less you can count on hardware wise on ARM. There's basically no legacy hardware or interfaces you can fall back to to make a bootloader that should work on most machines like you can on x86. You have to have real drivers for the SOCs in question, and perhaps even have info about each particular board in some cases. A lot of ARM stuff is non-discoverable too, so you need some sort of configuration database to tell you were things are. The kernel uses a device tree (not like coreboot's) which has its own issues.
2. Booting a kernel on ARM is complicated. There are a couple different kernel boot protocols (ATAGS, device tree), and if the kernel uses device tree you may be expected to load it and fix it up. The information itself and which information it is is board specific. There may even be a need to bridge between things the firmware proper did and the kernel, for instance telling the kernel where magical blobs of resident firmware code are.
Payloads can't actually even count on memory being in the same place in the address space which makes finding the coreboot tables somewhat tricky and which is a bit hacky as implemented right now. What we do for the existing boards is we have to staticlly tell libpayload where to look on that platform. A better solution would be pass a pointer to the coreboot tables in a register when the payload starts. Then libpayload and other payloads can be a little more generic.
I think I've basically addressed your question at this point, but I also want to mention somethings that I think could be improved in our SPI/CBFS stack.
Currently our SPI drivers are, I think, based on the U-Boot API. This is actually a fairly reasonable interface which has a start, stop, and xfer function. The start function asserts CS, the stop function deasserts it, and the xfer function does either a simplex or duplex transfer to the device. One problem with it, though, is that it does everything in terms of bits. That means all the call sights multiply the size by eight, and all the drivers divide by eight and probably check for remainder bits and flag an error. It's wasteful and doesn't really make any sense since we don't care about single bits of data. The size of the incoming and outgoing arrays are also independently controlled which complicates the driver logic considerably.
Then, we have the CBFS media support. This was unfortunately built into the drivers themselves and comes with its own set of functions which are built more around a memory mapping sort of interface. Those functions are implemented directly by the driver and make controlling the device more complicated. What I want to do to fix that up is to pull all the CBFS stuff out of the drivers and implement a "SPI" media driver which is its own component and uses the start, stop and xfer functions provided by the driver.
Another wrinkle is that the ICH SPI controllers aren't really SPI controllers. The physical interface they talk over is SPI and they talk to SPI devices, but the register interface and the behavior of the controller means that it's only suitable for talking to SPI flash chips. These never fit into the U-Boot API in U-Boot, and they still don't fit it in coreboot. In depthcharge I have two levels of interface, one for flash chips and one for SPI controllers. I have a "SPI" interface for flash chips on the other end of SPI controllers, but the ICH controllers implement the flash interface directly and not the SPI controller interface. I think the same thing would be appropriate for coreboot. The ICH drivers would implement the "media" interface, or whatever file like read/write interface is appropriate, and not implement the normal start, stop, or xfer functions.
Then finally we have the cases were we want to get at stuff on the chip without having to go through CBFS. For instance, when booting ChromeOS we rely fairly heavily on an FMAP which might say there's a block of data we need at a particular offset outside of the main CBFS, or perhaps we need to record something in the event log. To address that I'd like to further split apart the media interface so that there's a way to talk to the flash directly, and then there's a linkage that plugs that into the CBFS infrastructure.
So, there's a lot of work to do figuring out exactly how to fit the payload architecture into ARM. While the boot media situation is currently functional and can continue to be used, I think some restructuring could improve it significantly.
Gabe
On Fri, Jan 3, 2014 at 4:25 PM, Peter Stuge peter@stuge.se wrote:
Gabe Black wrote:
#2 has already largely been addressed in the Exynos, Tegra and Beaglebone ports.
Is that once in each port or once in the entire tree?
//Peter
-- coreboot mailing list: coreboot@coreboot.org http://www.coreboot.org/mailman/listinfo/coreboot