Skip to content

Compiling GRUB2 for Coreboot

Antonizoon edited this page Oct 7, 2014 · 3 revisions

Note: This guide is outdated and needs to be updated for the newest Libreboot build scripts.

Libreboot's default configuration has GRUB2 installed onto the BIOS chip, which requires recompilation and reflashing of the BIOS to configure; this can be a new experience for most people.

Make sure Libreboot's X60_source/ archive is extracted and ready to use.

Building GRUB2 From Scratch

The first thing to do before making any modifications is to build the GRUB2 binary for Coreboot, from scratch.

Download the latest GRUB2 source code from GNU Savannah. Then enter the grub/ folder.

git clone git://git.savannah.gnu.org/grub.git
cd grub

Build GRUB2 with the following commands (as a normal user):

make clean
./autogen.sh
./configure --with-platform=coreboot
make

Note: If you are building GRUB2 a second time, it is strongly recommended that you start with a fresh copy of the X60_source/grub/ folder, or the build may fail.

Editing grub.cfg

Return to Libreboot's X60_source/ folder. Under that folder are the files grub.cfg and grub-memdisk.cfg.

  • grub.cfg is installed to cbfs (coreboot filesystem). Make all edits to this config file.
  • grub_memdisk.cfg goes into the grub memdisk. Do not edit this file, it exists simply to load grub.cfg from cbfs (coreboot filesystem).

Open up and edit the grub.cfg file. Below are examples of some useful modifications:

Change the default boot partition

By default, the grub.cfg is set up to boot from /dev/sda1 (the first partition), as shown below:

