[RFC] Qi Bootmenu

Marc Andre Tanner openmoko at brain-dump.org
Fri Oct 9 13:00:12 CEST 2009

On Fri, Oct 09, 2009 at 02:35:14PM +1100, Carsten Haitzler wrote:
> On Thu, 8 Oct 2009 22:50:00 +0200 Marc Andre Tanner <openmoko at brain-dump.org>
> said:
> > Hi all,
> > 
> > I have been lurking around on various openmoko mailing lists for quite 
> > some time (about 1.5 years) but so far I didn't have the time to actually 
> > contribute anything useful because of study and work related activities. 
> > However during the last few days I actually had some time to waste.
> > 
> > I therefore looked around for possible projects and found the boot menu
> > thingy which interested me for quite some time because it involves various
> > different system parts.
> > 
> > I have seen in the mailing list archives that some people have actually 
> > already started to work on projects[0] with similar goals but as far as I
> > know they weren't really finished and/or customized for the Freerunner.
> > The closest thing to a working solution is probably kexecboot[1].
> > 
> > So here are my random thoughts on the subject, comments are appreciated.
> > 
> > Goals
> > =====
> > 
> >  - The user should be able to select which image to boot from 
> >    (surprised heh ;)
> > 
> >  - The image could also provide a minimal system rescue environment
> >    that is a sshd server which allows remote access to fix certain
> >    things.
> > 
> >  - In order for this to be useful it needs to be fast. Nobody wants
> >    to wait 10+ seconds just to select which image to boot. Speed is
> >    therefore the most important factor.
> > 
> > Overview
> > ========
> > 
> >  - The whole system could be packaged into an initramfs
> > 
> >  - Ideally I would like to store the boot menu image in NAND flash. 
> >    This would ensure that it is always around and different SD
> >    based images could be booted with it.
> > 
> >    The boot sequence would look something like this:
> > 
> >     - Bootloader (Qi) loads minimal kernel
> > 
> >     - kernel extracts initramfs /init is executed
> > 
> >     - application scans for system images on SD card, presents boot menu
> > 
> >     - selected kernel is started via kexec
> > 
> > 
> > Bootloader (Qi)
> > ===============
> > 
> >  - I would like to change the default boot sequence to first look
> >    for the special bootmenu image in the kernel NAND flash partition, 
> >    if this is not found the boot sequence should proceed with the SD card.
> > 
> >    The user can of course still use the hardware buttons to skip the 
> >    NAND boot and by pass the bootmenu system.
> > 
> >    The NAND kernel partition is 8MB large so we need to fit the kernel +
> >    initramfs in there.
> > 
> > Kernel
> > ======
> > 
> >  - optimized for size just the absolutely necessary tings
> >    should be compiled in. The gta02_micro_defconfig will be starting
> >    point for this. Is it still up to date/maintained?
> > 
> >  - compress? Recent kernels can be compressed using LZMA
> > 
> >    Question is if this would actually speed up anything?
> >    Answer depends on where the bottleneck is in data throughput
> >    or computing power. What is the expected data transfer rate
> >    from NAND flash?
> > 
> >  - disable console output completely
> > 
> > Userland
> > ========
> > 
> >  - uClibc
> > 
> >  - stripped down busybox
> > 
> >  - kexec-tools
> > 
> >    They only support zImages however distros ship uImages so
> >    we would either have to strip off the uImage header which is
> >    probably slow or add uImage support to kexec-tools.
> > 
> >  - dropbear sshd
> > 
> >  - bootmenu application (see next section)
> > 
> > Bootmenu application
> > ====================
> > 
> >  - should be something like kexecboot, however It should be finger friendly.
> > 
> >  - functionality should be something like this (taken from kexecboot):
> > 
> >     - read available filesystems from /proc/filesystems
> >     - read available partitions from /proc/partitions
> >     - try to mount each partition, search for zImage in /boot
> >     - present menu
> >     - kexec selected kernel
> > 
> >  - GUI based on elementary with framebuffer support?
> > 
> >    In theory this would be the best solution because we would
> >    use the same technology as in a normal system just with a 
> >    different backend.  This should ensure that it's actually
> >    finger friendly. Although text entry remains a problem 
> >    because the illume keyboard can't be used. But I hope that
> >    text entry won't be necessary anyway (no kernel command line
> >    changes through the GUI, sorry ;) In practice I don't know 
> >    how mature the framebuffer backend actually is and it has 
> >    quite a few dependcies[2]:
> > 
> >     * eina
> >     * eet
> >           o zlib
> >           o libjpeg
> >     * evas
> >           o freetype
> i think you missed fontconfig - though it is optional, all the default themes
> for elementary etc. assume fontconfig support for font naming.

Ok now I am confused. Evas actually has support for reading fonts.{dir,alias}
files and doesn't require fontconfig for this. Doesn't this work the way I 
think it does? 

