Evgeny Zinoviev has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/38770 )
Change subject: Documentation: Add MacBook internal flashing tutorial ......................................................................
Documentation: Add MacBook internal flashing tutorial
Change-Id: I2650d5d60db7a29a1567e44e89b785def9342df2 Signed-off-by: Evgeny Zinoviev me@ch1p.io --- M Documentation/flash_tutorial/int_flashrom.md A Documentation/flash_tutorial/int_macbook.md 2 files changed, 294 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/70/38770/1
diff --git a/Documentation/flash_tutorial/int_flashrom.md b/Documentation/flash_tutorial/int_flashrom.md index 28b534b..0ca59af 100644 --- a/Documentation/flash_tutorial/int_flashrom.md +++ b/Documentation/flash_tutorial/int_flashrom.md @@ -16,4 +16,9 @@ flashrom -p internal -w coreboot.rom ```
+## Vendor-specific + +- [Lenovo ThinkPad xx30 series](../lenovo/ivb_internal_flashing) +- [Apple MacBook](int_macbook.md) - 2011-2012 models + [flashrom's wiki]: https://www.flashrom.org/Flashrom diff --git a/Documentation/flash_tutorial/int_macbook.md b/Documentation/flash_tutorial/int_macbook.md new file mode 100644 index 0000000..b0638ca --- /dev/null +++ b/Documentation/flash_tutorial/int_macbook.md @@ -0,0 +1,289 @@ +# Apple MacBook internal flashing + +This page describes a method of flashing coreboot on 2011-2012 models of +Apple MacBooks. Whether it can be used on other generations of MacBooks +is unknown. + +This is a very delicate prodecure. Be very careful, check everything +twice, especially the numbers. A single mistake may brick your machine +and you'll have to flash the backup externally. Given this fact, you +should have an external means of flashing, just in case. + +It was tested and confirmed to work on following models: +- MacBook Air 5,2 +- MacBook Pro 8,1 +- MacBook Pro 10,1 + +MacBook Air 4,2 should work too, but it's not tested. + +## Introduction + +Apple's "Think Different" slogan fits perfectly with their approach to +firmware security. Besides the fact that they do not use SMM_BWP to +protect SPI flash from being writable from userspace, they do not even +protect Flash Descriptor (`fd`) and Management Engine (`me`) regions. + +The Intel Flash Descriptor is a data structure of fixed size (4KB) +stored on the flash chip (resides in `0x0000-0x0fff`), that contains +various information such as space allocated for each region on the +flash, access permissions, some chipset configuration and more. In +particular, it contains access permissions for `fd` and `me` regions. +Normally they should be read-only in production, but Apple, for whatever +reasons, keeps them read-write. + +Instead, they decided to use SPI Protected Range Registers (PR0-PR4) to +set protection over `fd`, but here they failed again. Due to a bug in +their firmware, `0x0000-0x0fff` is not write-protected after cold boot +and becomes read-only only after resuming from S3. You can dump PRx +protections by running `flashrom -p internal`. + +This is what you should see after a cold boot (if so, then you can use +this guide): +``` +PR0: Warning: 0x00190000-0x0066ffff is read-only. +PR1: Warning: 0x00692000-0x01ffffff is read-only. +``` + +And this is after resuming from S3: +``` +PR0: Warning: 0x00000000-0x00000fff is read-only. +PR1: Warning: 0x00190000-0x0066ffff is read-only. +PR2: Warning: 0x00692000-0x01ffffff is read-only. +``` + +So, after cold boot flash descriptor is not protected neither by PRx +registers nor by access permissions bits on the flash descriptor itself. +Under certain circumstances, **writable flash descriptor allows to flash +whole SPI flash** by using a couple of tricks. + +The idea is that we can shrink ME firmware with me_cleaner, flash small +coreboot image on the freed space and move reset vector there. Then +power off, boot coreboot and flash full image, as there will be no more +PRx set. + +## Stage 1. Flashing temporary BIOS + +#### Preparations + +Dump your ROM: +``` +flashrom -p internal -r orig.bin +``` + +Please save this backup to an external drive. You may need it in case of +failure. + +Extract flash layout: +``` +ifdtool -f orig_layout.txt orig.bin +cat orig_layout.txt +``` + +You should see something like or exactly this: +``` +00000000:00000fff fd +00190000:007fffff bios +00001000:0018ffff me +``` +If you compare these regions with what's protected by PR0 and PR1, +you'll notice that `fd` and `me` regions are fully writable and only +`bios` is protected. Writable ME region gives us around 1.5 MB which we +can use for our goals. + +Extract flash regions from the dump into separate files: +``` +ifdtool -x orig.bin +``` + +You can see that 3 new files were created: +``` +ls flash* +flashregion_0_flashdescriptor.bin flashregion_1_bios.bin flashregion_2_intel_me.bin +``` + +The ME firmware is ~1.5 MB in size, but we can truncate it with +me_cleaner: +``` +me_cleaner.py -t -r -O flashregion_2_intel_me_truncated.bin flashregion_2_intel_me.bin +``` + +The truncated firmware should be around 90K: +``` +stat --printf=%s flashregion_2_intel_me_truncated.bin +94208 +``` + +Rename the original `flashregion_2_intel_me.bin` file to not mix them up +in future: +``` +mv flashregion_2_intel_me.bin flashregion_2_intel_me_orig.bin +``` + +Now we need to write a new flash layout. 128K is more than enough for +the "neutered" ME firmware. We can use the rest for new `bios` region, +but 892K is enough: + +``` +00000000:00000fff fd +00001000:00020fff me +00021000:000fffff bios +00100000:007fffff pd +``` + +Note that we must allocate the remaining `0x100000-0x7fffff` for +something to be able to address and flash it in future. Let's just mark +it as `pd` (which stands for "Platform Data") for now. + +Save the new layout to a file `new_layout.txt` and update regions in the +dump: +``` +ifdtool -n new_layout.txt orig.bin +``` + +The updated image will be saved to `orig.bin.new`. Move it to a +separate directory for convenience: +``` +mkdir patched && cd $_ +mv ../orig.bin.new . +``` + +Extract flash regions again, now from the updated image: +``` +fdtool -x orig.bin.new +``` + +By now we have new `flashregion_0_flashdescriptor.bin` file with our +custom layout. Let's also move the patched ME here: +``` +rm flashregion_2_intel_me.bin +mv ../flashregion_2_intel_me_truncated.bin . +``` + +So far, so good. At this point our preparations for the first stage are +finished and we're ready to configure coreboot. + +#### Configuring and flashing coreboot + +Run `make menuconfig` and configure as shown below. Note that you need +to change **ROM chip size**, **CBFS size** and specify paths to modified +`flashregion_0_flashdescriptor.bin` and +`flashregion_2_intel_me_truncated.bin`. + +``` +Mainboard ---> + Mainboard vendor (Apple) + Mainboard model () # Set according to your model + ROM chip size (1024 KB (1 MB)) + (0xd0000) Size of CBFS filesystem in ROM + +Chipset ---> + [*] Add Intel descriptor.bin file + (/path/to/patched/flashregion_0_flashdescriptor.bin) Path and filename of the descriptor.bin file + [*] Add Intel ME/TXE firmware + (/path/to/patched/flashregion_2_intel_me_truncated.bin) Path to management engine firmware + [ ] Verify the integrity of the supplied ME/TXE firmware + [ ] Strip down the Intel ME/TXE firmware + Protect flash regions (Unlock flash regions) +``` + +Then you need to decide which payload to use. For now, it's recommended +to use GRUB2. Be sure to include a good config for it that can load variety +of setups. SeaBIOS works too, but currently needs a patch for internal +MacBook's keyboard to work. + +When configuration is done, run `make` to build coreboot. In the end you +should have 1024 KB coreboot ROM at `build/coreboot.rom`. Flashrom won't +accept it, because it's size must match the chip, so we have to make it +8 MB. Just add 7 MB of zeroes: +``` +dd if=/dev/zero of=7M.bin bs=1024 count=7168 +``` +``` +cat build/coreboot.rom 7M.bin > coreboot8.rom +``` + +Now cross your fingers and flash the new **`fd`** (`0x0000-0x0fff`), +**`me`** (`0x1000-0x20fff`) and **`bios`** (`0x21000-0xfffff`) regions +using the layout file: +``` +flashrom -p internal -w coreboot8.rom -l new_layout.txt -i fd -N +flashrom -p internal -w coreboot8.rom -l new_layout.txt -i me -N +flashrom -p internal -w coreboot8.rom -l new_layout.txt -i bios -N +``` + +The first stage is completed. Power off the machine now. Reboot won't +work: new flash descriptor becomes active on cold boot. + +On the next boot, if you're lucky and didn't do any mistake, coreboot +will be loaded from the new `bios` region, and Apple's EFI, that still +resides in `0x190000-0x7fffff`, will be ignored. + +## Stage 2. Flashing full ROM + +Now we can flash whole 8 MB chip, because no PRx are set anymore. Let's +relayout the chip again. + +If you want to continue using truncated ME: +``` +00000000:00000fff fd +00001000:00020fff me +00021000:007fffff bios +``` + +If you want to flash full ME firmware back: +``` +00000000:00000fff fd +00001000:0018ffff me +00190000:007fffff bios +``` + +Save it to `final_layout.txt` and create new flash descriptor again. +``` +mkdir patched2 && cd $_ +cp ../orig.bin . +ifdtool -n final_layout.txt orig.bin +ifdtool -x orig.bin.new +``` + +Go back to coreboot directory and run `make menuconfing`. + +In the **Mainboard** section change **ROM chip size** back to 8 MB and +set **Size of CBFS** according to your needs: now you have plenty of +space. `0x500000` or so should work just fine. + +In the **Chipset** section, update paths to the flash descriptor and ME +firmware files. If you decided to stick to truncated ME, use +`flashregion_2_intel_me_truncated.bin`, otherwise use +`flashregion_2_intel_me_orig.bin`. + +``` +Mainboard ---> + ROM chip size (8192 KB (8 MB)) + (0x500000) Size of CBFS filesystem in ROM + +Chipset ---> + [*] Add Intel descriptor.bin file + + # Use the latest flashdescriptor from the patched2 directory + (/path/to/patched2/flashregion_0_flashdescriptor.bin) Path and filename of the descriptor.bin file + + [*] Add Intel ME/TXE firmware + (/path/to/patched/flashregion_2_intel_me_truncated.bin) Path to management engine firmware + [ ] Verify the integrity of the supplied ME/TXE firmware + [ ] Strip down the Intel ME/TXE firmware +``` + +Save the config and `make` it again. Then flash `fd` and `bios` +according to the `final_layout.txt`: +``` +flashrom -p internal -w build/coreboot.rom -l final_layout.txt -i fd -N +flashrom -p internal -w build/coreboot.rom -l final_layout.txt -i bios -N +``` + +If you changed ME firmware back to original, flash it as well: +``` +flashrom -p internal -w build/coreboot.rom -l final_layout.txt -i me -N +``` + +Stage 2 is completed. Power off (reboot won't work again). On the next +boot, you will have completely corebooted MacBook.