menuentry 'Boot kernel directly from /dev/sda1 (processor.max_cstate=2)' {
    linux  (ahci0,1)/vmlinuz root=/dev/sda1 processor.max_cstate=2
    initrd  (ahci0,1)/initrd.img
}
menuentry 'Boot kernel directly from /dev/sda1 (idle=halt)' {
    linux  (ahci0,1)/vmlinuz root=/dev/sda1 idle=halt
    initrd  (ahci0,1)/initrd.img
}
menuentry 'Boot kernel directly from /dev/sda1' {
    linux  (ahci0,1)/vmlinuz root=/dev/sda1
    initrd  (ahci0,1)/initrd.img

If your chosen Linux system, or root partition is not located on the first partition, grub.cfg must be modified accordingly.

For example, if the Linux system or root partition is located on /dev/sda2 (the second partition), change the first three entries of grub.cfg to the following:

menuentry 'Boot kernel directly from /dev/sda2 (processor.max_cstate=2)' {
    linux  (ahci0,2)/vmlinuz root=/dev/sda2 processor.max_cstate=2
    initrd  (ahci0,2)/initrd.img
}
menuentry 'Boot kernel directly from /dev/sda2 (idle=halt)' {
    linux  (ahci0,2)/vmlinuz root=/dev/sda2 idle=halt
    initrd  (ahci0,2)/initrd.img
}
menuentry 'Boot kernel directly from /dev/sda2' {
    linux  (ahci0,2)/vmlinuz root=/dev/sda2
    initrd  (ahci0,2)/initrd.img

The critical difference is that all instances of (ahci0,1) is changed to (ahci0,2), and /dev/sda1 is changed to /dev/sda2 .

Likewise, if the Linux system or root partition is located on /dev/sdb1 (the second hard drive's first partition), change the first three entries of grub.cfg to the following:

menuentry 'Boot kernel directly from /dev/sdb2 (processor.max_cstate=2)' {
    linux  (ahci1,2)/vmlinuz root=/dev/sdb2 processor.max_cstate=2
    initrd  (ahci1,2)/initrd.img
}
menuentry 'Boot kernel directly from /dev/sdb2 (idle=halt)' {
    linux  (ahci1,2)/vmlinuz root=/dev/sdb2 idle=halt
    initrd  (ahci1,2)/initrd.img
}
menuentry 'Boot kernel directly from /dev/sdb2' {
    linux  (ahci1,2)/vmlinuz root=/dev/sdb2
    initrd  (ahci1,2)/initrd.img

If you are dual booting two different Linux systems, it can be advantageous to have entries for both:

menuentry 'Boot Trisquel kernel directly from /dev/sda3  (processor.max_cstate=2)' {
        linux  (ahci0,4)/vmlinuz root=/dev/sda4 processor.max_cstate=2
        initrd  (ahci0,4)/initrd.img
}
menuentry 'Boot Netrunner kernel directly from /dev/sda2 (processor.max_cstate=2)' {
        linux  (ahci0,2)/vmlinuz root=/dev/sda2 processor.max_cstate=2
        initrd  (ahci0,2)/initrd.img
}

Boot Ubuntu/Debian/Trisquel LiveUSB Systems

For some reason, the ISOLINUX detection has never worked whenever I wanted boot a LiveUSB, to install Trisquel. Instead, I had to add this GRUB entry:

menuentry 'Boot Ubuntu/Debian/Trisquel LiveUSB' {
        linux (usb0)/casper/vmlinuz boot=casper noprompt noeject processor.max_cstate=2
        initrd (usb0)/casper/initrd
}

That entry is designed for LiveUSB systems that use Casper, which is exclusive to Ubuntu/Debian/Trisquel LiveUSB. Other distributions will have to find different means; perhaps with SeaBIOS.

Add SeaBIOS as a GRUB2 Payload

One interesting payload that can be added to GRUB2 is SeaBIOS itself.

SeaBIOS can be very useful for booting Windows, or Linux liveUSB sticks the same way as any typical BIOS.

  1. Download the SeaBIOS source code, preferably to a folder named X60_source/seabios .

     git clone git://git.seabios.org/seabios.git seabios
    
  2. Configure SeaBIOS using make menuconfig:

     make menuconfig
    
  3. Set the following variables in menuconfig:

     CONFIG_COREBOOT 1
     CONFIG_DEBUG_SERIAL 1 
    
  4. Build SeaBIOS using the following command:

     make
    
  5. Enter the X60_source/ folder.

  6. Add this entry to the bottom of grub.cfg :

     menuentry 'Enter SeaBios' {
             set root='memdisk'
             echo    'Loading SeaBios ...'
             chainloader /bios.bin.elf
     }
    
  7. Enter the X60_source/grub/ folder.

  8. Create a temporary memdisk/ folder to hold payloads in.

     mkdir memdisk
    
  9. Place the compiled SeaBIOS payload into the X60_source/grub/memdisk folder.

     cp ../seabios/out/bios.bin.elf ./memdisk/
    
  10. Optionally, a bootsplash image for SeaBIOS itself can also be added using this command:

     cp bootsplash.png  ./memdisk/
    
  11. Finally, enter the memdisk/ folder and build the GRUB2 payload, with all of it's subpayloads embedded:

     cd memdisk
     ../grub-mkstandalone \
       --grub-mkimage=../grub-mkimage -O i386-coreboot -o ../grub2-X60_debug.elf \
       --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos xfs ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs minix_be minix minix3_be minix3 minix2_be minix2 zfs ufs2 ufs1_be ufs1 udf squash4 romfs jfs reiserfs procfs odc ntfs nilfs2 newc iso9660 hfsplus cpio exfat cpio_be afs btrfs bfs hfs video_bochs password png keystatus sleep loopback gfxterm_background' \
       --install-modules='syslinuxcfg bsd ls cat echo linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test' \
       --fonts= \
       --themes= \
       --locales= \
       -d ../grub-core/ \
       /boot/grub/grub.cfg=../../grub_memdisk_serial.cfg \
       $(find -type f)
    
  12. A GRUB2 payload, grub2-X60_debug.elf will be created under the folder X60_source/grub/ . Now skip the Creating a GRUB2 Payload section and go directly to the Building Coreboot with GRUB2 Payload section.

Tip: Once you've created a GRUB2 payload using this method; obviously, the section Creating a GRUB2 Payload can be skipped.

Add Memtest+ As GRUB2 Payload

Follow the same directions as SeaBIOS, but compile memtest+ instead, and add the below to grub.cfg (though it does deserve it's own instructions, will write them later)

menuentry 'Boot Memtest86+ (requires serial output, baud 115200)' {
    set root='cbfsdisk'
    chainloader /memtest
}

GRUB2 Background Image configuration

Note: With this configuration, if the background image is not found, it will safely revert to defaults.

If a PNG image will be used as the background, add the below config to the top of grub.cfg:

# background image configuration
insmod png
#insmod jpeg
if background_image (cbfsdisk)/background.png; then
  true
else
    set menu_color_normal=light-green/brown                                                                
    set menu_color_highlight=red/blue                                                                      
fi

If a JPEG image will be used as the background, add the below config to the top of grub.cfg:

# background image configuration
#insmod png
insmod jpeg
if background_image (cbfsdisk)/background.jpg; then
  true
else
    set menu_color_normal=light-green/brown                                                                
    set menu_color_highlight=red/blue                                                                      
fi

Make sure the background image is exactly 1024x768 in size (1400x1080 if an SXGA+ screen is used).

Then continue to Creating the GRUB2 Payload.

Creating the GRUB2 Payload

To create a GRUB2 payload with serial debugging enabled, enter the X60_source/grub folder and use this command:

./grub-mkstandalone \
  --grub-mkimage=./grub-mkimage -O i386-coreboot -o grub2-X60_debug.elf \
  --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos xfs ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs minix_be minix minix3_be minix3 minix2_be minix2 zfs ufs2 ufs1_be ufs1 udf squash4 romfs jfs reiserfs procfs odc ntfs nilfs2 newc iso9660 hfsplus cpio exfat cpio_be afs btrfs bfs hfs video_bochs password png keystatus sleep loopback gfxterm_background' \
  --install-modules='syslinuxcfg bsd ls cat echo linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test' \
  --fonts= \
  --themes= \
  --locales= \
  -d grub-core/ \
  /boot/grub/grub.cfg=../grub_memdisk_serial.cfg

To create a GRUB2 ramdisk with serial debugging disabled, use the command below.

Warning: We strongly recommend that you enable serial debugging. In case the grub.cfg doesn't work, serial debugging makes it possible to enter grub commands manually through an external serial terminal. Note that a Ultrabase X6 is needed in the event that serial debugging is necessary, since it adds a serial port to the ThinkPad X60.

./grub-mkstandalone \
  --grub-mkimage=./grub-mkimage -O i386-coreboot -o grub2-X60_debug.elf \
  --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos xfs ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs minix_be minix minix3_be minix3 minix2_be minix2 zfs ufs2 ufs1_be ufs1 udf squash4 romfs jfs reiserfs procfs odc ntfs nilfs2 newc iso9660 hfsplus cpio exfat cpio_be afs btrfs bfs hfs video_bochs password png keystatus sleep loopback gfxterm_background' \
  --install-modules='syslinuxcfg bsd ls cat echo linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test' \
  --fonts= \
  --themes= \
  --locales= \
  -d grub-core/ \
  /boot/grub/grub.cfg=../grub_memdisk.cfg

A file named grub2-X60-debug.elf or grub2-X60.elf will be created under the X60_source/grub/ folder.

Copy that file to the X60_source/coreboot/ folder.

Building Coreboot with GRUB2 Payload

Note: If serial debugging was disabled on your GRUB payload, it will be named grub2-X60.elf. Rename it to grub2-X60-debug.elf so that it will be found by Coreboot. Alternatively, run make menuconfig and change the name of the GRUB payload accordingly.

Enter the X60_source/coreboot/ folder, and run the make command to build coreboot.rom .

Note: If you want to make additional changes to the coreboot config, you can edit .config under X60_source/coreboot/, or run the command make menuconfig in the X60_source/coreboot/ folder.

make

A coreboot.rom file will be created under the X60_source/coreboot/build/ folder. Use the command below to modify the freshly made coreboot.rom for the X60.

cd build; dd if=coreboot.rom of=top64k.bin bs=1 skip=$[$(stat -c %s coreboot.rom) - 0x10000] count=64k; dd if=coreboot.rom bs=1 skip=$[$(stat -c %s coreboot.rom) - 0x20000] count=64k | hexdump; dd if=top64k.bin of=coreboot.rom bs=1 seek=$[$(stat -c %s coreboot.rom) - 0x20000] count=64k conv=notrunc

Modifying the Coreboot image

  1. First, enter the X60_source/coreboot/build/ folder.

  2. Copy the grub.cfg file from X60_source/ to the current folder.

  3. Now, the grub.cfg file needs to be embedded into the cbfs (Coreboot Filesystem). Use the following command to do so:

     ./cbfstool coreboot.rom add -f grub.cfg -n grub.cfg -t raw
    
  4. Then confirm that they exist inside the rom:

     ./cbfstool coreboot.rom print
    
  5. Afterwards, other extra files can be added using cbfstool as desired, such as extra payloads or background images:

     ./cbfstool coreboot.rom add -f memtest -n memtest -t raw
     ./cbfstool coreboot.rom add -f background.png -n background.png -t bootsplash
    
  6. Copy the coreboot.rom file to the X60_source/flashrom/ folder and install it using flashrom. (follow the Coreboot-Second-Flash guide)

Booting from LiveUSBs with GRUB2

Since GRUB2 on Coreboot does not work like a traditional BIOS, special steps need to be taken to boot typical LiveUSB disks.

Try the Parse ISOLINUX menu (USB) option first. It will usually autodetect the ISOLINUX menu and things will work out.

If not, you will have to install SeaBIOS; probably as a GRUB2 payload.

Sources

Testing GRUB2 Payload with QEMU

If you ever recompile GRUB2 and plan to use it as the Coreboot payload, it is strongly recommended that you thoroughly test it using the QEMU emulator.

If GRUB2 doesn't work, your BIOS will be bricked, and external hardware flashing is required for recovery.

Compile Coreboot with GRUB2 as SeaBIOS payload

SeaBIOS is an open source BIOS that works exactly like the typical old legacy BIOS. Since SeaBIOS is guaranteed and tested to work, we strongly recommend using it.

First, build Libreboot with SeaBIOS as shown above. Then, compile GRUB2.

Next, use these commands to add GRUB2 as a payload of SeaBIOS.

build/cbfstool build/coreboot.rom add-payload -n img/grub2 -f grub2.elf -t raw
build/cbfstool build/coreboot.rom print
BA Logo

Bibliotheca Anonoma

Coreboot Laptops

Coreboot is an open source, user configurable BIOS. However, it does use a few proprietary blobs here and there.

ThinkPads

These require hardware flashing. Due to Intel Management Firmware, proprietary blobs are required for newer Intel motherboards to even power up.

Chromebooks

Most Intel Chromebooks come with Coreboot preinstalled. SeaBIOS can optionally be installed to add Windows support.

Just use John Lewis's Installation Script for All Models to autoinstall.

Build Notes

NOTE: The Libreboot components of this wiki was divested into the Official Libreboot Documentation here. Please use that from now on.

Libreboot laptops are certified by the FSF to protect your freedom.

They contain no proprietary blobs of any kind, and have the best support for FSF certified GNU/LInux.

ThinkPads

Macbooks

Other Tutorials

Clone this wiki locally