-
-
Notifications
You must be signed in to change notification settings - Fork 186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add initial support for the ThinkPad T440p #1282
Conversation
blobs/t440p/export-blobs
Outdated
function usage() { | ||
echo -n \ | ||
"Usage: $(basename "$0") path_to_original_rom | ||
Extract Intel firmware from the original ROM. | ||
" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided not to copy or iterate on the existing extract.sh
script. Instead, I wanted to make something tailored for the T440p, focusing on improved readability.
Down the road, I think we should consolidate all the blob extraction tooling so that we don't need to replicate per board.
# Inherit the rest from the base T440p config. | ||
include $(pwd)/boards/t440p-maximized/t440p-maximized.config | ||
|
||
CONFIG_HOTPKEY=y | ||
|
||
export CONFIG_BOARD_NAME="ThinkPad T440p-hotp-maximized" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took a novel approach here. I didn't want to duplicate any config. I realized since this is just a Makefile, we can use the include
directive.
# TODO: Make a ThinkPad-common Linux config file. | ||
CONFIG_LINUX_CONFIG=config/linux-librem_common.config |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used the linux-librem_common.config
Linux config as it was the only one based on Linux 5.10.x. Unfortunately, the configs for the X230 didn't work.
Are you OK with merging this as-is? I don't like that it's pointing to a Librem config. But I also don't want to duplicate that file just for the T440p.
In the future, I think that we could benefit from a common Linux config with board-specific overrides.
CONFIG_CRYPTSETUP2=y | ||
CONFIG_FLASHROM=y | ||
CONFIG_FLASHTOOLS=y | ||
CONFIG_GPG2=y | ||
CONFIG_KEXEC=y | ||
CONFIG_UTIL_LINUX=y | ||
CONFIG_LVM2=y | ||
CONFIG_MBEDTLS=y | ||
CONFIG_PCIUTILS=y | ||
CONFIG_POPT=y | ||
CONFIG_QRENCODE=y | ||
CONFIG_TPMTOTP=y |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These magic values were copied from the X230 config.
# CONFIG_USE_BLOBS is not set | ||
CONFIG_VENDOR_LENOVO=y | ||
CONFIG_NO_POST=y | ||
CONFIG_CBFS_SIZE=0x800000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This value for the CBFS size is arbitrary. Originally, I had totaled the size of all binary blobs, subtracted that from the T440p's ROM size (12 MiB), and used the remaining space as the CBFS size (~11.68 MiB). However, this caused very long RAM initialization times (courtesy of cbmem -t
). And, an anecdote in https://groups.google.com/a/chromium.org/g/chromium-os-reviews/c/lUqRrGUoEBY/m/ka7L1f2BS8gJ suggested that this value needs to be a power of 2.
So, I picked a size I expected our Linux payload to fit into that was a power of 2 that I also expected would leave enough space in the ROM for the IFD, ME, GbE, and Coreboot.
Now, it takes less than a second for RAM initialization after flashing/first boot (anecdotally, it seems the MRC needs to be "trained?").
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have the impression that your initial CBFS_SIZE value might have been good, but not matching ifd defined region).
Ifd needs to be modified to take output of neutered ME size while ME region needs to be reduced under ifd, and the freed space added to BIOS region there. That BIOS size would become the size of cbfs region under coreboot config from memory, but will have to find traces again which I was unsuccessful finding last time.
Will try to find that information back since it needs to be part of the porting guide as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have the impression that your initial CBFS_SIZE value might have been good, but not matching ifd defined region).
Ah, okay, this makes sense. I ran me_cleaner on my original ROM again and then used ifdtool
to dump the IFD regions:
$ python me_cleaner.py -S -r -t -d -O out.bin -D ifd_shrinked.bin -M me_shrinked.bin ~/projects/t440p/t440p_original.bin
. . .
$ ./ifdtool -f layout.txt ifd_shrinked.bin && cat layout.txt
00000000:00000fff fd
00021000:00bfffff bios
00003000:00020fff me
00001000:00002fff gbe
Putting this into a notepad (using Soulver), I determined the size of each region and that there is 1 byte of padding between each region:
So maybe 0xBDEFFF
is the maximum CBFS size? I will recompile, flash, and see. It would be cool if we could automate this math.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update: 0xBDEFFF
did not work. RAM initialization times are back up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rbreslow I finally joined coreboot channel and posted my question directly to them here: https://matrix.to/#/!BZxDFuoBnMKnzVZwEp:libera.chat/$N_Nh4qJeU9gquoE9tzjeERYzsxgYB6j79uB6uvnoPdM?via=libera.chat&via=matrix.org&via=foss.wtf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rbreslow I finally joined coreboot channel and posted my question directly to them here: https://matrix.to/#/!BZxDFuoBnMKnzVZwEp:libera.chat/$N_Nh4qJeU9gquoE9tzjeERYzsxgYB6j79uB6uvnoPdM?via=libera.chat&via=matrix.org&via=foss.wtf
icon on coreboot channel answered. Excerpt:
icon:
it's notend - start
butend - start + 1
but that's not why it's slowing down. I assume with the bigger size, not everything in CBFS can be cached
there's CAR (cache as RAM) at 0xff7c0000..0xff7effff. this is used to store data before the DRAM is up
the BIOS region is mapped directly below 4G (0x100000000). so making CBFS too big, it could even conflict with CAR
I don't think this can be changed without also changing the MRC blob
so the best option is really to set CBFS_SIZE to 8MiB
one could still make the rest of the BIOS region available with a custom FMAP. only not as part of CBFS
I replied:
Interesting. Has no impact on ivy/sandy which extends cbfs region to reuse all liberated space from ME (11.5mb for heads maximized boards). But yet again, native ram init there.
Misalignments increased boot time in the past, but those were linked to tpm measurements problems (increasing boot time by 50 seconds, but also on older versions of coreboot).
Then icon replied:
yes, CAR is in 0xfefe0000..0xfefeffff for SNB
that's DCACHE_RAM_BASE/_SIZE in Kconfig btw.
oh, actually it's bigger
nic3-14159 added:
Side note, IIRC the coreboot build system rounds CBFS_SIZE down to 64KiB boundaries
@rbreslow Can you adjust the calculations and test with new CBFS? Might be a limitation of the MRC blob on which we might need to accept caching time (and document properly under board config as current limitation)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tlaurion Here are my cbmem
logs from the CBFS_SIZE
set 0xBDEFFF
: https://gist.github.com/rbreslow/50b45e538437dd10f9e2bf51abd260de. What size would you like me to try now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So maybe 0xBDEFFF is the maximum CBFS size? I will recompile, flash, and see. It would be cool if we could automate this math.
Basically, the right calculation is taking output of ifdtool -f layout.txt path/to/ifd_output_from_me_cleaner_on_fullrom_backup.rom and parsing the BIOS region, substracting end address to begin address.
@rbreslow Seems like xx30 and xx20 might have been off all along. Redoing.
CONFIG_GBE_BIN_PATH="@BLOB_DIR@/t440p/gbe.bin" | ||
CONFIG_HAVE_IFD_BIN=y | ||
CONFIG_BOARD_LENOVO_THINKPAD_T440P=y | ||
CONFIG_LINUX_COMMAND_LINE="intel_iommu=igfx_off" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without this, neither Qubes OS nor the Qubes OS installer would start. Presumably, because we're "kexecing" from an already running kernel, we need this set at the Coreboot level? Testing revealed that including intel_iommu=igfx_off
in the CONFIG_BOOT_KERNEL_ADD
board config option did nothing. And, the Qubes OS default boot option already contains intel_iommu=igfx_off
.
See:
- https://www.qubes-os.org/doc/installation-troubleshooting/#not-asking-for-vnc-because-we-dont-have-a-network--x-startup-failed-aborting-installation--pane-is-dead-error-during-installation
- https://github.com/Qubes-Community/Contents/blob/master/docs/troubleshooting/intel-igfx-troubleshooting.md
- https://www.kernel.org/doc/html/v5.10/x86/intel-iommu.html?highlight=igfx_off#graphics-problems
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly. Otherwise the iommu is configured incorrectly since first kernel boot would try to isolate Intel iommu and the kexec'ed kernel would not be able set differently.
Coreboot defined kernel option defines Heads behavior.
@rbreslow First comment: awesome contribution!!!! In the spirit of other maximimized boards, I would like to collaborate into making this board download ME and dump it under haswell blob dir like the other boards are doing it from Lenovo latest bios available prior of merge. ifd can probably be borrowed from libreboot, while I also suppose nvramutil from libreboot is able to generate gbe.bin and also drop it under haswell blob as a default with DE:AD:C0:FF:EE, if not extracted by user from backups as part of a export/extract script. (Not sure how me and gbe are injected in ROM with first look from coreboot config but might have overlooked. The idea there is to deliver all this working when adding a board if blobs are needed, otherwise turning this in a maintenance nightmare. As for yournlinux config being based in Librem, this might work as of now, but the config is tailored for those boards with modules for nvme for example. If you can take a look at x230 blob download script, this would need to be duplicated to download and extract ME from Lenovo. If we have that working with gbe.bin mrc.bin me.bin in place, we would be able to add the board into CircleCI. If you flash that ROM and it works for you, then merging it would be tested working and mergeable. Makes sense? Then next step would be to find magic number for CBFS, since 8mb seems really small to fit librem kernel and all the other stuff, which would probably fail really soon to build and without having it under CI we would just not notice. After that, main benefit for that board would be to have TXT variants for each boards, so that ACM blobs are also included and enabling DRTM which a lot of people are waiting for, which would make the t440p as a first working DRTM enabled platform. I'm interested into making those go forward sonic any help is needed, I will jump in. Awesome work! Note the ifd.bin cannot be generated as of today as opposed to gbe.bin, so normally those files come from "dead" boards. I can swear from memory that I have seen a t440p ifd over libreboot tree. And I'm pretty sure I documented how to modify that ifd to have its regions match moved me region to add frees space into BIOS region into PR that lead into first maximized boards being merged upstream. Will come back to you with that in next coming days as well. We want to get away of legacy board requiring users to extract blobs from backups, while an extract script is always provided so users can choose for themselves. Also note that t440p instructions should point to latest Lenovo bios update available to update EC prior of initial external flashing as well, currently missing. Awesome pointer for disassembly and flashing. Have not checked which flash chips are in the t440p, where the ones present under xx20/xx30 are really resilient to higher voltage. Better warned then sorry, and LC ch341 variant are safer, I agree. But using personally a black ch341 and having flashed hundred of x230 laptops myself, if not external power source are connected, I only have 3 bricks resulting of flashing..... Because I forgot to disconnect battery/AC adapter, not because of a 5v flasher. Again, better safe then sorry. Yes. Mrc trained memory is saved back to SPI. Thanks again for this contribution! |
For ME downloader+cleaner:
So basically
From blobs/xx30/README, applying the following on a fully stitched coreboot rom: Would produce proper ifd.bin to be dropped under blobs/haswell for IFD matching latest available ME from present recipe, and dodging blob redistribution limitations. |
I'm onboard 👍.
Yes, Libreboot has an $ strings my_laptop_ifd.bin
I!B`
E E
E E
E E
% %
% %
% %
GLRN11WW
9.1.10.1005
12MB
SIGNED
$ strings libreboot_ifd.bin
I!B`
E E
E E
E E
% %
% %
% %
GLRN12WW
9.1.20.1035
12MB
SIGNED Any ideas? Also, is there anything sensitive about sharing an IFD? Is there something specific to my laptop that could identify me? I haven't dug too deep.
Good catch. And that's convinced me to apply more scrutiny to the kernel config. I'll split things out into a separate
Yes, 👍.
Agreed. I left a comment with more thoughts here: #1282 (comment).
👍. This makes sense.
Ah, I should've included that in my testing instructions. I burned the latest BIOS update onto a CD and updated my laptop.
You're welcome! And thank you for your great feedback. Seriously, I appreciate it ❤️ . Here's a list of things I'm going to do:
|
I expected that the ME blob downloaded from Lenovo's website would match the ME I extracted from my laptop. After all, I performed a BIOS update before extraction, and they have the same version number. I ran me_cleaner on both files and compared the results. The SHAs were different, so I wanted to know why. $ sha256sum *.bin
b7cf4c0cf514bbf279d9fddb12c34fca5c1c23e94b000c26275369b924ab9c25 me_shrinked_lenovo.bin
18ee99989a16c82c66df639b0d3993a426a0e6400966e82824fc507ae2ae50a1 me_shrinked_my_laptop.bin The me_cleaner output was slightly different: $ diff -u <(python me_cleaner.py -r -t -O me_shrinked_my_laptop.bin ../ifdtool/flashregion_2_intel_me.bin) <(python me_cleaner.py -r -t -O me_shrinked_lenovo.bin ~/Downloads/ME9.1_5M_Production.bin) --- /dev/fd/12 2023-01-17 17:42:05.000000000 -0500
+++ /dev/fd/13 2023-01-17 17:42:05.000000000 -0500
@@ -15,12 +15,12 @@
BIIS (NVRAM partition, no data, 0x00036000 total bytes): nothing to remove
NVCL (NVRAM partition, no data, 0x000069c9 total bytes): nothing to remove
NVCM (NVRAM partition, no data, 0x0000439b total bytes): nothing to remove
- NVCP (NVRAM partition, no data, 0x0000a3c0 total bytes): nothing to remove
+ NVCP (NVRAM partition, no data, 0x0000a445 total bytes): nothing to remove
NVHM (NVRAM partition, no data, 0x00000058 total bytes): nothing to remove
NVJC (NVRAM partition, no data, 0x00003da0 total bytes): nothing to remove
- NVKR (NVRAM partition, no data, 0x00005fb3 total bytes): nothing to remove
+ NVKR (NVRAM partition, no data, 0x00005fb4 total bytes): nothing to remove
NVNF (NVRAM partition, no data, 0x0000175f total bytes): nothing to remove
- NVOS (NVRAM partition, no data, 0x0003a34b total bytes): nothing to remove
+ NVOS (NVRAM partition, no data, 0x0003a34d total bytes): nothing to remove
NVSH (NVRAM partition, no data, 0x000022c0 total bytes): nothing to remove
NVSM (NVRAM partition, no data, 0x00001de8 total bytes): nothing to remove
NVTD (NVRAM partition, no data, 0x00001feb total bytes): nothing to remove
@@ -35,7 +35,7 @@
MDMV (0x0048a000 - 0x0004ca000, 0x00040000 total bytes): removed
Removing partition entries in FPT...
Removing EFFS presence flag...
-Correcting checksum (0xda)...
+Correcting checksum (0xd9)...
Reading FTPR modules list...
UPDATE (LZMA , 0x1c6487 - 0x1c66b1 ): removed
ROMP (Huffman, fragmented data, ~1 KiB ): NOT removed, essential Using $ diff <(xxd me_shrinked_my_laptop.bin) <(xxd me_shrinked_lenovo.bin) 2,3c2,3
< 00000010: 2446 5054 0100 0000 2010 30da 0700 6400 $FPT.... .0...d.
< 00000020: 2000 0000 00fc ffff 0900 0100 0a00 e803 ...............
---
> 00000010: 2446 5054 0100 0000 2010 30d9 0700 6400 $FPT.... .0...d.
> 00000020: 2000 0000 00fc ffff 0000 0000 0000 0000 ............... It only looks like 10 bytes are different. I wasn't sure what to make of this, but then stumbled upon and used ME Analyzer to compare the two dumps:
ME Analyzer said the Lenovo ME was "stock," while the ME from my laptop was "extracted." And the Lenovo ME was missing a Flash Image Tool (FIT) version number. Looking at the source code, I found that ME Analyzer determines whether the firmware is "stock" or "extracted," as well as the FIT version, when analyzing I verified that the majority of the different bytes corresponded to the FIT version ( >>> int.from_bytes(b'\x09\x00', byteorder='little')
9
>>> int.from_bytes(b'\x01\x00', byteorder='little')
1
>>> int.from_bytes(b'\x0A\x00', byteorder='little')
10
>>> int.from_bytes(b'\xE8\x03', byteorder='little')
1000 And, looking at the data structure for So, now, we have a little more assurance that Lenovo hasn't injected any new backdoors since the last time I flashed my BIOS 😅. The only difference is that the ME firmware I extracted contains a "Flash Image Tool" version and a different checksum. |
Thanks for the ME analysis in previous post, makes sense. |
On IFD, it is known that some information, depending of makers (Lenovo) might fuse serial numbers and such, including Microsoft COA (never confirmed) inside of IFD. IFD could be generated, but nobody really cared going that route. The idea here is more "safety in numbers" and the more people sharing the same IFD, the more anonymous one can gets outside of using an IFD coming from libreboot/heads/whatever. Then, if using tails/qubesos or anything outside of corporate OSes known to leak through accepted but unread service agreement (Microsoft or others) are not supposed to be affected. I am not aware of a research that digged into that, while if there was enough money, we could definitely go back to specs or feed an IA with enough ifd to generate an abstracted one. But as opposed to ME binary blob, once again, just like the GBE blob, ifd is considered a configuration blob, which interest for us is to define regions, used by flashrom to determine what regions to flash. On maximized builds, those are neglected since we reflash the whole combined opaque spi, but it is still possible to call flashrom with --ifd and specify BIOS region to not touche GBE nor ifd, or ifd or GBE alone... Which depends of IFD define regions. Once again, the ifd needs to be unlocked to be changed in the future, and its ME region unlocked to have ME flashable in the future as well. This is mainly why we care to provide an ifd, otherwise coreboot bakes one, but flashing whole spi opaque image will result in a brick. If no valid ifd is added into coreboot config, then coreboot bakes an invalid one, and flashrom needs to be instructed to flash --ifd bios region only, otherwise resulting in a brick. |
I based this script on the Coreboot docs: https://doc.coreboot.org/northbridge/intel/haswell/mrc.bin.html. While adding an integrity check to ensure we're obtaining the correct blob. Also, it's worth surfacing that the SHA-1 for the resulting binary is the same SHA that Libreboot uses in their integrity check: https://notabug.org/libreboot/lbmk/src/master/resources/scripts/download/mrc#L95. However, I elected to use SHA-256 for extra paranoia.
I generated this config by walking through Coreboot's `make menuconfig`. The plan is to pare down verbose defaults and tweak from here.
Remove options that haven't deviated from defaults in the Coreboot Kconfig, despite being saved by `make savedefconfig`. Also, add `CONFIG_BOARD_LENOVO_THINKPAD_T440P`, which was missing from the `make savedefconfig` output, causing Heads builds to fail. And finally, bump `CONFIG_CBFS_SIZE` to `0x800000` (8 MiB to bytes to hexadecimal). This value for the CBFS size is arbitrary. Originally, I had totaled the size of all binary blobs, subtracted that from the T440p's ROM size (12 MiB), and used the remaining space as the CBFS size (~11.68 MiB). However, this caused very long RAM initialization times (courtesy of `cbmem -t`). And, an anecdote in https://groups.google.com/a/chromium.org/g/chromium-os-reviews/c/lUqRrGUoEBY/m/ka7L1f2BS8gJ suggested that this value needs to be a power of 2. So, I picked a size I expected our Linux payload to fit into that was a power of 2 that I also expected would leave enough space in the ROM for the IFD, ME, GbE, and Coreboot. Now, it takes less than a second for RAM initialization after flashing/first boot (anecdotally, it seems the MRC needs to be "trained?").
Without this, neither Qubes OS nor the Qubes OS installer would start. Presumably, because we're "kexecing" from an already running kernel, we need this set at the Coreboot level? Testing revealed that including `intel_iommu=igfx_off` in the `CONFIG_BOOT_KERNEL_ADD` board config option did nothing. And, the Qubes OS default boot option already contains `intel_iommu=igfx_off`. See: - https://www.qubes-os.org/doc/installation-troubleshooting/#not-asking-for-vnc-because-we-dont-have-a-network--x-startup-failed-aborting-installation--pane-is-dead-error-during-installation - https://github.com/Qubes-Community/Contents/blob/master/docs/troubleshooting/intel-igfx-troubleshooting.md - https://www.kernel.org/doc/html/v5.10/x86/intel-iommu.html?highlight=igfx_off#graphics-problems
29633e7
to
24d23ff
Compare
@rbreslow :
Also if you could provide current logs from boot (cbmem console of last boot dump) would help, where coreboot channel is really helping faster then I would ever have thought! |
They are consistent across multiple boots. I uploaded log files: #1282 (comment).
So, from As far as getting this pull request across the finish line, let's pick an arbitrary value but capture all of this context in a follow-up issue. Then, we can apply a smarter fix to all the boards. |
I diff'd the IFD and GbE blobs that I extracted from my machine from the ones provided by Libreboot for the T440p. Analysis of
|
@rbreslow from top of my head, I can only answer for GBE.bin Spec file to generate those config blobs have been upstreamed to coreboot per @Thrilleratplay, and then sprung the idea of having those being generated at runtime inside of osboot through nvmramutil now part of libreboot. Intel drivers are actually responsible to male sure that at least one of the two regions are valid. You can see under blobs/xx30/README a recipe to produce a GBE region, where instructions are basically duplicating that valid region to recreate a valid GBE.bin dropped there. I'm surprised that libreboot is not providing valid GBE.bin, being behind both spec file and GBE region generator (again blobs/xx30 or xx20/README) where more can be found checking the spec files used to generate those (and where DE:AD:C0:FF:EE comes from for credit and eye blink to creators... and anonymity in numbers) Note that nvmutil is planned to be included in firmware where Mac generator is desired by many. This will generate two equal regions with randomized Mac on demand at first.
Your analysis here is precious, where prior work was not necessarily revalidated and used as is. For what is defined as smaller permissions groups for GBE/me regions, I remember having read those permissions are used by ME to access those regions. On a flashrom perspective, ifd is used (if present. Aftetall this is Intel File descriptor and unique to Intel for those gen) ifd is used to specify regions to be flashed and to poke those regions prior of attempting erase/write functions. If ME region is locked for write (ifdtool not being called on ifd/rom to unlock ME region either by user or by coreboot stitching final firmware) flashrom will warn about protected regions (see https://osresearch.net/Prerequisites#legacy-vs-maximized-boards for legacy boards (where neither ifd nor ME were touched prior of maximized builds existence). This page gives flashrom output when regions are locked https://osresearch.net/Updating#locked-ifd-and-me |
There are some minor differences between the ICH9 and ICH8 flash descriptor. The flash descriptor @Thrilleratplay added to Coreboot ( I enjoyed using the "Hex patterns" DSL to analyze the flash descriptor/GbE blobs. There are data types, functions, conditionals, and even a standard library: https://imhex.werwolv.net/docs/. And now, we have the patterns I created during my analysis above. However, after talking with @WerWolv in Discord (the ImHex developer), I learned it might take work to encode a new binary using the pattern language. But in general, 100%, I agree it'd be cool to generate these blobs at build-time (or even runtime for
Do you know of any official documentation on this? I haven't been able to find anything that explains why there are two regions. And yeah, I see this in the xx30 README: # duplicate binary as per spec
cat gbe1.bin gbe1.bin > ../../../../blobs/xx30/gbe.bin And looking at my own
For clarification: Libreboot does provide a valid
Do you want to include
Thank you so much. Got it. Well, |
I went through all of the different options we copied from the Librem config. The only thing that stood out as irrelevant was NVMe support. However, I'm not a Linux kernel expert, and I didn't do a deep dive, so I'm sure there is still room for improvement.
I performed an analysis of the differences between an me.bin blob I extracted from my T440p and the me.bin blob from Lenovo's website: linuxboot#1282 (comment).
47627a7
to
ed8c74e
Compare
Great to have you back @rbreslow Thanks in particular for the warning about the speaker cable on T440p disassembly - I think the hardware maintenance manual dosen't make it as clear as it could the importance of extreme care when unrouting it. I have just tried the same configuration, but bumping the coreboot version to 4.19. Seems to work fine including suspend/resume |
More aligned with the naming conventions of xx20 and xx30's extract.sh.
I extracted the ifd.bin blob from my T440p using the blobs/t440p/extract script.
- I extracted the gbe.bin blob from my T440p's original ROM using the blobs/t440p/extract script. - Using a hex editor, I corrected the sign bit in part 0 that I found was malformed in my analysis: linuxboot#1282 (comment). - After correcting the sign bit, nvmutil showed that both parts of my gbe.bin blob had valid checksums. - Finally, I used nvmutil to set the MAC address to 00:de:ad:c0:ff:ee.
Before, the T440p blob scripts would look for Coreboot using the find command. Now, we require the user to specify the path to Coreboot in the COREBOOT_DIR environment variable. Also, add an output directory argument to each script. These changes will make it easier to integrate with the Heads build system and CI.
Now, when you run `make BOARD=any-t440p-variant`, the build system automatically fetches mrc.bin and me.bin.
We need extra dependencies to support Coreboot's util/crosfirmware.sh to extract the T440p's mrc.bin.
# Make the Coreboot build depend on the following 3rd party blobs: | ||
$(build)/coreboot-$(CONFIG_COREBOOT_VERSION)/$(BOARD)/.build: \ | ||
$(pwd)/blobs/haswell/mrc.bin $(pwd)/blobs/t440p/me.bin | ||
|
||
$(pwd)/blobs/haswell/mrc.bin: | ||
COREBOOT_DIR="$(build)/$(coreboot_base_dir)" \ | ||
$(pwd)/blobs/haswell/obtain-mrc $(pwd)/blobs/haswell | ||
|
||
$(pwd)/blobs/t440p/me.bin: | ||
COREBOOT_DIR="$(build)/$(coreboot_base_dir)" \ | ||
$(pwd)/blobs/t440p/download-clean-me $(pwd)/blobs/t440p |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make
rule syntax is:
targets : prerequisites
recipe
…
Where a "target" is a path to a file that needs to exist. So, we create two targets for mrc.bin
and me.bin
with recipes that run the corresponding blob scripts. And we make the Coreboot build target (defined elsewhere) depend on these blob targets.
Since a target is a path to a file, if the blobs already exist (e.g., user-supplied blobs), make
will skip these recipes.
See: https://www.gnu.org/software/make/manual/make.html#Rule-Syntax
blobs/haswell/obtain-mrc
Outdated
if [[ ! -f "$1/mrc.bin" ]]; then | ||
pushd "${COREBOOT_DIR}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a mrc.bin
already exists, don't try and download it again. Instead, skip right to the integrity check.
Any reason why NO_GFX_INIT is not defined under coreboot config? (As for x230 for example)? Since Linux provides i915+DRM, it seems unneeded? |
Is this board iGPU only? I'm still personally confused with the presence of libgfx init in coreboot and iGPU+dGPU presence without dGPU blobs. |
Not an issue for this PR, would be a question for when times come to add dGPU blobs for nividia dual graphics board owners. Edit: for reference #1057 (comment) |
Because we're using pushd/popd to make the Coreboot util invocation cleaner, we need to use realpath so that the scripts will work with any user input.
This change will improve build times by allowing the T440p to share the Coreboot 4.17 cache with the Librem boards. Once we update the other ThinkPad boards to use Coreboot 4.19, we'll make the T440p depend on the X230 again. Co-authored-by: Thierry Laurion <insurgo@riseup.net>
75e9e8a
to
1dd9c26
Compare
Nothing to say! Waiting for successful build with workspace passed from librem |
Hi there, I'm following this endeavor closely ever since shmalebx9 came up with his proposal to integrate files from the osboot project. Apart from that, I have some questions regarding Heads. Are their any wikis or manuals aside from osresearch? |
@PerAstraAdDeum ROMs are downloadable from CircleCI following https://osresearch.net/Downloading#downloading-heads-from-circleci Heads is still in a rolling release, there is no planned release until Heads finds a new home inside of an organization (that is political issue) and not figured out yet. This is because @osresearch is a user account and would require Trammel to do the releases himself as opposed to an organisation under github which could assign permissions to me and others to delegate tasks, which otherwise is limited to assign permissions to collaborators. Its a maintainership problem for which I do not have solution today and is the first step to have releases and after which, firmware images, even if not completely reproducible (other problem to be resolved before/after) to have firmware images pushed/downloaded and out in LVFS so fwupd can download firmware images and have Heads verify them (third problem) directly and automatically as users download other software updates. As of now there is another issue opened for no_gfx which seems to be a kernel config issue linked to using 5.x kernel as opposed to 4.x to boot platform and have final OS have console in framebuffer, common with librem platforms (kernel config for t440p was borrowed by librem_common). Long story short, firmware images are downloadable as circleci artifacts, today. |
Overview
I made the following changes to support the ThinkPad T440p:
mrc.bin
blob.maximized
/hotp-maximized
).me.bin
blob from Lenovo's website.ifd.bin
andgbe.bin
blobs extracted from my T440p.I did not perform any research into T440p support that doesn't involve external flashing. As such, I only created and tested
maximized
andhotp-maximized
Heads configurations.I'd like to split the following into follow-up issues/tasks:
Add CI support for the T440p. This will involve figuring out how to provide CI genericifd.bin
,me.bin
, andgbe.bin
blobs.mrc.bin
, to avoid excess load on Google's servers, and ensure we can retrieve it from the Internet Archive if the original source ever disappears (e.g., Libreboot). Perhaps we contribute this as a script to Coreboot?selfboot jump
Coreboot stage. About ~5 seconds longer than @tlaurion's X230. With no immediate difference in payload size.Resolves #1133
Testing Instructions
Requirements
I assume you already have all the system dependencies (e.g.,
gnat
,pkgconfig
, etc.) required to build Heads.I purchased the following to assemble an SPI flasher:
I set up an anti-static ESD mat/wristband at my workstation (connected to ground). And I wore nitrile gloves while performing all this work.
There are a bunch of warnings to avoid the CH341A programmer because the most commonly available one has a defect where it outputs 5.5V instead of 3.3V, which is unfortunate because it seemed like the most straight forward programmer to use.
However, I found a CH341A-variant with a physical jumper to change the voltage from 5.5V to 3.3V. So, I decided to purchase that and follow Chuck Nemeth's instructions to verify that it was outputting the correct voltage.
I tested
GND
to all the pins, got ~3.3V, so we're good to go.I found the following resources helpful when assembling the SPI flasher:
Some miscellaneous notes:
/CS
on the flash chip corresponds toCS0
on the CH341A./WP
or/HOLD
pins.flashrom
source code describes how to connect the remaining pins: https://github.com/flashrom/flashrom/blob/9a152b8191c5bd3b0a88b29c6b267030da77b770/ch341a_spi.c#L277-L289.VCC
(power supply) is disconnected from the SOIC-8 clip.VCC
to the SOIC-8 clip.Building Heads and Flashing
To access the flash chips on the T440p, I followed the "1160 Base cover assembly" instructions on page 79 of the hardware maintenance manual. Not everything here is necessary, there's some nuance required in removing the assembly, and I broke the speaker cable when disassembling my machine. I will expand on this in a future flashing guide.
With everything opened up, the chips are exposed. I used
flashrom
to extract the firmware from both flash chips:Then, I combined the contents of both chips to reproduce the original ROM:
$ cat backup_8192kb_1.bin backup_4096kb_1.bin > t440p_original.bin
Next, I built the project. This will fail, as we haven't supplied any binary blobs. However, we need it to install dependencies, like Coreboot:
$ make BOARD=t440p-hotp-maximized
Update: These steps were accurate when I created the pull request, but the scripts below have changed slightly after 9368404. Now, you only need to run
make
once if you want to use the Heads-supplied blobs.Now, we can extract the binary blobs from the original ROM:
And obtain the Haswell
mrc.bin
blob:We can compile the project again:
And finally, we can flash the T440p:
I tested both the
htop-maximized
andmaximized
variants:And verified both WiFi and Intel GbE networking work on a Qubes OS install:
Some thoughts to wrap up:
Options -->
→Boot Options -->
→Show OS boot menu
→Qubes,_with_Xen_hypervisor
→Make default
and then Heads will promptDo you want to reseal a disk key to the TPM [y/N]:
.OEM Factory Reset / Re-Ownership -->
is NOT your friend. Instead, you want to go underGPG Options -->
→Add GPG key to running BIOS and reflash
, which will prompt you to insert a USB drive containing your GPG public key. Then, the next time you selectUpdate checksums and sign all files in /boot
, Heads will prompt you to insert your GPG smartcard.