Recent site activity

Home‎ > ‎

Biffboot


The Bifferboard bootloader is called Biffboot.  It allows flashing a new kernel to the on-board flash (via ethernet or serial port), and setting various boot options.

History of previous versions. If you want to upgrade your bootloader, you need to use BiffJTAG.

Programming a kernel via the serial port

Serial programming must be performed from a Linux machine, and uses a tool called bb_upload.py (or bb_upload8.py for 8MB boards), which can be found in the firmware tarballs and in SVN.  Basically, it's a case of running the script giving a serial device and the kernel as argument, then powering on the Bifferboard.  When the Bifferboard powers up it prints the copyright message.  bb_upload.py intercepts this and sends an <ESC> character at the right moment, then issues commands to program the kernel.

You will need a serial console cable, either bought from http://www.bifferos.co.uk, or home-made to use this feature.


Programming a kernel over the ethernet

A custom (non-routable) protocol is used, which means you need to be directly connected to the Bifferboard via a cross-over cable, bridge or a switch in order to do this.  For a 940K kernel, transfer and programming time is around 15 seconds.  A tool called bb_eth_upload.py (or bb_eth_upload8.py for 8MB boards) is used.

It is not possible to set boot options via the ethernet, but noobs will be able to at least flash new kernels and make basic use of the board without a console cable.

How does it work?  The first thing Biffboot does on power-on is to initialise the ethernet hardware and listen for a received packet.  It listens only for 10 milliseconds before shutting off the receiver and continuing with the boot as normal.  A special packet has to be received in that 10 milliseconds, it has to have a destination MAC address which isn't FF:FF:FF:FF:FF:FF (broadcasts are not allowed) and it has to be the correct protocol.  If the correct packet is received it kicks the Bifferboard into programming mode.  Packets are received and actions taken.  Information is transferred in 8k blocks, and each one is verified via md5 before programming.

For those people paranoid about security and afraid that they won't notice someone hammering their network with 'discovery' packets every 5mS waiting for when someone reboots their Bifferboard this feature can be disabled at the serial console.  Ethernet programming cannot be disabled if the Config block has been overwritten though (see below).

Configuration Block

A bootloader configuration block resides 0x4000 bytes into the flash (0x2000 bytes long). The config block has an associated md5 checksum.  If the md5 is incorrect the bootloader will assume that area of flash is occupied by the kernel (or otherwise corrupt) and will load default values.  This means that if you don't want to use default configuration values, you will have 8k less for your kernel.  The configuration block on 1MB devices may be read and written via configfs if the biffconfig module has been loaded in Linux.

Quiet Serial port

The Biffboot serial console now allows a 'silent' boot, but still responds to the <ESC> key, which will drop you into the console menu.  Note that silent includes error conditions.  If the bootloader can't find your kernel and you've disabled the console, it won't tell you.

MMC/SD card  Flash Boot

If the Bifferboard JTAG has been disabled via R19 pull-down an MMC card can be connected to pins 2,3,4,5 of J1.  Most cards can be powered via pins 1 and 6 (+3.3v and GND respectively).  The MMC pins used by the bootloader are fixed (not configurable), you must use:

Pin2:   CLK
Pin3:   MISO
Pin4:   CS
Pin5:   MOSI


More info on how to physicaly hook up a MicroSD card slot can be found there.

MMC/SD booting can only be selected from the serial console menu.  If the card is detected the type will be printed:  MMC, SDSC or SDHC.

Biffboot does not recognise any filesystem on the MMC card, instead a special sector list in the 512-byte MBR at offset 0x100 gives the location and length of kernel sectors.  The structure for each entry in the list is as follows:

struct _kernel_map {
  unsigned long start;   // start sector
  unsigned long count;    // count of sectors to copy
};

Start sector indicates the first sector of a block of kernel data, count indicates the number of contiguous sectors of data.  When the data has been copied Biffboot steps onto the next structure and repeats.  If the start sector is zero, this indicates the end of the list, and the copied kernel will then get booted.  If the count is zero, but the start sector is non-zero this indicates a link to a sector containing additional _kernel_map items.  In this case the sector specified by 'start' is processed as a new series of _kernel_map entries.

The simplest example is a kernel starting just after the MBR, in contiguous sectors, where there will only be two _kernel_map entries:

Entry 1
start = 1   // the sector just after the MBR
count = (Kernel length/512 rounded up)

Entry 2
start = 0   // end of the list
count = 0

In this case the entire sector list may reside in the MBR, and no additional _kernel_map entries are required in further sectors.  With such an arrangement, a partition must be dedicated to the kernel, so this would be created about 5-10MB in size (/dev/sda1), with the rootfs residing on the second partition (/dev/sda2). See this script for help with creating this setup.

To have the kernel in a regular file, and /dev/sda1 usable, requires a program to determine the sectors occupied by the kernel, in a manner similar to the Lilo program.  This may be provided in the future.


Network Boot (TFTP)

If Network booting has been configured, pressing 'g' from the boot menu, or simply powering on will result in the bootloader attempting to load a kernel from a tftp server.

BIFFBOOT> g
Obtaining IP address.
ARP: 192.168.1.65 --> 00:0D:87:A2:54:11
My IP: 192.168.1.159
Server IP: 192.168.1.65
Boot file: initrd_fits_just.img
973344 bytes received from 192.168.1.65
console=uart,io,0x3f8 init=/etc/preinit root=/dev/sda1
[    0.000000] Linux version 2.6.27.5 (wrt@cent) (gcc version 4.2.4) #15 PREEMPT
[    0.000000] BIOS-provided physical RAM map:
etc...


Non-Kernel execution

Sometimes it's convenient to extend the bootloader with additional functionality, before Linux boots.  This could include adding a PXE boot mechanism to perform a network boot, adding the capability to boot from USB disk or CD-ROM, or simply running an OS other than Linux.  It is possible to configure Bifferboard to load the binary payload stored in flash much as it would the linux kernel, but then to simply call an entry point at the start.  The loaded payload can be another bootloader, or a BSD kernel, or something home-grown.  The only requirement is that this code is 32-bit.  The CPU will have already entered protected mode by the time this runs.

Kernel command-line

It is possible to set the kernel command-line via the serial console.  The maximum allowed length is 1023 bytes.  You will need to embed the command-line in the kernel if you need more than this (unlikely!).


ELF compatibility

Biffboot is capable of booting some Coreboot and Multiboot payloads (such as Memtest86+).  You will need a patch for Libpayload (most coreboot payloads use this), due to the fact that libpayload timing routines rely on the presence of the RDTSC instruction, which the Bifferboard doesn't have.  The patch attached below allows you to build a version of libpayload with the dependency on the TSC removed (you have to deselect the menu option for 'CONFIG_USE_TSC'.


Attachments

Scripts and other files relating to Biffboot have been moved to Subversion:

Č
ċ
ď
bb_eth_config.py
(2k)
Andrew P Scheller,
Aug 18, 2009, 4:34 AM
ċ
ď
bb_eth_config_input.py
(2k)
Andrew P Scheller,
Aug 18, 2009, 4:35 AM
ċ
ď
libpayload-no-tsc.patch
(5k)
Biff Eros,
Feb 4, 2010, 3:16 PM
Comments