mmga

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

README.md (15369B)


      1 # mmga: Make MacBook Great Again
      2 
      3 > **WARNING!** Please DO NOT use mmga! If you want coreboot on your macbook
      4 > and it's listed as supported, read [this blog post](https://ch1p.io/coreboot-macbook-support/)
      5 > first or contact me by email.
      6 
      7 ---
      8 
      9 **mmga** is a script to help flashing coreboot on some MacBook Air and Pro
     10 models without using external SPI programmer. See
     11 [this blog post](https://ch1p.io/coreboot-macbook-internal-flashing/) on how to
     12 do the same manually.
     13 
     14 ### Supported devices
     15 
     16 As of time of writing, following devices are supported in coreboot. Other models
     17 might be supported in future.
     18 
     19 * MacBook Pro 8,1 (13'' Early 2011) (`macbookpro8_1`)<br>
     20 * MacBook Pro 10,1 (15'' Mid 2012 Retina) (`macbookpro10_1`)
     21   
     22   **Attention!** Not all memory configurations are supported, see
     23   [here](#ram-configurations).<br>
     24 
     25 * MacBook Air 5,2 (13'' Mid 2012) (`macbookair5_2`)
     26 
     27   **Attention!** Not all memory configurations are supported, see
     28   [here](#ram-configurations).<br>
     29 
     30 * MacBook Air 4,2 (13'' Mid 2011) (`macbookair4_2`).
     31   
     32   **Attention!** Not all memory configurations are supported, see
     33   [here](#ram-configurations).
     34 
     35 iMac 13,1 is a candidate for support too, but [coreboot port](https://review.coreboot.org/c/coreboot/+/38883)
     36 for this device is not actively maintained at the moment and it may fail to build.
     37 I'll add iMac 13,1 support later when it's fixed.
     38 
     39 ### RAM configurations
     40 
     41 Models with soldered RAM are sold with different memory modules, manufactured by 
     42 different manufacturers. Not all of them are supported currently.
     43 
     44 To determine which memory you have in your MacBook, you can use `inteltool`
     45 and [this script](https://github.com/gch1p/get_macbook_ramcfg). You need to run
     46 them on the target machine.
     47 
     48 First, [download coreboot](#stage1) and build `inteltool`:
     49 ```console
     50 $ cd util/inteltool
     51 $ make -j4
     52 ```
     53 
     54 Download the script and make it executable. Then run:
     55 ```console
     56 $ sudo ./inteltool -g | /path/to/get_macbook_ramcfg -m MODEL
     57 ```
     58 
     59 Replace `MODEL` with your MacBook model: `mbp101` for MacBook Pro 10,1, `mba52`
     60 for MacBook Air 5,2 and `mba42` for MacBook Air 4,2.
     61 
     62 Then check the tables below.
     63 
     64 #### MacBook Pro 10,1
     65 
     66 | RAM configuration | Supported |
     67 | ------------------|-----------|
     68 | 4g_hynix_1600s    | 🚫 No     |
     69 | 1g_samsung_1600   | 🚫 No     |
     70 | 4g_samsung_1600s  | 🚫 No     |
     71 | 1g_hynix_1600     | 🚫 No     |
     72 | 4g_elpida_1600s   | 🚫 No     |
     73 | 2g_samsung_1600   | 🚫 No     |
     74 | 2g_samsung_1333   | 🚫 No     |
     75 | 2g_hynix_1600     | ✅ Yes    |
     76 | 4g_samsung_1600   | 🚫 No     |
     77 | 4g_hynix_1600     | ✅ Yes    |
     78 | 2g_elpida_1600s   | 🚫 No     |
     79 | 2g_elpida_1600    | 🚫 No     |
     80 | 4g_elpida_1600    | 🚫 No     |
     81 | 2g_samsung_1600s  | 🚫 No     |
     82 | 2g_hynix_1600s    | 🚫 No     |
     83 
     84 #### MacBook Air 5,2
     85 
     86 | RAM configuration | Supported |
     87 |-------------------|-----------|
     88 | 4g_hynix          | ✅ Yes    |
     89 | 8g_hynix          | 🚫 No     |
     90 | 4g_samsung        | ✅ Yes    |
     91 | 8g_samsung        | 🚫 No     |
     92 | 4g_elpida         | 🚫 No     |
     93 | 8g_elpida         | 🚫 No     |
     94 
     95 #### MacBook Air 4,2
     96 
     97 | RAM configuration | Supported |
     98 |-------------------|-----------|
     99 | 2g_hynix          | 🚫 No     |
    100 | 4g_hynix          | 🚫 No     |
    101 | 2g_samsung        | 🚫 No     |
    102 | 4g_samsung        | ✅ Yes    |
    103 | 2g_micron         | 🚫 No     |
    104 | 4g_elpida         | 🚫 No     |
    105 
    106 ---
    107 
    108 If your found out that your MacBook's memory is not supported, you can help 
    109 supporting it. Run `sudo inteltool -m`, save output to a text file and create a
    110 new issue specifying your MacBook model, memory configuration name with the text
    111 file attached.
    112 
    113 
    114 ### System requirements
    115 
    116 * Recent Linux distribution booted with `iomem=relaxed` kernel parameter
    117   (required for internal programmer to work);
    118 * Build dependencies. Here's a list for Debian-based distros:
    119     ```
    120     # apt install bison build-essential curl flex git gnat libncurses5-dev m4 zlib1g-dev make libpci-dev libusb-1.0-0-dev
    121     ```
    122 
    123     If you plan to use GRUB2 as a payload:
    124     ```
    125     # apt install libfreetype-dev unifont autoconf
    126     ```
    127 
    128     On other distros package names might differ. Be sure to install **gnat**
    129     prior to building coreboot toolchain.
    130 
    131 ### Building flashrom
    132 
    133 First of all, grab recent flashrom sources and build it:
    134 ```
    135 $ git clone https://review.coreboot.org/flashrom.git && cd flashrom
    136 $ make
    137 ```
    138 
    139 Optionally, install it to `/usr/local/sbin`:
    140 ```
    141 $ sudo make install
    142 ```
    143 
    144 ## How it works
    145 
    146 The firmware of the devices covered by this project is stored on SPI chip. It
    147 consists of various regions: `fd` (Flash Descriptor), `me` (Intel ME) and `bios`
    148 (BIOS, or Apple EFI). Sometimes there are more regions, for example there may be
    149 `gbe` region for Gigabit Ethernet or `ec` region with EC firmware, but for now,
    150 let's focus on our MacBooks.
    151 
    152 The most important region in context of this story is `fd`, the Intel Flash
    153 Descriptor.
    154 
    155 The Intel Flash Descriptor is a data structure of fixed size (4KB) stored on
    156 the flash chip (resides in `0x0000-0x0fff`), that contains various information
    157 such as space allocated for each region on the flash, access permissions, some
    158 chipset configuration and more. In particular, it contains access permissions
    159 for `fd` and `me` regions.
    160 
    161 This is the flash chip layout used in MacBook Air 5,2 (which has 8 MiB flash chip).
    162 It can be extracted from stock ROM image with `ifdtool`:
    163 ```
    164 00000000:00000fff fd
    165 00190000:007fffff bios
    166 00001000:0018ffff me
    167 ```
    168 
    169 Normally, the `fd` and `me` regions should be read-only in production, but this
    170 is not the case with MacBooks. Apparently, Apple's "Think Different" thing
    171 applies to firmware security as well.
    172 
    173 Instead, they decided to use SPI Protected Range Registers (PR0-PR4) to set
    174 protection over `fd`, but here they failed again. Due to a bug (I hope),
    175 `0x0000-0x0fff` is not write-protected after cold boot and becomes read-only
    176 only after resuming from S3.
    177 
    178 You can dump PRx protections on your device by running `flashrom -p internal`.
    179 If it doesn't work, make sure to boot with `iomem=relaxed` or try
    180 `-p internal:laptop=force_I_want_a_brick`.
    181 
    182 This is what you should see after a cold boot (and, if so, mmga should work on
    183 your device):
    184 ```
    185 PR0: Warning: 0x00190000-0x0066ffff is read-only.
    186 PR1: Warning: 0x00692000-0x01ffffff is read-only.
    187 ```
    188 
    189 And this is after resuming from S3:
    190 ```
    191 PR0: Warning: 0x00000000-0x00000fff is read-only.
    192 PR1: Warning: 0x00190000-0x0066ffff is read-only.
    193 PR2: Warning: 0x00692000-0x01ffffff is read-only.
    194 ```
    195 
    196 So, after cold boot flash descriptor is protected neither by PRx registers nor
    197 by access permission bits on the flash descriptor itself. Under certain
    198 circumstances, **writable flash descriptor allows flashing whole SPI flash** by
    199 using a couple of neat tricks, and that is what mmga script does.
    200 
    201 Writable `me` region gives us around 1.5 MiB of writable space. The idea is that
    202 we can shrink ME firmware image with me_cleaner to about ~128 KiB and use the
    203 freed space for a small temporary coreboot image. Writable `fd` gives us ability
    204 to change flash layout and move reset vector. We combine all this, flash modified
    205 regions, then power off (new flash descriptor becomes active on cold boot, so
    206 reboot won't work). Then boot our small temporary coreboot and flash the whole
    207 SPI chip, as there will be no more PRx protections set. So this is a two-stage
    208 process.
    209 
    210 Let's write a new layout:
    211 ```
    212 00000000:00000fff fd
    213 00001000:00020fff me
    214 00021000:000fffff bios
    215 00100000:007fffff pd
    216 ```
    217 
    218 In this layout, we allocate 128 KiB for `me` and 892 KiB for `bios`. To fit the
    219 original 1.5 MiB ME image into the 128 KiB region, it has to be truncated with
    220 [me_cleaner](https://github.com/corna/me_cleaner) with `-t` and `-r` arguments,
    221 the size of resulting image is ~92 KiB. We also have to allocate the remaining
    222 `0x100000-0x7fffff` region for *something*, to be able to address and flash it
    223 in future. So we just mark it as `pd`, which is commonly used for "Platform Data".
    224 
    225 After the new layout is ready, we build small coreboot ROM that fits into the
    226 allocated 892 KiB bios region. Then we flash **`fd`** (`0x0000-0x0fff`),
    227 **`me`** (`0x1000-0x20fff`) and **`bios`** (`0x21000-0xfffff`) according to the
    228 new layout. On the next cold boot, coreboot will be loaded from the
    229 `0x21000-0xfffff` region, and the old firmware, which still resides in
    230 `0x190000-0x7fffff`, will be ignored. This is **stage1**.
    231 
    232 After we boot with small temporary coreboot ROM, we're able to flash the whole
    233 8 MiB chip, because there are no more PRx protections set. We repartition the
    234 chip again, and the new layout looks like this:
    235 ```
    236 00000000:00000fff fd
    237 00001000:00020fff me
    238 00021000:007fffff bios
    239 ```
    240 
    241 It's almost the same, except that `bios` fills all the remaining space. Then we
    242 build coreboot again, flash `fd`, `me` and `bios` and power off again. On the
    243 next cold boot we will have completely corebooted MacBook. This is **stage2**.
    244 
    245 ## Usage instructions
    246 
    247 The **mmga** script automates steps described above and does all the dirty work.
    248 
    249 ### Usage:
    250 
    251 ```
    252 ./mmga <options> ACTION
    253 ```
    254 
    255 ##### Options:
    256 
    257 ```
    258 -h, --help: show help
    259 ```
    260 
    261 ##### stage1 actions:
    262 
    263 ```
    264           dump: dump flash contents
    265          fetch: fetch board tree from Gerrit (if needed)
    266 prepare-stage1: patch IFD, neutralize and truncate ME
    267  config-stage1: make coreboot config (for manual use)
    268   build-stage1: make config and build ROM (for auto use)
    269   flash-stage1: flash ROM ($COREBOOT_PATH/build/coreboot.rom)
    270 ```
    271 
    272 ##### stage2 actions:
    273 
    274 ```
    275 prepare-stage2: patch IFD (if needed)
    276  config-stage2: make coreboot config (for manual use)
    277   build-stage2: make config and build ROM (for auto use)
    278   flash-stage2: flash ROM ($COREBOOT_PATH/build/coreboot.rom)
    279 ```
    280 
    281 ##### other actions:
    282 
    283 ```
    284      flash-oem: flash OEM firmware back
    285 ```
    286 
    287 ### Warning
    288 
    289 You **should** have external means of flashing for a backup, **just in case**.
    290 The procedure described above is quite delicate and error-prone and any mistake
    291 may lead to a brick. In that case, you should have a copy of your original ROM
    292 **on external drive**. Please make a backup of `work/oem/dump.bin` after
    293 running `mmga dump`, or just copy the whole mmga directory.
    294 
    295 These posts may be a little helpful if you ever need to flash externally:
    296 
    297 - [MacBook Air 5,2](https://ch1p.io/coreboot-mba52-flashing/)
    298 - [MacBook Pro 10,1](https://ch1p.io/coreboot-mbp101-flashing/)
    299 
    300 ### Choosing the payload
    301 
    302 Currently, SeaBIOS and GRUB are supported by mmga. SeaBIOS supports legacy boot,
    303 it will most probably boot from an old school MBR partition. On the other hand,
    304 it may not boot from GPT (I'm not sure about it, correct me if you know more)
    305 and certainly it will not boot an EFI installation.
    306 
    307 Sometimes GRUB is a better choice, but it all depends on your system. If you are
    308 not sure, do some research before flashing or seek for help.
    309 
    310 It may be a good idea to prepare a USB drive with some live system. I can imagine
    311 a situation where you have chosen the wrong payload and cannot boot into your
    312 system after power off/on cycle to complete the second stage, because, for instance,
    313 SeaBIOS doesn't recognize your partition. In that case, you could try to boot
    314 from live USB to fix your system (if possible) or to complete second stage and
    315 change the payload.
    316 
    317 Of course, in order to do that, you should backup the whole mmga directory after
    318 the completion of the first stage but **before** the reboot.
    319 
    320 **Attention!** Recent SeaBIOS versions break internal keyboard and touchpad on
    321 MacBooks, for now it's recommended to use GRUB until it's fixed.
    322 
    323 ### Configuration
    324 
    325 Before you start, you have to update variables the `config.inc` file:
    326 - **`PAYLOAD`**: which payload to use, supported values are `grub` and `seabios`
    327 - **`MODEL`**: put your macbook model here, example: `macbookair5_2`
    328 - **`GRUB_CFG_PATH`**: only if you use `grub` payload; if empty, default
    329   `grub.cfg` will be used
    330 - **`COREBOOT_PATH`**: path to cloned coreboot repository (see below)
    331 - **`FLASHROM`**: path to flashrom binary
    332 - **`FLASHROM_ARGS`**: in case if flashrom detects multiple flash chips, put
    333   `"-c CHIP_MODEL"` here
    334 - **`STAGE2_USE_FULL_ME`**: if you want to use original Intel ME image in the
    335   final ROM for some reason, set to `1`
    336 
    337 #### stage1
    338 
    339 Get coreboot:
    340 ```
    341 $ git clone --recurse-submodules https://review.coreboot.org/coreboot.git && cd coreboot
    342 ```
    343 
    344 Build coreboot toolchain. You must have gnat compiler installed, it is required
    345 for graphics initialization (libgfxinit is written in Ada):
    346 ```
    347 $ make crossgcc-i386 CPUS=$(nproc)
    348 $ make iasl
    349 ```
    350 
    351 Dump the flash chip contents:
    352 ```
    353 # ./mmga dump
    354 ```
    355 
    356 **Create a backup of the stock ROM dump on external drive!**
    357 
    358 Create patched FD and neutralize ME:
    359 ```
    360 $ ./mmga prepare-stage1
    361 ```
    362 
    363 If your board's port hasn't been merged to coreboot master yet or you don't know,
    364 run:
    365 ```
    366 $ ./mmga fetch
    367 ```
    368 
    369 Create coreboot config and build the ROM:
    370 ```
    371 $ ./mmga build-stage1
    372 ```
    373 
    374 (If you're experienced coreboot user or developer, you may want to configure and
    375 build coreboot yourself. In that case, run `config-stage1` instead of
    376 `build-stage1`. It will create config that you can then copy to `$COREBOOT_PATH`,
    377 make your changes and build.)
    378 
    379 Flash it:
    380 ```
    381 # ./mmga flash-stage1
    382 ```
    383 
    384 If it's done and there were no errors, you have to **shutdown** the laptop.
    385 Do not reboot, the new flash descriptor is only active after cold boot, so it
    386 won't work and may lead to weird stuff as you've just messed with firmware. Wait
    387 a few seconds and power it back on.
    388 
    389 #### stage2
    390 
    391 Make patched flash descriptor for the next flash:
    392 ```
    393 $ ./mmga prepare-stage2
    394 ```
    395 
    396 Create new coreboot config and build the ROM (for experienced users,
    397 `config-stage2` is also available):
    398 ```
    399 $ ./mmga build-stage2
    400 ```
    401 
    402 Flash it:
    403 ```
    404 # ./mmga flash-stage2
    405 ```
    406 
    407 This may take a while, don't interrupt it and let it finish.
    408 
    409 Again, if there were no errors, power off the machine again, wait a few seconds,
    410 and power on.
    411 
    412 ## FAQ
    413 
    414 **My device is not listed, will it work?**
    415 
    416 No, but it might be possible to support it.
    417 
    418 **Will macOS continue to work with coreboot?**
    419 
    420 No. It's theoretically possible to turn a corebooted MacBook into a hackintosh
    421 by using TianoCore and Clover or OpenCore. Basically, if you want to use macOS,
    422 don't install coreboot.
    423 
    424 **Switching between iGPU and dGPU on MacBook Pro 10,1**
    425 
    426 Last time I checked, [hacks](https://wiki.archlinux.org/index.php/MacBookPro10,x#Graphics_2)
    427 were needed to use Linux with integrated GPU on this model. It seems that Apple EFI
    428 forces dGPU when OS is not macOS. I've integrated hybrid graphics driver into
    429 coreboot, it automatically switches to the configured GPU and you don't need to
    430 care about it anymore. By default, integrated GPU is used. The setting is stored
    431 in CMOS and you can change it with `nvramtool`.
    432 
    433 Note that to use discrete GPU you need to extract VGA ROM from the stock firmware
    434 dump and add it to CBFS, and configure coreboot to run VGA Option ROMs.
    435 
    436 ## TODO
    437 
    438 - Support custom FMAP for larger first-stage `bios` partition
    439 - Support multiple payloads at once
    440 - Support TianoCore as a payload
    441 
    442 ## Misc
    443 
    444 The script was tested on MacBook Air 5,2, MacBook Pro 8,1 and MacBook Pro 10,1.
    445 If you have successfully corebooted your macbook with it and it worked, please
    446 let me know.
    447 
    448 If you have any problems, contact me via GitHub issues or by email (see the
    449 copyright header in the script).
    450 
    451 ## License
    452 
    453 GPLv2