lbwww/site/tasks/index.md

89 KiB

title x-toc-enable
Jobs that need doing true

Yes. We already provide other non-coreboot firmware, such as the serprog images. We even integrate U-Boot, albeit as a coreboot payload with some init steps skipped in U-Boot (handled by coreboot).

TF-A is quite an interesting project:

https://www.trustedfirmware.org/

It is essentially an analog of coreboot; coreboot even uses parts of this, on some boards.

general auditing

Libreboot's build system design is already extremely efficient. See: lbmk build system documentation

One of the reasons for this is auditing. The build system is regularly audited. In this context, that means reading the code to check for quality, pre-emptively fix bugs and generally think about the design of the project. Smaller is better.

Code equals bugs, so less code yields fewer bugs. For a general idea of how audits are done in Libreboot, see:

Auditing can often be pedantic, and seem petty. You might commit a patch that reduces the sloccount by only 1 line, maybe 3, but they all add up. Audit 3 contained hundreds of changes, small changes, that together accounted for about 1000 lines of code removed, while not affecting functionality in any way.

Port vendor scripts to Heads

Ironically, one of the first entries on this page pertains to a competing project.

I promised the Heads project that I'd port Libreboot's vendorfile download and inject scripts to the Heads build system. Libreboot provides these scripts for automatically downloading certain firmwares at build time, as and when required for a given mainboard. These are provided by the vendor, e.g. SMSC SCH5545 Environment Control (EC) firmware used for fan control on Dell Precision T1650.

Heads has such logic, but it's not as developed as the logic in Libreboot, which was originally inspired by the Heads logic and then greatly expanded upon.

I'm putting this here on the Libreboot TODO page, so that I always see it. And I'm keeping it at the top of the page. This TODO entry is still relevant to Libreboot, because it concerns work that I will do in my official capacity, representing Libreboot while helping the (friendly) competition.

See: https://osresearch.net/

Heads is a really cool project, offering Linux-based kexec payloads on supported hardware. It's another coreboot distro, and their build system design even works similarly to Libreboot's (though they heavily use Makefiles whereas Libreboot exclusively uses shell scripts and uses a much simpler design). Heads provides many advanced security features like measured boot, even things like TOTP-based authentication using secrets stored in the TPM.

Very, very, very^2 cool project, and Libreboot has plans to integrate some of the same functionalitiys within it (see other notes on this page).

Interesting board ports

Libreboot can support any board from coreboot, in principle. It would also be feasible to integrate other (libre) boot firmware, if desirable. The list below is not exhaustive, it just lists boards that are interesting to us at this time:

Boards

  • HP EliteBook 2760p
  • HP ProBook 6360b
  • HP Revolve 810 G1
  • HP EliteBook Folio 9480m
  • HP EliteBook 8770w
  • HP EliteBook 820 G2
  • HP EliteBook 840 G2 (not in coreboot yet, but should be similar to 820 G2)
  • HP Z220 CMI and SFF mainboards
  • Dell OptiPlex 7010 and 9010
  • Dell OptiPlex 7020 and 9020
  • MSI PRO Z690-A mainboard (supported by Dasharo, not sure about coreboot) - also, Dasharo supports several more mainboards that aren't in coreboot proper.
  • KGPE-D16 and KCMA-D8: use the Dasharo fork of coreboot, instead of coreboot 4.11_branch, because Dasharo's version is much more up to date and more reliable with raminit. D8 isn't supported by Dasharo, but it's not much different code-wise to the D16 mainboard, so differences in coreboot 4.11_branch could be adapted to provide a Dasharo port.

ThinkPad T430s and T431s

These are interesting; the T431s in particular has soldered RAM, so we'd need to take care of SPDs (not done automatically yet, in coreboot). The schematics will show GPIO straps that could be used to glean which SPD data is correct, if we wanted to scan it automatically at boot time (we'd have to include SPD data for all known modules, it might be possible to extract it from vendor updates, otherwise we'd have to dump it from multiple variants of the same machine).

Both are supported by coreboot.

840 G2 (possible 820 G2)

These notes are based on a chat on Libreboot IRC.

The TPM is Infineon SLB9660 and does TPM 1.2. We could maybe upgrade firmware to that of SLB9665. It would no longer work with the HP BIOS but maybe coreboot could be used, and then we could have newer TPM version - SLB9665 firmware can meet TPM 2.0 specification.

(we do not yet use the TPM in any meaningful way on Libreboot machines)

Blobless boards

Not yet supported, but interesting for the project. Separated thus:

already supported by coreboot:

  • ASUS P5Q mainboard (ICH10 / i82801jx), known variants, e.g.: Pro, C, L-Pro, SE
  • Scan coreboot code for ICH9/ICH10 systems, or boards with x4x/gm45 based northbridges. Many of these can boot blobless.

Dell Latitude/Precision:

  • Dell Latitude laptops: E4200, E4300, E5400, E5500, E6500, Precision M4400,

Also E6440 (Haswell machine) - also E6540, 5540, E5440, E3540, E3440, E7440, and E7240 also - Nicholas says only the E6x40 models here have socked CPUs. The rest are soldered.

E7440: https://review.coreboot.org/c/coreboot/+/46540

E7240: https://review.coreboot.org/c/coreboot/+/40300 (original) and rebased to main: https://review.coreboot.org/c/coreboot/+/79746

These typically use MEC5045 or compatible EC. Some may use MEC5035.

SuperIO: at least M6500 is known to use ECE5028. I have a bunch of these Dells at my lab, they are high priority for porting because they would be easily flashable.

Broadwell Dell

E5450 uses MEC5085, currently untested for dell-flash-unlock.

Skylake Dell

https://en.wikipedia.org/wiki/Dell_Latitude#Exx70_Models_(2016)

Non-E models don't have the MEC ECs. The E models have MEC5085.

Nicholas isn't sure whether these have bootguard. TODO: test, and also test with dell-flash-unlock.

Dell Latitude E7240

See: https://review.coreboot.org/c/coreboot/+/79746

Haswell latitude, works with dell-flash-unlock, uses MEC5055 EC. Documentation is included with that patch. It should be possible to re-use the existing MRC extraction logic. It will have to be backported to the branch used for libremrc in lbmk.

NOTE: Iru Cai is the person working on this.

Dell Precision M4800 and M6800

Also M6800, though no port is available yet. 17.3 inch display.

See: https://review.coreboot.org/c/coreboot/+/79755

Another haswell machine. However, according to Nicholas Chin, at least on 1 January 2024, this patch (on patchset 4), there were problems with code quality and libgfxinit didn't work yet - also, the ACPI code seemed to be a dump of the vendor, which is of low quality and likely not suitable for entry into coreboot due to copyright reasons.

This port is worth looking at. When the issues are fixed, this will make a fine addition to lbmk.

E4200 SPD

NOTE: Some of this may be inaccurate, because it's copied from handwritten notes that were written very hastily and are barely legible.

The SPD EEPROM is on the back of the board, between the CPU backplate and the RAM chips. SOIC-8 chip labelled U2. It's a 24XX IC, should be possible to dump using a 3.3v-modded CH341A (on the 24xx socket).

or

modprobe eeprom

look in e.g. 0-0058 or 0-0052 in /sys/bus/i2c/devices

May need other modules like at25 and i2c-i801

The eeprom file in these should contain the SPD data. Just look through a bunch of them until the file is found and seems to be correct.

decode-dimms (utility) can also read eeprom and decode SPD data but doesn't dump the ram eeprom (dumping it in a ch341a as above would do so)

see https://unix.stackexchange.com/questions/92037/how-to-view-rams-spd-timings-table#92044

(yes, that url was also handwritten)

modprobe i2c-dev and sudo i2cdump 0 0x50 works in libreboot, but not the vendor bios.

Other Dells (Ivybridge and Sandybridge)

Nicholas Chin is interested in these:

  • E6520
  • E6420
  • E6320 and E6330
  • E6220 and E6230
  • E5520 and E5530
  • E5420 and E5430
  • 6430u
  • E5520m
  • E5420m

Most/all of these should be easily flashable, with the dell-flash-unlock utility, and many could be ported using autoport as a guide. Nicholas is working on these. They are left here for reference. If you have one of these, please contact nic3-14159 on the Libreboot IRC channel.

Look at the page: https://en.wikipedia.org/wiki/Dell_Latitude#Exx50_Models_(2015)

It lists Dell Latitude models, though "Precision" brand is also available on some models that may be Libreboot-feasible.

ARM-based CrOS devices

Alper Nebi Yasak ported several of these to Libreboot, but only the gru_bob and gru_kevin machines are known to be stable.

It would be nice to re-add veyron-based platforms, e.g. veyron_speedy - old, but still very useful.

The nyan, peach and daisy platforms were initially added to lbmk, but prematurely. They are talked about here:

https://libreboot.org/docs/hardware/#removed-boards

It would be nice in general to support more ARM platforms in Libreboot. None of these machines are as decent as the Apple silicon machines (m1/m2/m3 etc), but they're still decent enough for most computing tasks (and the Apple machines do not currently have coreboot support).

