Uwe Hermann wrote:
Hi all,
here's my (first) status report for the lbmenu project I'm working on as part of the Google Summer of Code. I should have done this a lot earlier, sorry for the delay.
What is lbmenu?
lbmenu is a simple payload which provides a LinuxBIOS config menu, which allows you to change some config options at "runtime", i.e. after LinuxBIOS did the hardware init, but before any bootloader or OS is started.
Planned features, design goals (mostly copied from my GSoC proposal)
Text-mode (Kconfig-like) console UI for changing LinuxBIOS settings.
Bootsplash screen (text mode only for now) where the user can press a certain (configurable) key to enter the configuration tool.
The tool should also be accessible over serial console (for headless clients, servers or debugging scenarios), as well as (if feasible) over telnet or ssh (given a big enough ROM chip and Linux + busybox in ROM).
The tool should work both in ROM (as part of LinuxBIOS), and as a standalone application on a Linux system. The GUI should be the same (or similar) in both cases. The standalone version might enable some options which cannot be used in the embedded version because of size constraints.
To investigate: Implement the standalone tool as a frontend of lxbios? Or include the lxbios code in the standalone tool?
The tool needs to fit into flash ROM (together with LinuxBIOS and at least one LinuxBIOS payload), so size is important. Typical sizes of flash ROM chips today range from 256 KB to 2 MB.
It should be reasonably easy to extend the tool. For example, it should be possible to (later) add a graphical user-interface on top of the generic, UI-independent code of this tool.
A graphical user-interface is _not_ part of this GSoC project, though!
"BIOS password" feature for setting a LinuxBIOS password. Without the correct password, no payload should be executed/booted.
Random possible ideas for after GSoC
Internationalization support (using gettext or something similar). The strings in the UI should be fully translatable into other languages. Changing the language at run-time would require the strings of all supported languages to be placed into ROM (size constraints), so this will probably be a compile-time option only.
Configurable UI-Themes (colors, layouts, key mappings, text-based or (later) graphical splash screens etc.)
Payload selection mechanism to choose at runtime which payload to boot (if multiple payloads are included in the ROM chip). This would make it theoretically possible to choose between GRUB2, EFI, Open Firmware and other payloads upon each system boot.
It's not yet clear if this should be done in lbmenu, or as a mechanism in LinuxBIOS itself, or maybe as part of lbgrub2.
LinuxBIOS Device Tree browser which shows the device tree for this mainboard (maybe even allows changes?).
Implementation plan/notes
Written in C code (minimal assembly code, if required).
The code will be documented using Doxygen-style code comments.
A manpage will explain the usage and parameters of the tool. Optionally, there will be some help texts in the tool (configurable, as that increases the size of the tool).
Ideally, the building of the tool will be integrated in the normal LinuxBIOSv3 build process, with hooks for adapting some defaults or settings of the tool at compile-time.
QEMU will be used for testing the implementation.
License: GPL, version 2 or later.
Status
I have written a minimalist ncurses-implementation called tinycurses, which allows some basic primitives such as printing characters on screen, moving the cursor, reading keys from keyboard, beeping etc.
It (sort of) supports both, VGA text console, and serial; more work is needed, though.
This is designed as a general purpose payload library, which can also be used by other payloads which need console text support, serial output, keyboard services, beep() etc.
The alternative would be to use the stock ncurses, but there are various problems:
Too big; tinycurses is stripped down to just provide the most important functions and features (e.g. no wide character support).
Requires syscalls, term library, and generally an OS. I _do_ have a first test version which is compiled/linked against newlib (http://sourceware.org/newlib/), a small libc implementation which has stubs for OS-less builds (which we need in LinuxBIOS + payloads).
However, making this really fully work will require a lot more work. Also, the smallest lbmenu payload size when using newlib I've been able to get so far, is 130 KB or so (which is quite a lot).
My plan is to be able to use lbmenu with 256K ROM chips, and you need to put LinuxBIOS (30-70 KB) in there, as well as at least one payload (say FILO, ~60-80 KB), and lbmenu. So size is very important.
On the long term the lbmenu implementation should probably rely on the tinycurses implementation for that reason (which is currently smaller than 10 KB or so, and doesn't require newlib).
The final goal of all of this would be to use plain Kconfig _within_ lbmenu (at runtime) to display lbmenu's options and let the user change them. Thus ncurses or tinycurses needs to be complete enough to be able to compile kconfig.
If this is absolutely not feasible, well, I'll have to implement a small menu system from scratch, but I hope that won't be necessary.
The compile-time options of lbmenu are configured via kconfig, just like the options of LinuxBIOSv3 itself.
So far my draft implementation of lbmenu can be booted, prints a text banner (VGA and/or serial), can react on a (configurable) keypress, e.g. ESC, then enter a "menu" (which is a stub right now), and reboot upon another ESC keypress.
TODO
Finish tinycurses and/or ncurses+newlib so they're usable with kconfig.
Figure out a mechanism to select between various payloads included in the ROM (_if_ this will be done in lbmenu, discussions welcome).
Implement read/write of CMOS values.
The configuration menu within lbmenu will be "dynamically" generated (or that's my plan at least) from Kconfig.lbmenu files in the LinuxBIOSv3 tree. The same parser which is used in Kconfig should parse all *.lbmenu files and construct the lbmenu main menu from that.
So you can have southbridge/amd/cs5536/Kconfig.lbmenu which provides lbmenu menu items which are CS5536-specific (e.g. enable/disable IDE). Another mainboard/amd/norwich/Kconfig.lbmenu would provide mainboard- specific menu items etc. etc.
Probably a few other things I cannot think of right now.
No code yet, sorry, but I'll try to put together a small demo soon which I can post here.
I intend to put tinycurses into the global util/ directory, as it's independant of LinuxBIOS and generally usable for other payloads.
Same for lbmenu, it should be in util/ and gets its tinycurses implementation via svn:externals (as should all other payloads which use it)...
Any comments and suggestions welcome!
Uwe.
This is really interesting. I think I will have a use for it in the future. Even if it's only for experiments but it should speed up the task.
--Darmawan Salihun