On Tue, Mar 24, 2015 at 10:22:13AM -0600, Bruce Rogers wrote:
All,
When building SeaBIOS in the context of QEMU v2.3-rc0 using various openSUSE versions we found that some recent versions overflowed the 128K limit imposed for bios.bin. The Makefile fails with the suggestion of using a more recent toolset or of eliminating some features to make it fit. Neither of those are options in this case.
The 128K build should only be needed with older machine types on QEMU, and one should be able to compile without all the hardware device drivers there.
Of course another option is to review the code for places where variables or strings can be reduced in size without changing functionality. That doesn't buy us all that much, but enough for all of our cases except the oldest toolset. I'll post the patches I came up with during this review of the SeaBIOS code shortly to see what people think.
The 128K bios.bin needed by older QEMU machine types doesn't need new functionality, but some future SeaBIOS changes will undoubtedly still cause it to continue to grow a bit. Since we are right at the boundary of overflowing 128K, I thought it was worth investing some effort in backing away from that limit so we don't have to constantly worry about every small change causing an issue there.
In addition to the above mentioned data size reductions, another thing I noticed was that the e820 array is 32 entries, as given by BUILD_MAX_E820. It appears that QEMU only will ever fill 16 of those entries, so perhaps it would make sense to reduce that size when the usage is for QEMU only.
As a more general query, I was wondering if anyone else knew of places where the size of SeaBIOS could be reduced? I'd be happy to try to help make that happen.
There are a few areas I'm aware of:
- go to 32bit only hardware drivers - see https://github.com/KevinOConnor/seabios/tree/testing-32bit-drivers right now many hardware drivers are compiled in both 16bit mode and 32bit mode, so compiling them only in 32bit mode is a notable size reduction. Unfortunately, it causes compatibility problems for really old DOS-era programs (emm386). There is an SMI handler to work around this, but it's only supported on QEMU TCG (not coreboot, csm, or kvm).
- string merging between modes. Right now, if a string is used in both 16bit mode and 32bit mode, it is copied into the final binary twice, but they could share the same copy. I haven't figured out a way to get the linker to do this though.
- reducing debugging strings on failure paths. There are a lot of places where a custom debug message is outputted on rare failure paths. It should be possible to replace a number of these locations with warn_internal_error(), warn_noalloc(), warn_timeout() etc. (Reducing code size is the reason for these warn_xxx() functions.)
- increase the debug level of many dprintf calls. There is no standard for what log level to use in dprintf calls, and it would probably be good to have a standard. I suspect a number of calls could be moved out of the default debug level of 1.
- it may be possible to avoid using space for bss variables in the rom. I suspect this is too complex to be worthwhile though.
-Kevin