The actual coreboot code for these machines is thought to be reliable. The problem is that the U-Boot port is not yet stable across all these machines. Libreboot has Alper's proof of concept which works well on gru chromebooks.

Caleb is interested in the krane chromebooks, but has had problems with vboot, getting it to boot reliably on custom firmware builds.

OpenSIL and AMD Ryzen

Coreboot is importing OpenSIL code from AMD, to support Epyc Genoa (server platform).

There are also chromebooks now with AMD Ryzen CPUs.

https://github.com/coreboot/coreboot/commit/a859057db8d2eaf59a7575e303d7af35979d12d7

https://github.com/coreboot/coreboot/commit/9e45e32420eda750afea9f6e4a3e6de42ba4152b

NOTE:

9elements seems to be the main entity working on OpenSIL integration in coreboot, under the direction of Arthur Heymans.

also https://www.youtube.com/watch?v=gAZw0fTKdYg

AMD Family16 boards

See: https://review.coreboot.org/c/coreboot/+/71607

This is part of a patch series, from 9 September 2023 onward, re-adding AMD Family 16 platform to coreboot, most notably enabling use of the new allocator and other things in coreboot.

AMD AGESA-based platforms were removed from coreboot, because they weren't being maintained anymore, so they were dropped. Some of those boards are still quite decent today. Various efforts here and there have revived some of them, e.g. the Dasharo project.

Also referenced there: Biostar A68N-5200 mainboard. Check coreboot 4.18_branch for these boards. Coreboot started removing the AGESA boards after release 4.11.

Lenovo G505s

Old board, removed from coreboot ages ago, but one of the fastest pre-PSP AMD laptops, has full init in coreboot - it does require a VGA ROM for graphics. Anyway: http://dangerousprototypes.com/docs/Lenovo_G505S_hacking

This page was linked to me ages ago by Mike Banon. It contains instructions for how to configure the machine. It might be worth integrating into lbmk.

RISC-V hardware

See: https://github.com/oreboot/oreboot

Oreboot is a re-written fork based on coreboot, re-written in Rust instead of C, and it has a strong focus on RISC-V platforms. We should start integrating this into lbmk - although Rust has several disadvantages, oreboot is still a good project.

(though, whenever possible, lbmk should stick to coreboot, to keep things simpler - are there efforts to implement oreboot ports in coreboot/C?)

UEFI payload

A UEFI payload in Libreboot is highly desirable, because it would basically enable any distro or BSD to Just Work.

MrChromebox distribution

MrChromebox is another coreboot distro, similar in spirit to Libreboot.

Of interest: Mrchromebox provides Tianocore-based UEFI setups on chromebooks, and we could probably integrate some of that in Libreboot. Tianocore is essentially bloatware, and really a liability for the Libreboot project due to its complexity, though MrChromebox targets a very different audience.

Chromebooks (x86)

Start supporting x86 chromebooks in Libreboot. We don't support any. There is already MrChromebox, we could just track that, but use our own payloads instead of Tianocore.

Specifically: lbmk could have a feature added to it where it re-uses configs from MrChromebox, with logic to automatically disable the payload. In lbmk, coreboot configs do not enable payloads at all, because payloads are compiled by lbmk and added after the fact - this is why we have elf/ containing coreboot images without payloads, and bin/ which contains the full ROMs, with payloads inside. This design is much more flexible, and permits builds to be re-used more efficiently so as to reduce overall build time, when compiling for multiple mainboards.

U-Boot SPL and UEFI on x86

Simon Glass has been working extensively on x86 support for U-Boot, to be used as a coreboot payload. This work is of interest to the Libreboot project, because we provide UEFI on ARM but not on x86.

U-Boot also provides SPL which can be used to execute other software in the flash, and it's often used to boot a Linux kernel; since U-Boot provides a UEFI implementation, it's perfect.

U-Boot is the preferred choice of UEFI implementation on x86, for Libreboot purposes, because U-Boot uses a coding style similar to Linux and can more easily import Linux drivers which are high quality, and Linux functionality in general, for anything that we need.

Since we already provide U-Boot on ARM (thanks to the continued work done by Alper Nebi Yasak), U-Boot on x86 would then create a situation whereby Libreboot is consistent across platforms, at least for UEFI-based setups.

RockPro64

Another interesting board that coreboot supports. We could add this.

uefistub

Currently under review in the coreboot project, this provides an incomplete UEFI implementation, but much more minimalist than the U-Boot one. It doesn't really do anything except provide the most minimal code possible, and then you can jump to a Linux payload in the flash.

For UEFI purposes, U-Boot seems more mature, and it offers other features like SPL. As already stated, this is the preferred UEFI implementation for Libreboot, but uefistub is listed too because it's interesting.

Videos (plus RISCV)

The Open Source Firmware Conference (OSFC) in 2023 had several interesting talks pertaining to ARM, secureboot, linuxboot, UEFI and everything in between. Also RISCV/oreboot. Here are some videos, some of which contain info already alluded to on this page:

In general, there are many interesting talks:

The talks go all the way back to 2018. They're all worth watching.

Linuxboot

See for inspiration: Heads project and Ownerboot project, these are other coreboot distros similar to Libreboot, but they provide Linux-based payloads. Also see more in general, the Linuxboot project.

Libreboot's build system is documented, see: lbmk documentation.

It's possible to provide a Linux system that runs from the flash. Linux can execute another Linux kernel, using the kexec feature. There are bootloaders that can make use of it, for example the u-root project.

Libreboot's current choice of coreboot payloads are:

  • SeaBIOS (x86 only), provides a traditional PC BIOS implementation
  • GNU GRUB (x86 only), provides a multiboot implementation, can boot Linux and BSD. This is the preferred default payload on x86, especially for Linux distros, because it provides many security features like GPG signature checking on Linux kernels, and password protection.
  • U-Boot (ARM only), provides several boot methods, we typically use the UEFI implementation but it also provides many different boot methods; the one that is most interesting is the SPL (secondary program loader) feature, which is essentially the same concept as loading a coreboot payload - together with something like the minimal uefistub payload, can provide a complete setup.