> >     * ecore
> >           o ecore-file
> >           o ecore-evas
> >           o ecore-input
> >           o ecore-job
> >           o ecore-txt
> >           o libiconv (functionality can be provided by uClibc)
> >           o tslib
> >     * edje
> >           o embryo
> >           o lua
> >     * libpng
> nb. u can drop libpng. if all your image data is inside edje files (or u can
> put it inot .eet files too) then you won't need this.

I added libpng because I saw that the default elementary themes uses png files
and I thought it needs some way to read them, thus libpng.
> >    I have cross compiled all this and without any special optimisation
> >    (I just disabled everything in ./configure which seemed not critical)
> >    the whole system is about 6-7MB large this is without the kernel.
> indeed.

As a said this is without any optimization, no special compilation flags, 
nothing. I should try to link everything statically which has 2 main advantages:

 - the linker should be able to remove any code paths which aren't actually

 - at runtime the dynamic linker doesn't have to load all the libraries 
   (less I/O + code relocation) which should speed up the application start. 

> >    I am not familiar with the EFL code base but what I have seen
> >    so far seems like it isn't really optimized for size. So there could
> >    be some potential although it would require some work and upstream 
> >    approval.
> > 
> >    Maybe the idea to use elementary is overkill but what are the 
> >    alternatives? 
> i'll shime in here. yes. efl has grown over the years, and well - the more
> functionality you want, the more space it will take. if you are hell-bent on
> smallest size you possibly would just write your own fb gui that is very simple
> and ugly (with white/black boxes for example). 

