Skip to content

Commit 19a1527

Browse files
committed
move retrofitting LinuxBoot into UEFI PI to its own chapter
And specify the language for the code block. Signed-off-by: Daniel Maslowski <info@orangecms.org>
1 parent 399dce7 commit 19a1527

4 files changed

Lines changed: 235 additions & 234 deletions

File tree

.github/workflows/lazy-lint.bash

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ shame_list=(
55
[./src/case_studies/TiogaPass.md]=1
66
[./src/components.md]=1
77
[./src/coreboot.u-root.systemboot/index.md]=1
8-
[./src/implementation.md]=1
98
[./src/intro.md]=1
109
[./src/naming.md]=1
1110
[./src/SUMMARY.md]=1

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
- [The magical cpu command](utilities/cpu.md)
1515
- [Device Under Test](utilities/dut.md)
1616
- [Implementing LinuxBoot](implementation.md)
17+
- [Retrofit LinuxBoot into UEFI Platform Initialization](uefi-pi-retrofit.md)
1718
- [LinuxBoot using coreboot, u-root and systemboot](coreboot.u-root.systemboot/index.md)
1819
- [Glossary](glossary.md)
1920
- [History](history.md)

src/implementation.md

Lines changed: 0 additions & 233 deletions
Original file line numberDiff line numberDiff line change
@@ -2,236 +2,3 @@
22

33
The aim of LinuxBoot is to reduce complexity and obscure firmware by moving
44
that functionality into kernel and user-space.
5-
6-
This chapter describes the procedures from a [LinuxBoot
7-
workshop](https://docs.google.com/presentation/d/1s9ka4v7leKeJa3116AQoNb9cv3OqmnW6pgn0ov9WiHo/edit?ts=5e2b227b#slide=id.g7ceec54197_4_163)
8-
where an Atomic Pi board with UEFI firmware was converted to run LinuxBoot. The
9-
build materials associated with this are found at
10-
[digitalloggers/atomicpi](https://github.com/linuxboot/mainboards/tree/master/digitalloggers/atomicpi).
11-
12-
Read the below and consult the Makefile for the details of how it was
13-
implemented.
14-
15-
## A quick refresher on UEFI
16-
17-
UEFI has three sections:
18-
19-
+ SEC ("Boot")
20-
+ PEI ("Very early chip setup and DRAM programming")
21-
+ DXE ("DRAM code")
22-
23-
DXE process is very complex; some systems have 750 DXEs.
24-
25-
LinuxBoot replaces most of the UEFI software with Linux. LinuxBoot has an
26-
initramfs provided by [u-root](./u-root.md).
27-
28-
The above are stored inside a flash filesystem (FFS) inside a region of flash
29-
on your motherboard (the BIOS region). Another important region of flash is the
30-
ME region.
31-
32-
The Management Engine (ME) is an x86 CPU embedded in the Intel Platform
33-
Controller Hub (PCH). It runs the Minix operating system which boots first and
34-
enables hardware such as clocks and GPIOs. ME checks the contents of flash
35-
memory and is used to implement "BootGuard". If you reflash and the ME is in
36-
"BootGuard" mode, your machine will be unusable. You need to run a tool called
37-
`me_cleaner` on the image to disable BootGuard.
38-
39-
## How do you get LinuxBoot on your hardware
40-
41-
Start with a board running standard UEFI and proceed from "zero changes to
42-
FLASH" to "max changes" in 4 steps:
43-
44-
+ Boot from USB stick via UEFI shell command _or_ netboot (zero changes)
45-
+ Find a way to read flash and write flash
46-
+ Understand the flash layout
47-
+ Prepare linux kernel and initrd/initramfs payload.
48-
+ Replace UEFI Shell code section with Linux kernel and associated initrd
49-
(change part of one thing)
50-
+ Remove as many DXEs as possible (change by removal). This change:
51-
+ Speeds boot
52-
+ Reduces panic possibilities
53-
+ Removes exploits
54-
+ In production, it has solved problems
55-
+ Clear ME region for initrd storage
56-
+ Replace some DXEs with open source components (change by replacement)
57-
58-
One of the challenges in the above is in finding (or reclaiming) enough space
59-
in flash to shoehorn your kernel and initrd into.
60-
61-
## Tools of the trade
62-
63-
There are two tools you use when you modify the UEFI flash image: `utk` and
64-
`me_cleaner`.
65-
66-
The ME Cleaner tool:
67-
68-
`/usr/bin/python2 me_cleaner.py -s` _imagefile.bin_
69-
70-
`me_cleaner` sets the high assurance platform (HAP) bit. HAP provides a way to
71-
disable a feature on Intel chips that does not allow us to modify the UEFI
72-
image and install LinuxBoot. Setting the bit with `me_cleaner` disables the
73-
"feature". Note that this does not always work; check with the LinuxBoot
74-
community.
75-
76-
When you run `me_cleaner`:
77-
78-
```
79-
~/projects/linuxboot/me_cleaner/me_cleaner.py -s /tmp/rom.bin
80-
```
81-
82-
you should see output similar to the following:
83-
84-
| |
85-
|:---|
86-
|`Full image detected`|
87-
|`Found FPT header at 0x1010`|
88-
|`Found 20 partition(s)`|
89-
|`Found FTPR header: FTPR partition spans from 0x6f000 to 0xe700`|
90-
|`ME/TXE firmware version 2.0.5.3112 (generation 2)`|
91-
|`Public key match: Intel TXE, firmware versions 2.x.x.x`|
92-
|`The AltMeDisable bit is SET`|
93-
|`Setting the AltMeDisable bit in PCHSTRP10 to disable Intel ME…`|
94-
|`Checking the FTPR RSA signature... VALID`|
95-
|`Done! Good luck!`|
96-
97-
By applying `me_cleaner`, it has been observed that almost 4M of flash ram can
98-
be reclaimed for use. That 4M is enough to store a reasonably full featured
99-
compressed initrd image.
100-
101-
The `utk` tool can:
102-
103-
+ Remove DXEs
104-
+ Insert new DXEs
105-
+ Replace the binary code of a DXE with a kernel
106-
+ Reallocate space from the ME region to the BIOS region ("tighten")
107-
108-
## LinuxBoot Implementation steps
109-
110-
### Step 1: boot Linux via netboot / UEFI shell
111-
112-
+ netboot: standard BIOS-based PXE boot
113-
+ Netboot is probably the most common working boot method on UEFI
114-
+ We have never seen a system that did not have a net boot
115-
+ UEFI Shell (mentioned only for completeness)
116-
+ Install Linux on FAT-32 media with a name of your choice (e.g. "kernel")
117-
+ FAT-32, also known as MS-DOS file system
118-
+ Boot kernel at UEFI Shell prompt
119-
+ We've run into a few systems that don't have a UEFI shell
120-
121-
#### Working with a system that only has a net interface
122-
123-
If the system only has a net interface, you use Dynamic Host Configuration
124-
Protocol (DHCP), using broadcast DISCOVER, and Trivial File Transfer Protocol
125-
(TFTP) to get the boot information you need.
126-
127-
Configuration information is provided by REPLY to a DHCP request. The REPLY
128-
returns an IP, server, and a configuration file name that provides:
129-
130-
+ Identity
131-
+ What to boot
132-
+ Where to get it
133-
134-
Data is provided by TFTP. HTTP downloading takes a fraction of a second even
135-
for 16M kernels. With TFTP it's very slow and TFTP won't work with initramfs
136-
much large than 32MiB. Most LinuxBoot shops use or are transitioning to HTTP.
137-
138-
Note: Boot images require a kernel(bzImage) + an initramfs + a command line.
139-
They can be loaded as three pieces or compiled and loaded as one piece, as
140-
described in this section.
141-
142-
### Step 2: read & write the flash
143-
144-
There are two main ways to read and write the flash - hardware and software.
145-
146-
Hardware: It is worth buying a Pomona 5250 SOIC Clip adapter to read directly
147-
by hardware to have something to roll back to if anything goes wrong. Avoid
148-
cheap SOIC clip adapters that don't allow you to use standard jumper leads. For
149-
a good example of using a Raspberry Pi 3/4 to read/write, see [Sakaki's EFI
150-
Install Guide/Disabling the Intel Management
151-
Engine](https://wiki.gentoo.org/wiki/Sakaki%27s_EFI_Install_Guide/Disabling_the_Intel_Management_Engine#imt_check)
152-
153-
Software: With a working boot image, use flashrom to read an image of your
154-
flash. To write you may need to disable flash protections (look for "ME
155-
Manufacturing mode" jumpers on your motherboard). Figure on generally using
156-
software methods for reading & writing flash, but with hardware to drop back
157-
to.
158-
159-
### Step 3: Familiarise yourself with the flash layout and identify free space
160-
161-
Open your flash image with UEFITool, and locate the filesystem containing the
162-
DXE's (it will have the Shell or `Shell_Full` in it ). Check how much volume free
163-
space is in that filesystem - this will be an initial limit when you come to
164-
place your kernel and initramfs in it in step 5.
165-
166-
### Step 4: Prepare linux/u-root payload
167-
168-
Start small and work your way up.
169-
170-
+ Use the tiny.config to configure your first kernel, and embed a small
171-
initramfs in-kernel (the u-root cpu payload is an excellent starting point).
172-
+ One can have a full kernel/initramfs in around 2M of flash.
173-
+ A more full featured kernel might consume 2M and a u-root bb distribution 4M,
174-
which may well exceed the volume free space.
175-
+ When there isn't enough space in this filesystem, one can either start
176-
removing unused DXE's (step 6), or use space formerly used by the ME Region
177-
(step 7).
178-
179-
### Step 5: replace Shell binary section
180-
181-
+ UEFI Shell is a DXE
182-
+ DXEs are Portable Executable 32-bit binaries (PE32)
183-
+ They have multiple sections, one of them being binary code
184-
+ You need a flash image (in this case called _firmware.bin_). You can get
185-
it via vendor website, flashrom, or other mechanism.
186-
+ The following `utk` command replaces the Shell code section with a Linux
187-
kernel:
188-
+ `utk firmware.bin replace_pe32 Shell bzImage save` _new.bin_
189-
+ Note: It's always a PE32, even for 64-bit kernels. _new.bin_ is a filename
190-
of your choosing.
191-
+ After running `utk`, you can reflash
192-
193-
### Step 6a: remove as many DXEs as possible
194-
195-
+ You can do an initial mass removal based on your current knowledge
196-
+ `utk` automates removing DXEs: this is the DXE cleaner
197-
+ `utk` removes a DXE, reflashes, checks if it boots, repeat
198-
This part should be easy: DXE can have a dependency section. In practice,
199-
it's hard: because dependency sections are full of errors and omissions. A lot
200-
of UEFI code does not check for failed DXE loads.
201-
202-
### Step 6b: place your initramfs in me_cleaned region
203-
204-
+ Run `me_cleaner` and then utk tighten on the source image, then inspect the
205-
image using UEFITool. If successful, there will now be padding at the
206-
beginning of the BIOS region of a substantial size.
207-
+ This padding space can be used, without the filesystem's knowledge, to stash
208-
an initramfs. The kernel is informed of the location this initramfs as an
209-
initrd kernel parameter.
210-
+ Use the base address of this padding region to calculate the offset in
211-
the flash image where the initrd is stashed using dd.
212-
+ Use the address (not base address) as the initramfs location in memory to
213-
pass as a kernel parameter.
214-
215-
### Step 7: replace closed-source with open source
216-
217-
+ If you can build a DXE from source, you can use `utk` to remove the
218-
proprietary one and replace it with one built from source. You can get DXE
219-
source from the tianocore/EDK2 source repo at github.com. The GitHub repo has a
220-
**_limited_** number of DXEs in source form; i.e., you can't build a full
221-
working image using it.
222-
+ There are scripts that let you compile individual DXEs, including the UEFI
223-
Shell and Boot Device Selection (BDS). These two DXEs have been compiled and
224-
are used in the Atomic Pi. Source-based BDS was needed to ensure the UEFI
225-
Shell was called.
226-
+ You only need the UEFI Shell built long enough to replace it with Linux.
227-
228-
### Final step: reflash the image
229-
230-
+ "Native" reflash: Boot the system whatever way is easiest: netboot, usb,
231-
local disk, and run `flashrom -p internal -w _filename.bin_` where
232-
_filename.bin_ is a filename of your choosing.
233-
+ Run `flashrom` with an external device such as an sf100. There may be a
234-
header on the board, or you might have to use a clip.
235-
`flashrom -p dediprog:voltage=1.8 -w _filename.bin_`
236-
237-
The voltage option is required for the Atomic Pi.

0 commit comments

Comments
 (0)