U-Root in particular (not to be confused with U-boot has parsers in it for GRUB and Syslinux config files. GRUB also has a parser for syslinux configs. This makes it a useful drop-in replacement for the GNU GRUB payload that Libreboot currently uses. Linux has much better drivers than GRUB, especially for things like LUKS2 and networking.

Ideas for how to implement in lbmk

Look at the lbmk documentation for context. The most logical way to implement Linux payloads in Libreboot's build system, lbmk, might be:

  • Re-use the current crossgcc handling in script/update/trees, which is used for coreboot and u-boot. Coreboot's cross compiler isn't very useful for general applications e.g. utilities, but it could compile the Linux kernel easily.
  • Separately to crossgcc, use musl-cross-make for the programs inside initramfs. Use this to provide musl libc, busybox and all of the userland applications in general. Musl-cross-make itself would not be used as-is, but adapted and integrated into the lbmk build system. The design of musl-cross-make is largely compatible with that of lbmk, because both build systems are written in shell scripts and with the same minimalist mentality. 72 source lines! At least as of musl-cross-make git revision fe915821b652a7fa37b34a596f47d8e20bc72338.
  • In each package defined under config/git/ in lbmk, use the current design but support specifying, for each one, whether or not to use musl-cross-make. The current design in lbmk already permits use of make and cmake, for simple projects, otherwise for more complicated setups, a dedicated script is written, e.g. script/build/grub for building the grub images (which runs automake in the grub build system), or script/build/roms which builds rom images.
  • A script, script/build/linuxboot would build the entire payload with u-root in it, but script/update/trees would actually build each package.

BONUS: the musl-cross-make logic could also be used to provide static linked utilities, so as to provide compiled utilities in Libreboot releases, reliably. We currenty only provide source code for utilities, which is not always convenient for users, especially for utilities needed alongside vendor scripts.

If done in the way described above, the current code size in the Libreboot build system would not increase much. It's mainly the addition of musl-cross-make. Most of the generic build logic already exists in lbmk, for projects that use cmake and/or make. It could be done with minimal complexity.

Flash size limitations

With a stripped down kernel, and sensible configuration, about 6-8MB of flash space would be required in this setup. The Heads setup is just under 8MB.

Why Linux in flash?

Linux has better drivers than GRUB, has netboot, and it's much more practical when you want to control the boot process. For example, you could more easily implement measured boot and make use of TPM-based security mechanisms.

For the everyday user, it probably doesn't make much difference if they're already happy with SeaBIOS, GRUB or SeaBIOS.

x86 implementation

Coreboot can directly execute it as a payload, but we would also execute it from the GRUB payload - if running from the GRUB payload, we could just provide it as a vmlinuz and initramfs file.

ARM implementation

We already standardise on U-Boot, for ARM machines. It's debateable whether Linuxboot is even desirable here, U-Boot is quite competent, but the SPL mode in U-Boot could be used to provide the Linux payload setup, OR:

See: uefistub

Although currently only under review, not yet merged anywhere, uefistub seems like a useful way to provide just the most minimal UEFI implementation, required on Linux distros, but all it does it then boot a Linux payload. This is probably what should be used, on ARM platforms, instead of U-Boot, if Linux is to be provided in flash, but the uefistub will use a lot less space than U-Boot. That being said, uefistub does not seem to provide a complete, or even fully correct UEFI implementation.

(then again, linux on bare metal providing kexec as main bootloader method is also quite non-standard, at least on x86 and ARM).

Netboot.xyz

It's unlikely that this will actually be used in lbmk, but this provides a really nice way to boot Linux distros over the network:

https://github.com/netbootxyz

It uses iPXE, whereas we would be using Linux and kexec.

Zfsbootmenu

See: https://docs.zfsbootmenu.org/en/v2.3.x/

Similar in concept to netboot.xyz, but this actually does use Linux. It can boot many distros. We could provide something similar to this in Libreboot.

This was briefly documented on the Libreboot website, before argon2 kdf support was merged in Libreboot GRUB.

Seek QUBES endorsement

Libreboot is compatible with Qubes, on several supported mainboards. This could be audited, to provide a complete list. Qubes has a page on their website which lists compatible devices.

It would be a nice way to promote the Libreboot project, and promote Qubes at the same time, which is an excellent project. We could host a page specifically for it, saying what works on our end, and basically copy that to their wiki.

GRUB VGA modes

VGA support is not universal in Libreboot. We typically rely on GRUB to start in console mode (GRUB_TERMINAL=console), which means GRUB won't change modes, it'll just use whatever mode we started in.

We do not currently modify GRUB's video handling, so some distro setups will try to use VGA modes, or some syslinux configs (that GRUB can parse) will, causing weird behaviour on many Libreboot systems.

TODO: modify GRUB to only have behaviour matching GRUB_TERMINAL=console. See: https://www.gnu.org/software/grub/manual/grub/html_node/Simple-configuration.html

This will prevent the need for modification. In some cases, it is necessary to modify GRUB_TERMINAL in distro grub configs. The way Libreboot's GRUB menu works is, it scans for GRUB and Syslinux/Extlinux configs on the user's HDD/SSD, switching to the first one found.

GRUB configs menu

Libreboot systematically scans for GRUB/Syslinux/Extlinux configs provided by the user's operating system, by scanning partitions. It can also scan encrypted partitions (asking for the user to type their LUKS passphrase).

However, Libreboot switches to the first one found. In some cases, a user may have multiple configurations.

TODO: Keep the current behaviour, for performance reasons, but offer a mode where instead a new menu appears, with menuentries generated, where each one just switches to one of the detected configurations.

This would enable Libreboot to work more seemlessly on dualboot setups, where it is currently assumed that the user would modify grub.cfg in the flash.

This pertains to the GRUB payload provided in the flash, by Libreboot. It is currently the preferred payload in Libreboot, at least for x86 machines.

Document flash write protection

IFD-based method

Already covered, but could be documented more prominently. Use ifdtool --lock libreboot.rom to lock the IFD.

This method is easily circumvented, by enabling the Flash Descriptor Override, which varies from trivial to physically difficult depending on the board.

On some platforms, such as the Dell Latitude E6400, this method is entirely useless; on the E6400, the EC firmware can be instructed to override the IFD settings, by enabling the Flash Descriptor Override (in fact, this is part of what the dell-flash-unlock utility does).

FLILL-based method

We already vaguely mention Intel Flash Descriptor settings ta enable write protection. This documentation should be expanded on.

See: https://opensecuritytraining.info/IntroBIOS_files/Day2_02_Advanced%20x86%20-%20BIOS%20and%20SMM%20Internals%20-%20Flash%20Descriptor.pdf

Actually, look at that site in general:

Anyway:

Universal across all currently known IFD versions, the FLILL section can be used to define invalid opcodes when the flash is used, and this could be used to define write and/or erase opcodes. Up to 4 can be defined.

This could be used to complement existing flash-based write protection. Of particular interest is the fact that the FLILL config cannot be overridden. Setting HDA_SDO (newer platforms) or HDA_DOCK_EN (GPIO33) to enable Flash Descriptor Override, will not affect FLILL entries.

We could document this on the Libreboot website.

SMM write protection

system management mode can also be used, to implement flash write protection.

PR (Protected Range) registers

Differing per platform but defined by Intel datasheets, the Protected Range registers can be set, to enable flash write protection. Once written, these cannot be changed until a reboot. Anything can set them.

This is the preferred method and should be the default (enabled by default), because it can be done from GRUB. So, it could be provided on GRUB setups.

We could make it so that all menuentries in the default Libreboot GRUB menu enable this, when possible on a given mainboard. The GRUB shell would not enable it, and special menuentries that don't enable it could be provided (or an entirely separate GRUB config, e.g. grub_unprotected.cfg).

With the PRx-based method, the user can easily circumvent it when they want to update their firmware. Combined with a passphrase in GRUB, for menuentries and the shell, this would prevent an unauthorised user from updating the system; boot password alone cannot protect against malicious code in the user's operating system, but this method would require a boot password.

It could also be done earlier, in coreboot, but then there's no way to turn it off. Doing it from GRUB (or Linux, when a payload for that is added) seems wiser.

In practise, this should probably not be the default. Libreboot's current default is no write protection, though most Linux distros and BSDs enable protecting /dev/mem by default, that the user can turn off at boot time when they want to flash (e.g. cmdline option iomem=relaxed in Linux, or kern.securelevel=-1 in OpenBSD).

Chip-specific

Some flash chips support their own write protection scheme, covered in their datasheets, but this is usually unreliable or inconsistent. This method is not to be relied upon.

Layers!

Security is all about layers. When you want to lock down the flash, use every method available to you.

lbwww: Document MXM graphics

MXM graphics modules are present, on some laptops that we do not yet support, because certain functionality is needed on them that we do not implement yet.

See: https://codeberg.org/libreboot/lbmk/issues/112

Unlike on several other setups, many of these modules require certain data tables to be present, provided by a BIOS interrupt, which the VGA ROMs then use. These tables essentially contain config for things like ports, and power management. More information, including links to PDF files containing the specs for it, are provided for in the above linked issue page.

Several more high-end HP EliteBook machines use MXM graphics modules, e.g. HP EliteBook 8560w.

MXM works! TODO: merge

Riku got it working. See:

the "int" tool can be used to determine what mxm spec you have, and the mxmdump util can be used to dump the mxm config. on systems where there is no i2c rom, the system firmware (in this case libreboot) must provide it via int15h interrupt. riku's seabios patches implement this.

TODO: Document this properly, if not already documented.

John lane GRUB patches

The GRUB project itself has started merging some of this functionality, for things like detached LUKS headers. We had these for GRUB in Libreboot 2016 releases, but they were since removed.

Current functionality works on most setups, and we merge Argon2 KDF support into GRUB, out-of-tree.

See: https://grub.johnlane.ie/

Interesting, the Arch Linux AUR has several of these patches for its GRUB 2.06 package. See: https://aur.archlinux.org/packages/grub-luks-keyfile

These could be re-based for GRUB 2.12, which is what Libreboot uses.

Already merged

GRUB 2.12 has these patches already, so we don't need to do anything. The above pertains to GRUB 2.06, but they were upstreamed for 2.12. That being said, we do have some users who like 2.06 for some reason!

Document how to use

John lane's site even has instructions for how to use detached LUKS headers in GRUB.

Maybe we could do something for it in automation too. When scanning for grub.cfg files, at the stage where cryptomount -a is executed, we could also check for LUKS header files and handle them if found. Yes, we could make the default Libreboot setup work out of the box, with detached LUKS headers. We already have this functionality, as described above, but we need to configure it. Read John Lane's site for more information, and the upstream GRUB documentation will also cover it.

lbmk-c: clustered builds

I had an idea on IRC when we were talking about how to optimise the build speed in Libreboot. Most of the time is spent simply compiling the ROM images, and this will become especially true when we support hundreds of boards; almost none of the time, by percentage, will be spent on payloads and cross compilers anymore.

So my idea was: what if we had a cluster setup where multiple machines have their own clone of lbmk, but they all stay in sync, re-using the same builds, for example the same crossgcc builds, but each dividing up tasks between each other.

For example, if you have 100 boards and 10 machines, those 10 machines in the cluster would build 10 rom sets each. They would tell each other when they're all done, and then at the end, there would be a process where they're all copied.

This could probably be done using an NFS share, for things like the bin/ directory on the release/ directory. We really will need something like this in the future, because Libreboot's goal is to support literally every coreboot board, providing automated configurations for all of them.

distcc is probably useful here:

https://www.distcc.org/scenarios.html

ccache

not directly related, but this can speed up coreboot builds

Fixdep

This would be something to implement in coreboot's build system, but could also benefit lbmk. Currently, any changes to the coreboot's config results in Make recompiling all objects, even if make clean wasn't run or if the change shouldn't have an effect. This is because the build system force includes the generated config.h header into every source, thus making it a prerequisite of every object. This file contains C macro definitions for the value of all visible Kconfig options, allowing code to reference these values for various purposes. Since all of them are contained in this file alone, any change to the config will cause config.h to be updated, forcing all object targets to be out of date.

Linux solves this using a utility called fixdep (scripts/basic in the kernel sources), which parses all source files and their included headers to determine which configs, if any, an object actually depends on. The config.h prerequisite is replaced with dependencies on the appropriate config options, allowing make to skip rebuilding objects that do not have any config dependencies or where the config has not changed in value.

This may make it possible to avoid running distclean in lbmk between boards, allowing existing objects to be reused if the new board's config does not affect the object. This would reduce the complexity of the build from O(n*m) to the order of O(m), where n is the number of configs and m is the number of source files. For maximum effectiveness using fixdep alone, boards would need to be built in an order that minimizes the differences in configs between sequential builds, otherwise Make may end up rebuilding an object that was built previously but overwritten with a new build due to a change in the config.

Consider:

  • Board A, which sets CONFIG_TEST=y
  • Board B, which sets CONFIG_TEST=n
  • Board C, which sets CONFIG_TEST=y
  • test.c, which uses the value of CONFIG_TEST

An order such as A->C->B would be most efficient:

  1. A: test.c compiled for the first time with CONFIG_TEST=y
  2. C: CONFIG_TEST hasn't changed, so test.o can be reused from step 1
  3. B: test.c recompiled, since CONFIG_TEST changed back to n

An order such as A->B->C would be least efficient:

  1. A: test.c compiled for the first time with CONFIG_TEST=y
  2. B: test.c recompiled, since CONFIG_TEST changed to n
  3. C: test.c recompiled again, since CONFIG_TEST changed back to y, even though this configuration was previously built in step 1.

Given the number of possible configs, the ideal order is likely impractical to determine, and some files may necessarily have to be built multiple times with the same Kconfigs applied. However, the use of ccache would help mitigate this issue, as it would return cached object files when it detects that the sources for the object being built are the same as a previous compile.

All of this should be carefully implemented to ensure that the resulting output is the same as if each file was compiled from scratch each time.

The following article describes the function of fixdep in more detail, under the header "Dependency tracking": https://opensource.com/article/18/10/kbuild-and-kconfig

Nicholas Chin is looking at this in coreboot.

Use crossgcc for SeaBIOS and GRUB

We currently use hostcc for the SeaBIOS and GRUB payloads. This, among other things, means lbmk is currently only supported for amd64 machines.

See other notes on this page about Linuxboot. When that work is done, we will have better infrastructure for cross compilation, which could also be used for this purpose.

In particular, GRUB's build system requires you to build certain utilities first. We use grub-mkstandalone to then provide the coreboot payload. For GRUB specifically, we should therefore use musl-cross-make. SeaBIOS can be built using crossgcc.

Port lbmk to BSD systems

In particular, FreeBSD is of interest.

We probably don't need to natively port it, because FreeBSD has Linux ABI compatibility in its kernel, using linuxlator, and you can bootstrap a Debian system under it.

See: https://docs.freebsd.org/en/books/handbook/linuxemu/

See: https://docs.freebsd.org/en/books/handbook/linuxemu/#linuxemu-debootstrap

We may still need certain build system modifications anyway, but this would probably be mostly just documenting how to use lbmk that way.

FreeBSD specifically offers many advantages, such as really good OpenZfs integration (better than ZFS-On-Linux setups), which it can do natively because the licensing in BSD is compatible; Linux can't merge ZFS due to CDDL licensing.

An actual native port to FreeBSD is also feasible, and coreboot itself already has some support for that, as does GRUB. If using crossgcc to build all payloads, this could be even easier.

Building a Linux kernel might be slightly more challenging, but again: crossgcc.

Adapting musl-cross-make for use in FreeBSD could be interesting. Other notes on this TODO page talk about using musl-cross-make to provide static linked utilities in releases, but this has only Linux in mind. Doing them for FreeBSD may also be desirable.

Libreboot already has excellent support for booting all of the BSDs. Having the build system be compatible would just be another great boon.

Package lbmk in distros

Providing binaries of Libreboot in distros wouldn't make sense, because we do that anyway, on Libreboot RSYNC, but having ports of the build system on various Linux distros and BSDs might be desirable.

Distro package managers could check when changes are made to a given board, and if the system you're on matches that given board, the package manager could provide you with an option to flash it.

This would probably only be provided on systems where that is extremely safe, specifically that those systems have been well-tested. Some ports in Libreboot are a bit flaky and would require extra work.

It's unlikely that this job will ever be done, but it's on the TODO page anyway. Distro package managers concern themselves with OS applications, kernel, libc, bootloaders and so on; Libreboot is a step below them, earlier on in the boot process.

But then again, there are things like fwupd that provide firmware updates in distros, so there's no reason Libreboot couldn't do something equivalent - we could even do binaries, though I'm mostly thinking of the Libreboot build system itself. A distro could package lbmk to build for a specific Libreboot version, and handle all of the dependencies and everything.

Vendor scripts

Bruteforce more files

We bruteforce extract IME but some other firmwares are more or less hardcoded in config.

In particular, VGA ROM extraction could be improved. We could modify the romheaders utility to return zero status or non-zero status based on a given PCI vendor/device ID; non-zero if it's not a match, for a given file, or it isn't a VGA ROM. We currently extract an nvidia ROM for certain models of Dell Latitude E6400, but the logic is more or less hardcoded.

The script at script/vendor/download auto-downloads vendor firmwares needed on certain mainboards, during build time. Libreboot's build system uses the script at script/vendor/inject to add or remove such files after the fact, on release ROMs, because those firmwares are deleted at release time. This work began mostly after mid-2022, and has since been expanded to cover many types of firmwares, used on various mainboards.

Investigate 16MB flash setups

On some ivybridge and sandybridge boards, where flash is 8MB or 12MB, it is feasible (with some soldering) to upgrade it to 16MB setups.

The IFD is configured accordingly, but some board modification besides that may be required. For example, on the ThinkPad T440p, SPI2 is easily accessible but SPI1 requires full disassembly. One could re-wire the board, removing the Chip Select resistor for SPI1, and the SPI2 CS resistor, then re-wiring CS1 to CS2 via a resistor, so that only SPI2 is used (thanks go to Nicholas Chin for describing this idea) - then you stick one big 16MB flash on SPI2, which is easily flashable.

These upgrades are really only recommended for advanced users. We do already provide images for them; 16MB ROM images on many GM45 thinkpads, and also the ThinkPad X230.

A 16MB setup was attempted on the ThinkPad T440p, but didn't boot, and I now believe it was because I didn't insert the MRC firmware at the correct offset during that test. Libreboot's build system now handles that correctly, in the vendorfile inject script at script/vendor/inject.

In IFD-based systems, CS1 and CS2 are separate, but data lines like MOSI/MISO are shared, and the PCH/southbridge will enable or disable the given flash IC to access the region needed.

ME Cleaner status page

See: https://github.com/corna/me_cleaner/issues/3

It's a good reference, though far from complete. People post there saying whether their hardware works with me_cleaner.

Overclocking

See: https://review.coreboot.org/c/coreboot/+/42547

The patch, now abandoned, is a proof of concept tested on Asus P8Z77-V LX2 with i7-2600 and i5-3330. It is possible for coreboot to enable overclocking on some boards, though it's seldom-used and not very universally supported.

It might be useful on some machines. The research here (by Angel Pons) may be transferrable to other platforms.

Better dependencies handling

Lbmk supports handling dependencies, in such a way that a required program is automatically downloaded after the main one. For example, GRUB requires gnulib.

The problem is that it doesn't work in reverse. For example, when you download gnulib, it's actually saved under src/grub/gnulib, and src/grub/ is the directory created when downloading GRUB.

Illustration:

./update trees -f gnulib
./update trees -f grub

This will first download gnulib, but then src/grub now exists, and the second command to download GRUB will fail, because that directory now exists, but does not have anything in it. Some checks for GRUB may then pass, thinking that GRUB has already been downloaded, when it hasn't.

Observe:

no u lbmk$ git clone . test
Cloning into 'test'...
cdone.
 dno u lbmk$ c dtest
bash: c: command not found
no u lbmk$ l^C
no u lbmk$ cd test
no u test$ ls
build	COPYING  projectname  script  util
config	include  README.md    update  vendor
no u test$ ./update trees -f gnulib
Cloning into '/home/leah/Project/lbdev/lbmk/test/tmp/gitclone'...
remote: Counting objects: 281482, done.
remote: Compressing objects: 100% (33030/33030), done.
remote: Total 281482 (delta 248520), reused 281273 (delta 248367)
Receiving objects: 100% (281482/281482), 69.48 MiB | 7.98 MiB/s, done.
Resolving deltas: 100% (248520/248520), done.
HEAD is now at 9f48fb992a filevercmp: fix several unexpected results
no u test$ ./update trees -f grub
src/grub already exists, so skipping download
src/grub/gnulib already exists, so skipping download

In this case, GRUB will now always fail to download, until the src/grub directory is deleted, which would delete gnulib.

The following could be done:

  • Check whether a given location for a download is within a location used by another project, and refuse to do anything if that's the case (exit with error) OR:
  • Automatically download that other program first

It's probably cleaner to go with the first one. Prevent a program downloaded by lbmk from being included within another. If another such program is needed inside another, for example as a submodule, then the program could be modified. For example, modify GRUB to use the location of ../gnulib as the directory for gnulib, where you would then have src/grub and src/gnulib - this can already be done, simply by configuring everything in config/git/, but lbmk currently does not check this.

For comparison, here's what happens if you download GRUB (which defines gnulib as a dependency):

no u test$ rm -Rf src/grub
no u test$ ./update trees -f grub
Cloning into '/home/leah/Project/lbdev/lbmk/test/tmp/gitclone'...
remote: Counting objects: 101717, done.
remote: Compressing objects: 100% (23307/23307), done.
remote: Total 101717 (delta 76079), reused 101552 (delta 75971)
Receiving objects: 100% (101717/101717), 71.90 MiB | 12.85 MiB/s, done.
Resolving deltas: 100% (76079/76079), done.
HEAD is now at 64e3cee72 gpt: Add compile time asserts for guid and gpt_partentry sizes
Applying: mitigate grub's missing characters for borders/arrow characters
Applying: say the name libreboot, in the grub menu
Applying: Add CC0 license
Applying: Define GRUB_UINT32_MAX
Applying: Add Argon2 algorithm
Applying: Error on missing Argon2id parameters
Applying: Compile with Argon2id support
Applying: Make grub-install work with Argon2
Applying: at_keyboard coreboot: force scancodes2+translate
Applying: keylayouts: don't print "Unknown key" message
Applying: don't print missing prefix errors on the screen
Applying: don't print error if module not found
Applying: don't print empty error messages
Cloning into '/home/leah/Project/lbdev/lbmk/test/tmp/gitclone'...
remote: Counting objects: 281482, done.
remote: Compressing objects: 100% (33030/33030), done.
remote: Total 281482 (delta 248520), reused 281273 (delta 248367)
Receiving objects: 100% (281482/281482), 69.48 MiB | 9.55 MiB/s, done.
Resolving deltas: 100% (248520/248520), done.
HEAD is now at 9f48fb992a filevercmp: fix several unexpected results
no u test$ ls src/grub
acinclude.m4	BUGS	      docs	  INSTALL	     po        TODO
asm-tests	conf	      geninit.sh  linguas.sh	     README    unicode
AUTHORS		config.h.in   gentpl.py   MAINTAINERS	     SECURITY  util
autogen.sh	configure.ac  gnulib	  Makefile.am	     tests
bootstrap	COPYING       grub-core   Makefile.util.def  THANKS
bootstrap.conf	coreboot.cfg  include	  NEWS		     themes
no u test$ ls src/grub/gnulib
build-aux	 COPYING	 gnulib-tool.py.TODO  posix-modules
cfg.mk		 DEPENDENCIES	 lib		      pygnulib
ChangeLog	 doc		 m4		      README
check-AC_LIBOBJ  etc		 Makefile	      STATUS-libposix
check-copyright  examples	 modules	      tests
check-module	 gnulib-tool	 MODULES.html.sh      top
config		 gnulib-tool.py  NEWS		      users.txt

A more general audit is in order, overhauling the entire dependencies infrastracture, within lbmk. A lot of the sanity checking is done manually, just by configuring everything sensibly and knowing what pitfalls to avoid.

Libreboot is essentially no different to apt-get, in so far an lbmk is concerned. The apk package manager in Alpine Linux is the closest to lbmk mentality; their package manager is highly advanced, but written with a very minimalist and efficient design. Libreboot's handling of packages and dependencies could be re-modelled using apk-tools as inspiration.

Detect module changes

When a given package is already downloaded and built in some way, lbmk currently works on the assumption that it doesn't change. During development, it is necessary to manually delete certain build artifacts, and know what to delete.

For example, you have to delete src/grub after updating the GRUb revision in lbmk. Lbmk does not, for example, detect when you updated the revision and automatically adjust to the new revision+patches by: 1) undoing all patches and 2) running git pull 3) resetting again to the new revision and applying new patches and 4) cleaning the previous builds