I know that elf provides a lot of features and is rather small for what it does
(don't get me started on gtk or qt). But what suprised me for example was that
although I had compiled elementary with just the framebuffer backend it 
nevertheless tried to use the X backend unless it was told to not do so (with
ELM_ENGINE=fb). So there apparently is code there which strictly speaking 
doesn't has to be there.

Another thing is the lua/embryo thing. If I am not mistaken they basically do 
the same thing so it should be possible to only use one of the two. Lua was
added recently and should become the default, right? So embryo will go away in
the long run, correct? But I guess it will be needed for backwards compatibility
anyway so in my opinion it should be possible to disable lua at compile time.

> to reduce complexity i would even remove fonts. what i'd do is:
> 1. every bootable os provides as well as kernel in /boot/zImage (or wherever),
> it provides a /boot/bootIcon - this is a simple zlib compressed (see zlib docs
> on how to simply give it a chunk of data to compress, or decompress). you could
> avoid compression if u want, but i think this would be worthwhile. lets say the
> icon data is RGBA (lets use a universal format to account for different
> devices with different screen depths/formats). aany bootable os must provide
> this file or it wont be listed. (yes it's an added requirementm but moving work
> to the bootable os's i takes it out of the qui boot image)
> 2. within the qui boot fs u include some /boot/wallpaper file - same format as
> icons.
> 3. you load wallpaper, convert to screen depth in the simplest/dumbest way
> (speed isnt important. you are not doing realtime ui rendering). eg for 16bpp
> this would be:
> unsigned int *inpix;
> unsigned short *outpix;
> *outpix = (((*inpix & 0xff0000) >> 19) << 11) | (((*inpix & 0xff00) >> 10) <<
> 5) | ((*inpix & 0xff) >> 3);
> i'll leave it up to you to handle other screen formats (32, 24, 18, 15, 12,
> 8bpp etc.). but one per format.
> now blend the icons u find (u'll probably just want to blend agaibnst the
> original rgba wallpaper image and then convert thr result to screen format like
> above - see google for alpha blending math. its rather simple. it's easy to do,
> its much more work to do FAST. here speed isnt important as u are just going to
> render this once and put it up - no realtime ui), one at a time on the screen
> eg:
> +-------------+
> |             |
> | [ 1 ] [ 2 ] |
> |             |
> | [ 3 ] [ 4 ] |
> |             |
> | [ 5 ] [ 6 ] |
> |             |
> +-------------+
> ... etc.
> as many as the screen fits - the icons themselves can just be an image (eg a
> penguin) or image + text. u'll probably want to use tslib and get coords when u
> press to see if up press on one of them - then boot that. you should adjust the
> layout based on screen size. eg for landscape:
> +-------------------+
> |                   |
> | [ 1 ] [ 2 ] [ 3 ] |
> |                   |
> | [ 4 ] [ 5 ] [ 6 ] |
> |                   |
> +-------------------+
> this will provide all you need for a grahical boot. it wont be smooth. it wont
> scroll or animate. it wont let you add much more complexity without a lot of
> work (eg configuration panels or more than the above hyper-simple boot), but it
> will function and be very small.

Thanks for your insight. I think it's a little to low level for me right now,
afterall I have a limited amount of time I can spend on this. The key is
probably to get the right balance between the amount of work and usability /
performance. For now I will leave some abstraction layers in and see how
small/fast this can be made. 
> of course it's easy for me to say this. i've done all this kind of stuff
> before. many times. in fact deep down inside efl are semblances of some of
> this, as just a subset of all that efl does. but it does so much more so it's
> not small. in return for that footprint you get a small mountain of features.
> but as i said - easy for me to say the above. i can do it in my sleep -
> it'sw hat i do, but it's up to you to decide if you are up to doing it at this
> low level or not. for any reasonable app you'd end up using enough of efl's
> features to make it worth carrying along its size. it'd be worth the expense,
> but... for you i don't know if you will ever use all those features. it may
> simply not be worth it. as long as u use efl your image is not going to be that
> small. then again you are adding dropbear and thus also enough network config
> tools to set up usbnet

This should be covered by busybox i hope.

> - what about wifi? wireless tools too? how much is the

Not going to happen (at least not by me). The network support is just to
provide a kind of minimal rescue system to ssh in over usb, mount the sd card
and then chroot into the regular system to fix something. It's not intended
to get some kernel + root filesystem from a NFS server over wifi. Anyway if the
usb network support should be the few KBs which make it to large/slow then I
will probably drop them. 

> image size when you remove any of the ui bits - all your other parts (libc,
> busybox, dropbear, network tools to bring up usbnet and/or wifi, wireless
> tools, dhclient if u have wifi... etc. first see how big that is. how big is
> it? then relative to that, look at ui.

I agree that this is the right approach. Antoher interesting thing is how much
an aditional MB actually costs in terms of speed (copy from NAND to RAM).

Below is a listing of my current initramfs files sorted by size. Now that I
compare them to my SHR system I see that they are a lot larger. For example 
libevas-* is only 687K on my SHR. I will have to investigate if this is just
because of the missing optimization flags in my $CFLAGS or what causes this. 

928K	./usr/lib/libevas-ver-pre-svn-04.so.0.9.9
648K	./usr/lib/libedje-ver-pre-svn-04.so.0.9.92
584K	./usr/share/fonts/DejaVuSans.ttf
512K	./usr/lib/libuClibc-
448K	./usr/lib/libfreetype.so.6.3.20
384K	./usr/lib/libelementary-ver-pre-svn-04.so.0.5.1
356K	./usr/bin/busybox
328K	./usr/share/elementary/themes/default.edj
272K	./usr/lib/libjpeg.so.7.0.0
224K	./usr/lib/libpng12.so.0.40.0
212K	./usr/sbin/dropbearmulti
168K	./usr/lib/libecore-ver-pre-svn-04.so.0.9.9
108K	./usr/lib/libeet.so.1.2.2
100K	./usr/lib/libeina-ver-pre-svn-04.so.0.0.2
88K	./usr/sbin/kexec
84K	./usr/lib/libz.so.1.2.3
84K	./usr/lib/libecore_evas-ver-pre-svn-04.so.0.9.9
80K	./usr/lib/libm-
68K	./usr/lib/libpthread-
44K	./usr/lib/libembryo-ver-pre-svn-04.so.0.9.9
44K	./usr/lib/libecore_con-ver-pre-svn-04.so.0.9.9
40K	./usr/lib/libecore_fb-ver-pre-svn-04.so.0.9.9
28K	./usr/lib/evas/modules/engines/fb/linux-gnueabi-armv4tl-ver-pre-svn-04/module.so
24K	./usr/lib/libecore_file-ver-pre-svn-04.so.0.9.9
24K	./usr/lib/ld-uClibc-
24K	./usr/lib/evas/modules/engines/software_generic/linux-gnueabi-armv4tl-ver-pre-svn-04/module.so
20K	./usr/lib/evas/modules/loaders/jpeg/linux-gnueabi-armv4tl-ver-pre-svn-04/module.so
16K	./usr/lib/libecore_input-ver-pre-svn-04.so.0.9.9
16K	./usr/lib/libcrypt-
16K	./usr/lib/evas/modules/engines/buffer/linux-gnueabi-armv4tl-ver-pre-svn-04/module.so
12K	./usr/lib/libdl-
8.0K	./usr/lib/ts/variance.so
8.0K	./usr/lib/ts/linear.so
8.0K	./usr/lib/ts/input.so
8.0K	./usr/lib/ts/dejitter.so
8.0K	./usr/lib/libutil-
8.0K	./usr/lib/libts-1.0.so.0.0.0
8.0K	./usr/lib/librt-
8.0K	./usr/lib/libresolv-
8.0K	./usr/lib/libnsl-
8.0K	./usr/lib/libecore_job-ver-pre-svn-04.so.0.9.9
8.0K	./usr/lib/evas/modules/savers/png/linux-gnueabi-armv4tl-ver-pre-svn-04/module.so
8.0K	./usr/lib/evas/modules/savers/jpeg/linux-gnueabi-armv4tl-ver-pre-svn-04/module.so
8.0K	./usr/lib/evas/modules/savers/eet/linux-gnueabi-armv4tl-ver-pre-svn-04/module.so
8.0K	./usr/lib/evas/modules/loaders/png/linux-gnueabi-armv4tl-ver-pre-svn-04/module.so
8.0K	./usr/lib/evas/modules/loaders/eet/linux-gnueabi-armv4tl-ver-pre-svn-04/module.so
8.0K	./usr/lib/eina/mp/eina_chained_mempool.so
8.0K	./usr/bin/dialog
4.0K	./usr/sbin/init
4.0K	./usr/lib/ts/tatung.so
4.0K	./usr/lib/ts/pthres.so
4.0K	./usr/lib/libecore_txt-ver-pre-svn-04.so.0.9.9
4.0K	./usr/lib/libc.so
4.0K	./usr/lib/eina/mp/eina_pass_through.so
4.0K	./usr/etc/ts.conf
4.0K	./usr/etc/passwd
4.0K	./usr/etc/fb.modes
> one thing i can suggest. you can drop edje and elementary and do this in just
> ecore_evas + evas. you could even drop eet here. just 1 image format loader (eg
> libpng), and you'd be able to i think have a subset of ecore (ecore,
> ecore_evas, ecore_input, ecore_fb), and just evas + buffer, software_generic
> and fb engine and just png loader module. no savers modules.
> now you'd need to create all your own "widgets" - but you could stick to a
> simple design as above just an array of icons. load the icon files (now u can
> make them .png files in the boot dirs of the os's) and put them on the screen.
> you can now easily add callbacks for the mouse down (or up really) on each icon
> and boot the appropriate os. wallpaper can also be a png file in the qui boot
> fs. you will be using efl at a lower level. you handle the callbacks directly
> and place the objects yourself (and handle canvas resizes - yes it can happen
> even on the fb. eg a resolution change, but in general handling this right
> just handles the inital fb size right anyway). this will mean you donthave to
> handle rendering code and different screen formats, image loading or tslib
> interfacing etc. it should have you a much reduced efl footprint. but keep you
> from the lowest ugliest bits. hell if you keep all the "os info for the ui"
> inside the png font handling is moot. u will still need freetype - but u just
> put name of the os image into the icon itself (nothing 10 seconds in gimp cant
> do).
> so to repeat
> 1. either full efl, elementary etc. - but this will be a big footprint. always
> 2. subset of efl and keep your ui simple eg as i described above and punt off
> all the os identification to a png icon as i described above and justddumbly
> display it and handle events when the user presses it. smaller than full efl
> but not totally minimal.
> 3. do it all yourself at the lowest levesl. as small as it will get but by far
> the most amount of work for you.

Thanks for this nice overview.

I would like to try it in that order and see how useable it is speed wise and
if it's too slow then move to the next variant and remove one layer of 

For now I am working with option 1. As I said in my first mail it would be nice
to use the same technology just with a different backend and therefore reuse all
the work you and others have put into it.

Option 3 (although probably not as low level as you described it) is what 
kexecboot does. It would therefore be an option to add touchscreen support to 
kexecboot. I would probably not be as pretty as an elementary based solution
if there are people who actually care about the optical aspect of the thing. 
> > Proof of Concept
> > ================
> > 
> > As a proof of concept I started to write a simple shell script (well
> > in the beginning it was simple in the meantime it evolved in kind of 
> > mini build system, maybe something like OpenWRT could be used but I
> > wanted a simple solution where I actually understand what's going on) 
> > which downloads and cross compiles everything with an uclibc based 
> > toolchain.
> > 
> > So far I have cross compiled all the components mentioned in this 
> > post the result is about 6-7MB large.
> > 
> > I then tried to run the elementary dialog application from the 
> > elementary wiki page[3] in a chrooted system and this works
> > (although there seems to be a problem with the touchscreen which
> > doesn't quite work right and sometimes even causes a segfault).
> do you have ts calibration working? 

Don't know yet, I have just copied over the ts.conf from SHR so that it at least
uses the same/right modules. Touchscreen calibration is the next thing I need
to look into. Because I tested this in a chroot from within a SHR system I 
thought the touchscreen would already be in a redy-to-use state (i.e calibrated)
is this a wrong assumption? 

Anyone want to share a known to work receipt for touchscreen calibration on 
the Freerunner?

> you may actually have problems here in that
> if the ts is not calibrated and u dont have the right calibration data, it may
> not be totally useful. but this depends from device to device. as for segv.
> backtraces please! :)

Will have to reproduce it later on.

Thanks for your comments.


 Marc Andre Tanner >< http://www.brain-dump.org/ >< GPG key: CF7D56C0

More information about the devel mailing list