[coreboot] GSoC-2014 Project for Coreboot
adurbin at chromium.org
Fri Mar 14 14:58:01 CET 2014
On Thu, Mar 13, 2014 at 10:15 PM, mrnuke <mr.nuke.me at gmail.com> wrote:
> On Thursday, March 13, 2014 04:29:06 PM David Hendricks wrote:
>> On Tue, Mar 11, 2014 at 7:55 AM, Naman Govil <namangov at gmail.com> wrote:
>> > Hi!
>> > a generic interface for
>> > accessing block devices on ARM SoCs so that coreboot could launch its
>> > stages from the block devices (an MMC for example).
>> Seems interesting, but I am a little bit worried that the project is too
>> narrow. We updated CBFS about a year ago to allow CBFS content to come from
>> any media. This was required for the earlier ARM-based platforms which use
>> SPI ROM since the content was not memory mapped as it is on x86 platforms.
>> It should be reasonably easy to follow that model using MMC as a backing
> The problem is not that CBFS is not easily extendable to incorporate MMC;
> that's a 100 liner . The problem is creating yet another API for accessing
> stuff, besides which we'll add an MTD and NAND API, etc. etc. etc. This would
> make us EFI-ish.
>> IIRC Alexandru ran into issues with adapting the A10's MMC driver from
>> u-boot to coreboot and making it fit into the bootblock, which was
>> constrained by the amount of SRAM available on the A10. I am worried that
>> you will end up fighting implementation-specific problems on the platform
>> you choose instead of doing more interesting infrastructure work.
> I'm glad you brought that up. I ran into several problems, most of which were
> a result of CBFS's x86-centric design rather than the shortage of SRAM. A lot
> of CBFS callers love to generate map() calls, which means we as the backend
> need to provide the cache where to map that. When I get a map() call to map
> 20+ KiB of romstage into an area of SRAM I must provide, which must not
> overlap the final destination of romstage, I am wasting SRAM. If I only got a
> call to read(), with the destination being the resting place of romstage, that
> would eliminate the SRAM pressure a bit.
CBFS is definitely not friendly to environments that can't map() the
storage area of the CBFS itself. Beyond that in-storage format with
metadata tightly coupled to the data itself leads to needing to stream
large amounts of data through the working set just to locate the piece
that is desired.
On top of that the CBFS API doesn't allow for freeing up of used
resources. Yes, there is the construct of map() and unmap(), but the
used API in the code base returns pointers from map() and that means
there is no way to free up the internal cache. However, read() doesn't
solve the map() problem. read() and map() both need memory so in a
constrained environment w/o memory-mapped access to the CBFS storage.
Lastly, the big reason for large map() requests is because we don't
have a pipelined lzma path. For the non-lzma files read() will work
exactly as you described.
> My first solution was to make the CBFS cache and the romstage destination
> overlap. That needed a trivial change in CBFS, but that patch dropped the soap
> for various reasons. The alternate_cbfs implementation for that was also
> clumsy and difficult to read.
> Another problem I almost had was caused by problem #1. Since I needed a ton of
> RAM for the CBFS cache, I had to initialize RAM in the bootblock. Adding that
> code almost caused overgrowing the maximum bootblock size. I was getting close
> to the 24KiB limit with the MMC driver in there as well. I moved a bunch of
> non-essential stuff to romstage, and optimized the code layout a bit to not
> compile big bloat in bootblock. If I nuke the MMC debug messages, the
> bootblock goes under 13KiB, with MMC and raminit. Seems like there's also room
> for an MTD/NAND driver.
I noticed in your code  you just read in all of the CBFS in-core.
Or did I misread that? And your init_default_cbfs_media() always
re-initializes and reads the CBFS again? I take it that function only
gets called once? Most likely because that is the bootblock.
> So, I hope I killed any worries about "fighting implementation-specific
> problems on the platform", which brings me back to the awkward design of CBFS.
> If we go the way of separate API for every possible bootblock media, you can
> have a Kconfig to select which to boot from.
> If, on the other hand, you have a well designed, unified block dev API, you
> can select your block device based on some some heuristic to decide which
> media to boot from. Make it a GPIO.
> Why is this better? You don't need two implementations of alternate_cbfs,
> which are extra code size, extra code, and generally look ugly and complicate
> the code.
> I hope I convinced both of you that this is not an easy, trivial problem, and
> will take a big chunk of GSoC time, as well as tons of dedication to get done
> right. The purpose is not to hack something together to boot. I already did
> that in my github branch . The purpose is to Do It Right (TM).
> Naman, that means that if you pull this off, you'll need to be completely
> involved with the community for the twelve or so weeks of coding. You'll need
> to have patches up on gerrit early, take feedback, and involve in lots of
> discussion about the design. You will often be rewriting patches in the
> afternoon, in order to conform to the new design ideologies you discussed in
> the morning. You will repeat this process many times. You'll have to get
> intimate with the coding standards and ideologies of coreboot. I suggest you
> demonstrate a profound understanding of the foundation of our coding standards
> in your application, by correctly formatting any example code included
> therein. Your goal must be to have your work merged in coreboot master, and
> your board booting from MMC/SD with that code, by the pencils down date.
>  https://github.com/mrnuke/coreboot/commits/cubie_mmc
> coreboot mailing list: coreboot at coreboot.org
More information about the coreboot