In practise, revisions don't change very often in Libreboot, and they're normally updated all at once, when they are updated.

Normal/fallback scheme

Libreboot currently does not handle the normal/fallback payload scheme at all. Instead, it is assumed that the user will always be booting from the fallback payload, with no normal payload provided. One single payload. This assumption is hardcoded into certain logic, in the build system.

Coreboot supports configuring which scheme to use, at boot time, but we don't use it. Coreboot's default is to always load the fallback, so we use that.

Improved payload documentation

The actual payload documentation is quite sparse in Libreboot, especially SeaBIOS but also GRUB. We don't need to repeat what is said by upstream docs, but we also don't link to them or cross reference them in any way.

We should start writing about the payloads in more detail, referencing upstream documentation whenever possible.

Static compiled utils in releases

We curerntly only provide binaries of the firmware itself, for each mainboard, but we do not provide utilities compiled. We provide only source code, and the user is expected to compile utilities from source.

This can be inconvenient, especially if the user is running the vendorfile download scripts. This should be done alongside providing musl-cross-make for the linuxboot builds.

Download repositories in bulk

At present, lbmk does what it needs to do, and downloads repositories only as required, upon each stage of the boot process. For example, it may download gnulib when downloading GRUb, after having maybe built 5 mainboards all with only SeaBIOS, having built SeaBIOS before those 5 - it doesn't build SeaBIOS and GRUB before the 5.

What this means is that the internet may work at one stage during a build, but for very long builds (ones that take hours, which some do), it may be that the user's internet goes down, and a latter part of the build fails, where it might have succeeded if packages were downloaded much earlier and in bulk.

Optimisation

So, TODO: Make lbmk determine precisely what packages would later be downloaded through various parts of a build, for a given command, and do it all at once, and then build. This is also better because, for very large amounts of modules, that take a long time to install, existing downloaded modules could be built while the download is in progress, to save on overall build time. This would be especially beneficial on slow internet connections, where a larger amount of time is spent downloading that building.

In this context, slow internet means 20Mbps or less. Libreboot downloads a lot of code during the build process. For reasonable build times, it is currently recommended that you run lbmk an on internet connection that is at least 100Mbps. You can still use slower connections, it'll just take longer.

Don't copy src trees

For multi-tree projects, lbmk currently copies the source code per tree, e.g. coreboot/default, coreboot/dell. What could be done instead is to use the existing Git history as-is, and just make a new branch, with whatever patches, at the given revision.

At release time, to save space, the given repository would have its history re-initialised, with the code branches reset per tree, and the source code copied, then committed - this would actually create more copies than lbmk currently does, thus using the disk more heavily, but only during release time. For normal builds (from Git, or from released archives), less disk space would be used, and there would be less disk I/O. This would especially reduce wear and tear on SSDs, where Libreboot is used.

This may have some complications, where submodules are used. A solution to this would be to define those submodule repositories under lbmk's config/git/ instead, and from there, define them as dependencies for a given project. Where a multi-tree project defines them, those dependencies could themselves be treated as multi-tree in the ame way as described above, even if they don't have a configuration for that in lbmk, because they are already used as dependencies in the multi-tree projects - in this case, if no custom config is provided, they would just use whatever revision is used in the defined submodule for the main target project that lbmk is downloading for.

Vendor scripts

Check hashes of resulting files

Libreboot extracts the files from vendor updates, and those updates are checked against known hashes, but lbmk only defines such hashes for the larger updates themselves. hashes for the files extracted could also be defined, mostly as a way to ensure that they were correctly extracted, though it could default back to current behaviour (only check the main file) if individual checksums for inside files are not defined.

Handle submodules manually

Lbmk automatically downloads git submodules (all of them) on a given downloaded repository, when a .gitmodules file is present. This functionality should be retained, but submodules are also not to be relied upon for redundancy.

In some cases, especially critical projects like coreboot, these submodules should be defined by lbmk config/git/ files instead, with redundant repositories, and the host projects (e.g. coreboot) modified to use these, instead of gitmodules.

Git's own submodules logic doesn't handle redundancy really well and it's not very fault tolerant either. Libreboot's lbmk, while less featureful, is designed for redundancy.

What if someone is compiling a given revision of lbmk in 10 years from now? Some of those repository links might have died, or those projects might have experienced a hostile takeover and been overwritten. Anything can happen. If there are backup repository links already baked into lbmk configs, it offers some redundancy in the future.

It also offers some redundancy now, in the present, if a given git server goes offline for a break period of time. Libreboot's design is quite simple, and done with this philosophy in mind, that everything should always have a backup.

Auto-update repositories

Already written elsewhere on this TODO page is to automatically decide which repositories need updating, when running any part of lbmk. This is thought of with the same mentality in mind, always thinking about what someone will be running in the future. You can't predict what will happen, so you have to be prepared. Users are unpredictable.

Reproducible builds

We can't focus on this reliably, because we use hostcc extensively for many parts of the build process. Other parts of this TODO page talk about how to integrate linux as a payload, by improving our cross compiling setup.

Cross compilation is the first step to reproducibility, because then we only have to worry about the toolchain, which is easier to control. We can start focusing specifically on reproducibility once all of that has been done.

Tarballs

We already have partial reproducibility, though we currently use the -T0 option in xz, whereas -T1 is more appropriate; forcing it to run on 1 core will ensure that the file is always compressed in the same way.

See: https://reproducible-builds.org/docs/archives/

We already pretty much are right on the money. The main task that we still need to work on is cross compilation; specifically, we need to actually cross compile, because most code is compiled by hostcc when we use lbmk. This is covered in another section, on this TODO page.

Also: https://lists.debian.org/debian-dpkg/2016/10/msg00012.html

This post writes about the rationale for -T1 when using xz.

VGA: Run-time, not build-time

In coreboot, configuration of video initialisation is done at build time. This has several disadvantages, in that you now need multiple ROM images for multiple configurations, but it has the upside that the resulting ROM image will have fewer bytes of code within it.

From an lbmk perspective, the upsides are largely ignored because we want to build hundreds and hundreds of ROM images, fast. That means reducing the amount of time spent to compile for each mainboard.

We currently do this on each mainboard:

  • libgfxinit with text mode startup, if possible
  • libgfxinit with coreboot framebuffer, if possible
  • vgarom setup when desirable; usually executed by seabios, not coreboot

This is often literally 3 different ROM images, for all of the above. It is possible to have a libgfxinit setup where SeaBIOS is the payload, so that VGA ROMs can be executed aswell, but this has several issues, covered elsewhere on this page.

It would be nice if all of this could be runtime options instead. By "runtime", we do mean modification of the ROM image, but not in a way that requires a full re-build. A good example of this would be the SeaBIOS runtime setup:

https://www.seabios.org/Runtime_config

On SeaBIOS, it is not necessary to re-build for the most part (though some things are still left to build-time config). Instead, you edit files inside the coreboot file system (CBFS), that SeaBIOS will use to configure itself at boot time.

We could take a note from SeaBIOS and do that here, but in coreboot. Why is it that we need separate ROMs just to switch between the coreboot framebuffer or classic text mode startup? Why can't it be the same ROM?

If we were to do it at runtime like described above, we could cut the build time in half, or even more than half; we could cut it down to about 30% of the current time. Disabling libgfxinit could also be a runtime option. It's already possible to change the payload at runtime for instance (manually), by running cbfstool.

Modularise the coreboot stages

ie. generate cbfs in lbmk

We currently use the coreboot build system which is designed to build all stages, such as the bootblock, car, ramstage, romstage etc. The coreboot build system already builds these separately, as separate binaries, and then joins them all together inside the CBFS (coreboot file system) of the target ROM image. Essentially, coreboot creates the empty file containing CBFS, and starts adding all of the files.

The logic is already there in coreboot, but it does everything all at once.

We might benefit from splitting this, within the coreboot build system, so that it's possible to do one stage then another, separately, and then we could use lbmk to join them, initialising the CBFS and adding all of the stages.

This could be useful when we do actually need a build-time configuration changed, but where many stages are identical between different build-time setups. This could then be abused, to substantially reduce the overall build time in lbmk. We want to build hundreds of ROM images in coreboot, and that takes time - too much time.

This will require working with upstream, and in practise require that they accept such proposals. The build system design in coreboot is already ready for this sort of thing, and it could be done with minimal complexity - the current behaviour would be retained as a default.

We might have to backport to some older revisions, because lbmk uses certain older revisions on some machines, e.g. AMD AGESA platforms.

Macbook21 C-states patch

See: https://review.coreboot.org/c/coreboot/+/63587

We currently re-use the same ROM image for macbook21 on the imac52, but it is now believed that the C-state config there is not suitable on imac52. See patch.

TODO: test on imac52 and macbook21. If confirmed (again, see patch, the problem is described there), we can expand it to configure c-states differently on imac52. This config is used to enable efficient power management, on these machines.

How to dump c-state config

i2cdump 0x69

dump the c-state config from apple efi firmware

imac5,2 breaks with the current c-state patch used in libreboot, according to f_ on IRC.

powertop can give info about available c-states

also: don't use efi grub or anything efi on non-macos operating systems on these machines, doesn't work well in apple's firmware. mentioned by avph in the gerrit link (see above)

Check file ownership in builds

When lbmk is running, it is assumed that the current user has ownership of the files. If lbmk is operated on a clone that is under different ownership, it might fail in strange ways; for example if you had read access but not write access. There is already general error management all over lbmk, where a given command returning non-zero status will result in lbmk pretty reliably exiting, and printing the error on screen for the user.

However, we do not specifically check permissions/ownership of files. For example, the user might have cloned lbmk as root to run the dependencies script, and then they want to run lbmk. We already make lbmk exit, with non zero status, if it's run as root, for safety reasons, but this does not apply when lbmk is run on a clone that is owned by another user.

Lbmk could specifically check for this at startup, and provide a specific warning message to the user, so that they know what to do to fix it. Lbmk would also then exit earlier, rather than trying to run something, which might result in very unpredictable behaviour.

Sanity checks

We basically should have startup sanity checks in general, such as checking whether all the right dependencies are installed on the host system - similar to autoconf setups used by many GNU projects, though we don't want to use autoconf, it's bloat.

If a sanity check is passed, a configuration file can then be provided, which can be used to control how lbmk runs. For example, if a certain version of a library is installed that behaves differently from a newer version, lbmk might have logic implemented that makes it behave differently depending on which library is installed. The general goal of lbmk is to be as portable as possible, but without introducing too much complexity into its design, so this TODO item will have to be handled with a lot of core.

Remember the mantra: code equals bugs.

We are running lbmk on extremely buggy systems, such as Linux. We do not yet have native support for running on BSD systems for example. This TODO entry is basically the same thing as the other entry on this page about porting to BSD. So tackle both.

Software Bill of Materials

Generate an SBOM for all of Libreboot, on release builds specifically; it can be skipped for performance/convenience reasons on regular development builds from git. See: script/update/release - it would be handled here, because this is the script that actually generates full release sets.

SBOM is a requirement now, in many commercial contexts, depending on how software is used, or how it's shipped. For example, if you're providing software to certain government departments, in certain countries, they may require it.

We can't know where Libreboot will be used. Let's automate this problem so that our users don't have to. Coreboot already has some support for this, in its build system, and we could adapt the build systems of other projects, and tie it all together from lbmk.

The way lbmk works makes it very simple to implement something like this. The SBOM is literally just a thing that says what's included in a software release, or an aggregate distribution of software in our case. Libreboot's build system already has to have things like repository links, revisions, lists of patches and so on, to know how each piece of software is configured.

I'd say this would be handled in, say, include/sbom.sh within lbmk, with a minimal stub in script/update/trees that handles it. All it would do is generate an sbom file by reading everything under config/. This would not be used automatically, during regular development builds, but it would be used by script/update/release. It could output the sbom to regular stdout, with errors outputted to stderr (specifically, and deliberately - like if a certain piece of software is missing or disabled or something, write about that in stderr, though the actual sbom data would be on stdout).

Let's say you do it as -z - ok, but the script handles specific projects. So now we do:

./update trees -z coreboot

This is just one example. The trees script already knows how to read configs of all the projects, so that it knows how to download and build them. It would just output that in a parseable format, to stdout. Then you might do for example:

./update trees -z coreboot 1>sbom.txt 2>sbom.txt.err

But oh, what's this? We already know that the trees script can handle multiple projects. For instance:

./update trees -z flashprog pico-serprog grub seabios

Then it would output for all of those. It just goes in a loop.

This is just an idea. Anyway, this should go hand in hand with reproducible builds, which is mentioned elsewhere on this TODO page.

This is a very unix-y way to do an sbom, in lbmk, which is already a very unix-esque build system design. Write one thing that does one thing well. We pretty much already have everything we need to implement this.

NOTE: The above is not necessarily the best way to handle an SBOM, it's just one possible idea off the top of my head, proposed that way because it would minimise the amount of complexity needed in lbmk, to handle that use-case.

NOTE: the -z option in ./update trees is not yet implemented. Again, the above just a concept.

Re-use build artifacts

Libreboot's build system, lbmk, does not re-use artifacts well. It largely assumes that you are building everything from scratch, which is great for release builds and is very simple, but sometimes that can be annoying during development. This pretty much goes hand in hand with the other TODO item on this page, about lbmk checking itself when a given codebase or config gets updated, so that it can adapt itself.

Most notably, lbmk runs distclean on most/all codebases before then running make-all. This is done for simplicity, and in practise usually works OK because most projects only get built once, unless they are modified (by a developer).

This might be useful for:

Partial coreboot re-builds

A lot of the time in lbmk, we are building multiple variants of the same mainboard, for different setups. We could skip a lot of the re-building. This pretty much goes hand in hand with the other entry on this TODO page, about spliting up the various stages in coreboot, and handling CBFS generation within lbmk.

Notes about Git

See: https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/

This guide has some useful information about using Git, and some of it may be useful for this goal. There are many cases where we download all of the Git history for a given project, where we really only need a small part of it. We could speed up the downloads a lot, and also speed up the builds a bit (by reducing the amount of deltas that need to be resolved when cloning).

In particular, Git Work Trees are a useful feature that we might use in lbmk.

Scan submodules for backups

Where a project does use submodules, it's possible that we may already define how to download it, with redundant links. We could scan for this, by parsing the .gitmodules file within a project and comparing to what we have under config/git/.

Chinese users can't run lbmk

Libreboot has quite a few Chinese users, but the Chinese internet blocks access to several sites like github - and apparently the coreboot gerrit site is also blocked, where we clone coreboot from.

We'd need to get Chinese internet users to test this, but lbmk should be modified to work on the Chinese internet, when downloading packages. China is a huge country with over 1 billion people, all of whom deserve to use coreboot.

We could provide special branches of lbmk with patches in it, that make certain upstreams be altered. For example, download coreboot from several mirrors that are not blocked in China.

I did toy with the idea of making a Gitee account (China's not-invented-here copy of GitHub), but registration required a Chinese phone number, so I couldn't make an account. I was going to set it up for Libreboot.

me cleaner is old

From what I can tell, me_cleaner is not well-tested or supported on many newer Intel platforms. it shouldn't affect us in Libreboot for now, because we're not even past Haswell yet, but see for instance:

Also: disablement

See: https://github.com/corna/me_cleaner/issues/278

This looks interesting. It seems on some arrandale machines it's actually possible to completely disable the ME (remove it from the nor flash), with "almost no ill effects" according to the OP on that issue page.

FAQ: cover USB fuzzing attacks

We write on the FAQ that SATA devices could potentially have DMA capability, but this has still not been proven, and it's probably not true in practise.

USB may not have DMA, but it's possible to perform what's called a fuzzing attack, whereby a USB device pretends to be something such as a keyboard, a mouse, a networking device, or any number of things in quick succession. A wily attacker could program a small USB dongle, and plug it into your running machine. If your operating system is insufficiently secured or otherwise poorly configured, and attacker could then remotely control your machine, and steal data.

You can just look up "USB fuzzing attack" online. There are several actually practical examples of it in the wild, and it's really easy to do. Easy meaning: cheap. It's a low-effort attack.

So we should cover it, and talk about ways to mitigate the risk (e.g. disable USB input devices and networking devices, in the user's operating system).

Auto-configure IFD region limits

We currently configure the ME/BIOS region sizes manually, which is fine, but the way it's configured is very complicated.

See: Vendor file guide

The way the Libreboot build system works, the Intel ME and other firmware is automatically downloaded at build time. At release time, blobs such as these are deleted, but an extra insert script is provided that can provide the same auto-download and auto-insert on release ROMs.

The default Intel ME firmware is about 5MB in most setups. We use me_cleaner which removes a lot of the malicious features in the ME, and truncates it to a much smaller size, e.g. 96KB on ivybridge systems (down from the default 5MB).

We currently configure this manually. We could do it automatically, though it should not be done automatically at build time, but at the time of adding a given machine to Libreboot. We could automate it like so:

  • Download the vendor update, and use the bruteforce extraction method to get at me.bin
  • Run the me_cleaner program, and get the size of the ME.
  • Pass it a factory dump, and run me_cleaner on that, to set all the extra bits like HAP, but don't use truncate.
  • Run the --unlock command in ifdtool, to unlock that ROM.
  • Auto-configure the IFD region sizes in that dump, based on the truncated size.
  • Extract the final IFD, and the GbE region if it exists.

Then it can configure the config file under config/vendor/.

After this, lbmk would still have static configs, not altered in any way at build time, but this would be an automated way to add new configs. Read more on the guide linked above, and read the vendor scripts themselves, to learn more; you can also read about them on the lbmk maintenance manual.

Signed commits

Start signing commits in Git. There's nothing more to say. Just do it.

Secure suspend method (LUKS setups)

See: https://github.com/shmalebx9/luks-suspend-portable

Caleb came up with a method to have suspend functionality, where the encryption keys are not stored in memory. It's worth looking into. We might be able to provide something automated in lbmk.

USB keyboard in secondary payload

We don't use secondary payloads defined here, but see: https://ticket.coreboot.org/issues/484

The issue page has info about the problem, and a workaround. Listed here for reference, in case this functionality is ever used in Libreboot.

zstd in btrfs on grub

Reported buggy by a user on IRC. TODO: test it

zstd is the compression used in btrfs, when compression is enabled. No other information was given, other than it is "buggy". Reported on Libreboot 20231101.

Optimise crossgcc space

Re-use crossgcc from other coreboot trees, in other coreboot trees. We currently build several versions of it, but we probably only need one, maybe two. Audit this, across various coreboot trees. Specific coreboot trees (older ones) could just be patched if re-using crossgcc from a newer tree.

T60 /proc/acpi/ibm/thermal

Reported by a user (unknown what LIbreboot version), this file is not available at all. It was later revealed that the user flashed a ROM image without microcode updates, triggering the AE18 errata. Thermal management is buggy without the updates, on that platform.

Link CPU errata PDFs

Libreboot makes reference to CPU errata in documentation, but without actually linking to the documents themselves. Link to the PDFs for all available CPUs, on supported Libreboot hardware. AMD has them too. These are errata documents that define which bugs exist in each CPU, and which ones have been fixed by microcode updates - they also generally provide information for OS developers, to know how certain bugs should be mitigated, whenever possible.

Macbook2,1 backlight controls

Was reported broken in linux 6.1, but works in 5.x

Since linux 6.1, the backlight subsystem was revamped. Try one of the cmdline options:

  • acpi_backlight=video
  • acpi_backlight=vendor
  • acpi_backlight=native

More testing is needed on this. So far, nothing seems broken on other machines tested and no user reports have come in. The way backlight controls work on coreboot can differ a bit from the vendor firmware on some boards.

Not really a major issue, but it does need to be addressed.

TODO: test other platforms too

Test other platforms.

Document CH341A variants

All CH341A variants are garbage for ISP-based flashing, because of weak drive strength and poor board layout, also the WP/HOLD pins are often held high via straight connections to VCC on these boards (rather than going through a pull-up resistor, as safe electrical design would dictate).

However, Libreboot currently only documents the black and gold one, that comes with 5V logic levels by default, and it has information for how to modify it so that the logic level are 3.3v - in addition, there are 1.8V logic level adapters, that just come with logic level converters on them.

The original green variant is 3.3v by default, and some newer variants have adjustable voltage for the logic levels.

For socket-based flashing, they're actually quite decent flashers. Quite convenient, because you don't have to mess with a breadboard or anything, because they already have ZIF sockets on them for DIP-8 ICs, on which you can also use adapters for SOIC-8, SOIC-16 and WSON-8.

E6400 VGA ROM (Nvidia)

See: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=990662#22

Although we couldn't reproduce it after testing, a redditor did report that following these steps caused nouveau to work.

Also: e6400nvidia_4mb works better on that setup, nouveau is actually stable in some cases. Check the E6400 page for libreboot, it lists issues with nouveau on those machines.

Test Crystalwell CPUs on T440p

Coreboot has support for these, but they have not been tested as far as I know, and no reports have been made for them by Libreboot users. These offer higher performance and the machine is already very nice.

Ditto W541.

How to extract VBT data

See:

Extract it from the vga rom, the vbt header is in there, and the number of bytes will be in the size field, so that one can know how many bytes to extract. One of these tools linked above prints it.

The VBT table is needed on machines where intel libgfxinit is used. It can just be extracted and included in a coreboot port.

Also see: intelvbttool in coreboot. How to use:

intelvbttool --inlegacy --outvbt data.vbt

Example patch (merged in coreboot) that used this: https://review.coreboot.org/c/coreboot/+/79625

Guix: use debootstrap

GCC-Gnat is unavailable in Guix, due to the distro's requirement for sources to be bootstrapped. GCC-Gnat is also required, for building GCC-Gnat. We build it in libreboot, to provide libgfxinit, because it's written in Ada.

Therefore, lbmk cannot be used reliably in Guix. It's possible to just add a binary for Gnat to the host, and then use that, but there is another idea:

Guix does have debootstrap, which could be used to bootstrap a Debian system, and install everything in that, including GCC-Gnat. Of course, we don't need to do anything for this in lbmk, but it would be nice to document.

In fact, it wouldn't necessarily need to be specific to Guix, because many systems have debootstrap; FreeBSD also has it, and it's even mentioned here on this page, though in the context of porting lbmk to FreeBSD.

Perhaps this could be done:

In the logic for ./build dependencies distroname, add an option for Guix, but on that one, make lbmk automatically set up debootstrap if it's being run for Guix (and it would detect whether the host actually is Guix System).

docs/build/clean.md

Add this section, telling the user (of lbmk specifically) how to clean various directories. This isn't handled universally, due to lbmk's design. When updating revisions, a lot of manual intervention is needed if an existing revision was already downloaded, especially if it was built.

For example, if you already compiled GRUB at a given revision, it will be present under elf/grub/. If you're updating the revision in lbmk, you must delete elf/grub first. Similarly, if you're testing out code changes, you have to know to do that and re-make GRUB.

This section relates to another section on this page, about automatically handling such updates in lbmk when it runs. Until that is done, this section is also here. We should document how this is handled, under the current scheme. A lot of development on lbmk requires the operator to know how lbmk works.

The preference however is to simplify and automate everything as much as possible. That is Libreboot's philosophy, that the user should never have to do more than is absolutely necessary when someonething could just as easily be done in code.

E6400 security

See other section on this page about write protection.

Setting PR registers for write protection is a valid way to write protect on Dell E6400, and it would not be affected by the flash-unlock utilitiy.

SMM methods

Tere are two SMM write protect methods:

The old lock enable bit, which causes an SMI to be triggered whenever BIOS write enable is changed back to 1. Then SMM needs to change the BISO write enable back to 0. Not the best option as it is vulnerable to timing attacks where a write gets through before SMM can change it back.

On newer chipsets (5 series and newer, basically everything newer than GM45), there's a new bit called SMM BIOS write protection, which prevents flash from being written to unless all cores are in SMM, which is better than the other method.

^ These notes were supplied by Nicholas Chin via IRC.

PCI-E REBAR

See: https://github.com/xCuri0/ReBarUEFI

This is required on some newer graphics cards, and can otherwise improve performance when supported. Support supports PCI-E REBAR - apparently some GPUs need it.

It allows the host CPU to access all of VRAM at once, without 32-bit legacy code. The above repository is a proof of concept that shows it working, though the work there is not directly applicable to us.

This feature is only supported commercially on much newer mainboards, and is unavailable on many older mainboards, but it can be added if the firmware is updated. This is one of the benefits of the freedom coreboot gives you. We could enable this on all the older desktop machines, where otherwise their factory firmware does not and will not enable it (and the above link is for UEFI systems only).

Shrink FSP size (Intel)

See: https://blog.osfw.foundation/breaking-the-boundary-a-way-to-create-your-own-fsp-binary/

Remove modules from FSP that coreboot doesn't use. This will especially be useful on setups where linuxboot is to be enabled. Initially done on Alderlake but possible on other platforms.

Thanks go to Nicholas Chin for linking this.

Chromebooks

Especially useful here, if using the default setup. In the default setup, there are essentially three copies of the firmware in flash: a recovery image, an "A" image and a "B" image, according to Nicholas Chin.

Compare factory/download neutered ME

Use tools and hexdump diffs to compare neutered Intel ME images, comparing ones neutered from factory.bin dump, and ones from the auto-downloader in lbmk.

Probably no difference, or no differences that matter, but we never tested this (no problems so far, since mid/late 2022 when we started doing this in osboot, and heads did it for years before we did, and they never had any problems).

HP 820 G2 TPM

TODO: check that it can be upgraded to TPM 2.0 (default is 1.2). It's a SLB 9660 TPM

https://community.infineon.com/t5/OPTIGA-TPM/SLB-9660-TT1-2-upgrade-TPM-1-2-to-TPM-2-0/td-p/382419

https://support.hp.com/gb-en/document/c05792935

Apparently, this can be upgraded to TPM 2.0. Riku linked this on IRC:

https://forum.ts.fujitsu.com/forum/viewtopic.php?t=49340#p156746

And also this, straight from the horse's mouth:

https://www.infineon.com/cms/en/product/security-smart-card-solutions/optiga-embedded-security-solutions/optiga-tpm/slb-9660xt1.2/

GRUB nvme support

GRUB doesn't support nvme on bare metal.

SeaBIOS does.

Libreboot is getting a lot of new ports, and some of them can use nvme drives. We need nvme support in GRUB.

TODO: adapt SeaBIOS nvme code for GRUB. Also submit upstream.

GRUB can do nvme but only if it's supported by the (UEFI) vendor firmware.

4th SSD on T440p

probably possible on w541 too

https://www.youtube.com/watch?v=jURgHzLrpBs

https://www.youtube.com/watch?v=gAZw0fTKdYg

this was tested on windows in the lenovo firmware, but it will be possible to use this in coreboot with linux/bsd

todo: test it. need to actually solder it and test it.

Disable ME device in devicetree

We neutered, but coreboot still enables MEI1 on many boards.

Look in devicetrees within coreboot, and see:

			device ref mei1 on end
			device ref mei2 off end
			device ref me_ide_r off end
			device ref me_kt off end

Example taken from lenovo/x230. We could just turn all of these off. It doesn't affect anything in practise, whether this is on or not, because we neuter anyway, so the ME interface is broken by default. Leaving it on in devicetree will result in a benign error message on linux dmesg.

Switchable Graphics (Optimus)

Some of the Thinkpads we support have dual graphics, using Nvidia Optimus. It'd be nice to have. This coreboot patch enables it on Thinkpads:

https://review.coreboot.org/c/coreboot/+/28380

There are other patches on Gerit, related to Optimus too:

https://review.coreboot.org/q/Optimus

This should be looked into.

Overclocking (CPU and RAM)

Coreboot could be modified to support overclocking. Here is an example patch on gerrit (not merged in main):

https://review.coreboot.org/c/coreboot/+/42547

Coreboot can also be used to load custom SPDs for the RAM if you want to get into re-binning (as it's called. Thank you Riku for telling me that this is what it's actually called). Useful if you want to quickly test.

Libreboot is starting to support machines where some users may want to start overclocking their CPU/GPU/RAM.

As for GPU overclocking: usually there are programs you can run for this in your operating system, but sometimes on laptops with dgpu, the VGA ROM might limit it in some way.

This article is from someone who modified the VGA ROM on their AMD Radeon graphics chip, in a laptop: https://habr.com/en/articles/232265/?_x_tr_hist=true - it is an example of the sort of thing lbmk could automate, when auto-downloading those VGA ROMs, on certain machines. NOTE: Page is in Russian, use a translator.

The type of people (enthusiasts) that like Libreboot would be into this sort of thing. It may be interesting to study, especially on haswell machines.

Haswell

https://www.youtube.com/watch?v=vCZiTSZutR4

interesting video on alienware laptop (haswell), and there are other examples. those machines, whether they get ported to coreboot or not, could be used to study what affect those options have: take dumps of hardware logs using various utils, before and after, to study what change those settings actually makes. this could reverse engineered to then add those options in coreboot.

haswell overclocking would be very useful to have, on libreboot machines, because you can get some still-very-nice CPUs for these machines.

X60/T60 alloc magic is broken at 0x7b1aedf0: 0

See: https://codeberg.org/libreboot/lbmk/issues/179

Reported on T60. Another user reported on X60. Happened when booting from battery. On the X60 reported, booting with charger connected worked, but this GRUB error is produced when booting on battery.

Happens in 20240126 and 20240225. Does not happen in 20230625.

A bisect is indicated; possibly in GRUB, but if nothing is found there, then the bug will be in coreboot. Could be either of them.

Could be a bug in GRUB's memory management. And/or regression in coreboot raminit. More testing is needed.

NOTE: May 2024 release is using coreboot from 20230625 on these laptops (i945) to work around the issue, but it'll possibly be fixed before that release, otherwise afterward.

Intel/AMD errata PDF

List PDF links for Intel/AMD CPUs, provided by Intel/AMD, showing what is unpatched as of yet, in microcode updates.

https://www.intel.com/content/www/us/en/products/docs/processors/core/core-technical-resources.html

https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/blob/main/releasenote.md#microcode-20230808

Links.

interesting video

https://www.youtube.com/watch?v=5qauRh7eTNY

Automate testing

Even though there's lots of error handling, it's better to be paranoid than brick users' machines.

Unit tests

  • Build time or separate?
  • me_cleaner -c: checks that ime was inserted and has valid signatures

CI

Preferably self-hosted. Run tests for every commit. There could be tests of different size, and even a periodic nightly release could be done.

Integrating this with an automated test stand would also be doable. At the very least, it would assure that the ROM images boot successfully.

Board status

As the number of ports grows, it becomes harder to keep track of what works. Let's build a machine-readable repo documenting every release (or commit) on every board. What features/payloads work, maybe include errata text field. A HTML report could also be generated and published online.

On top of this, an easy to use installer could be developed. It would know to not install an unbootable (broken) ROM, and would inform users about any known problems and have meaningful options.

haswell board bifircation

https://www.mouser.com/pdfDocs/4th-gen-core-family-desktop-vol-1-datasheet.pdf

page 89

also

https://winraid.level1techs.com/t/bios-mod-to-enable-pcie-bifurcation/31547

ec hacking on lenovo x230

https://zmatt.net/unlocking-my-lenovo-laptop-part-2/

DELL 7th gen

3050 micro is being worked on.

3050 sff and mt are TODO

5050 models also.

Dell 3020

another haswell. different to 9020, but could be added.