Build the Coreboot ROM Image (ThinkPad T430)
============================================


Copyright (C) 2018, 2019, 2021, 2022  Kai Mertens <kmx@posteo.net>  

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
copy of the license is included in the section entitled "GNU Free
Documentation License".


TODO: This file lists essential steps for reference only and should be
completed. Please use the toolchain scripts instead. See
`../doc/toolchain.md`.


Coreboot Documentation
----------------------


When reading this How-to, please go along with Coreboot Documentation:

<https://doc.coreboot.org/getting_started/index.html>  
<https://doc.coreboot.org/mainboard/lenovo/t4xx_series.html>  
<https://doc.coreboot.org/mainboard/lenovo/t430.html>  
<https://doc.coreboot.org/mainboard/lenovo/xx30_series.html>  


Retrieve Sources, Checkout and Compile Toolchain
------------------------------------------------


Basically:

    $ git clone https://review.coreboot.org/coreboot
    $ cd coreboot
    $ git checkout 4.8.1
    $ git submodule update --init --checkout
    $ make crossgcc-i386


Extract Binary Blobs from Original Firmware Dump
------------------------------------------------


Place your original `lenovo.bin` firmware dump into folder
`coreboot/util/ifdtool/`, then use `ifdtool` to extract flashregions,
i.e.:

    $ cd util/ifdtool
    $ make
    $ ./ifdtool -x lenovo.bin
    File lenovo.bin is 12582912 bytes
      Flash Region 0 (Flash Descriptor): 00000000 - 00000fff
      Flash Region 1 (BIOS): 00500000 - 00bfffff
      Flash Region 2 (Intel ME): 00003000 - 004fffff
      Flash Region 3 (GbE): 00001000 - 00002fff
      Flash Region 4 (Platform Data): 00fff000 - 00000fff (unused)
    $ ls *.bin
    flashregion_0_flashdescriptor.bin  flashregion_1_bios.bin  flashregion_2_intel_me.bin  flashregion_3_gbe.bin  lenovo.bin

* Flash region 0 will be used as is by this How-to.

* Flash region 1 will be replaced by coreboot firmware. From the output
  above, the original size of that region is obvious: 0x700000. This
  region might be increased if region 2 (Intel ME) is shrunk.

* Flash region 2 will be cleaned by means of ME_Cleaner.
  See `build/me_cleaner.log` for more infos, i.e.:

        [...]
        The ME minimum size should be 1667072 bytes (0x197000 bytes)
        The ME region can be reduced up to:
         00003000:00199fff me
        Checking the FTPR RSA signature... VALID
        Done! Good luck!

    However, shrinking the ME region down from 5MB to 1.6MB is a
    different step, not yet documented here. See
    `../doc/how-to-modify-ifd.md` and `../doc/toolchain.md` instead.

* Flash region 3 will be used as is with this How-to.


Coreboot Configuration
----------------------


    $ make menuconfig

Use default values, but additionally select/deselect as specified:

* Mainboard
    - Select: Mainboard vendor (Lenovo)
    - Select: Mainboard model (ThinkPad T430)
    - Select: ROM chip size (12MB)
    - Select: Size of CBFS filesystem in ROM = 0x700000

* General Setup
    - Select: Use CMOS configuration values

* Chipset
    - Include CPU microcode in CBFS (Generate from tree)  --->

    - Select: Add Intel descriptor.bin file

        `"(util/ifdtool/flashregion_0_flashdescriptor.bin)"` Path and
        filename of the descriptor.bin file

    - Select: Add Intel ME/TXE firmware

        `"(util/ifdtool/flashregion_2_intel_me.bin)"` Path to
        management engine firmware

    - Select: Verify the integrity of the supplied ME/TXE firmware

    - Select: Strip down the Intel ME/TXE firmware

        *** Please test the modified ME/TXE firmware and coreboot in
        two steps ***

    - Select: Add gigabit ethernet firmware

        `"(util/ifdtool/flashregion_3_gbe.bin)"` Path to gigabit
        ethernet firmware

        NOTE: It seems as if this blob is optional, in case you want to
        disable onboard LAN. See TODO notes above.

* Devices
    - Graphics initialization (Use libgfxinit)  --->
    - Display  --->
        + Framebuffer mode (Linear "high-resolution" framebuffer)  --->

* Payload
    - Select: Add a payload (An ELF executable payload)
    - `"(payload.elf)"` Payload path and filename

        NOTE: File `payload.elf` should match your previously built
        executable GRUB payload file for platform i386-coreboot. See
        [GRUB How-To][].

    - Secondary Payloads --->
        + Select: Load coreinfo as a secondary payload
        + Select: Load nvramcui as a secondary payload

NOTE: The .config file may contain your paths which you probably don't
want to share with others.


Compile
-------


When you have exit the `menuconfig` tool, type:

    $ make

This will provide the `coreboot.rom` in folder `build/`.


Add Custom Files
----------------


### Add Zerocat’s GRUB Configuration File


Use coreboot’s `cbfstool` to add the custom configuration file as `etc/zerocat.cfg`:

    $ build/cbfstool build/coreboot.rom \
        add -t raw -n etc/zerocat.cfg -f <your/path/to/grub@2.02_zerocat.cfg>
    $ build/cbfstool build/coreboot.rom \
        print

See [grub@2.02_zerocat.cfg][] for reference. Before using it, please
edit the file and adjust your keyboard layout which is currently
pre-set via `keymap`.

NOTE: The T430 sound card seems to be off during boot, thus muting the
GRUB Console. Commands like `play 1200 1000 10` won't create any audible
output, same as morse codes or speaker modem.


### Secondary Payloads


#### NVRAMCUI and Coreinfo


Secondary payloads `nvramcui` and `coreinfo` should be accompanied with
an informative message about occasional freezes, what can be achieved
with GRUB, but not with SeaBIOS. Therefor, let’s move them out of the
SeaBIOS `img/` search path:

    $ for i in coreinfo nvramcui; do \
        build/cbfstool build/coreboot.rom \
          extract -m x86 -n img/$i -f $i.extracted && \
        build/cbfstool build/coreboot.rom \
          remove -n img/$i && \
        build/cbfstool build/coreboot.rom \
          add-payload -c lzma -n $i -f $i.extracted && \
        rm $i.extracted; \
      done;

NOTE: When invoking `coreinfo` fromout the GRUB Boot Menu, please get
prepared for occasional freezes due to CPU exceptions and faults. See
[Coreinfo CPU Exceptions][].

NOTE: When invoking `nvramcui` or `coreinfo` fromout the GRUB Boot
Menu, switch your RF Kill Switch off! Active bluetooth devices might
freeze the application.


#### Add SeaBIOS Payload


[Zerocat’s GRUB Configuration File][grub@2.02_zerocat.cfg] already
comes with a menu entry to chainload the SeaBIOS payload. Add files to
the `coreboot.rom` as required:

    $ build/cbfstool build/coreboot.rom \
        add -t raw -n config-seabios -f <your/path/to/seabios/.config>
    $ build/cbfstool build/coreboot.rom \
        add -t raw -n vgaroms/vgabios.bin -f <your/path/to/seabios/out/vgabios.bin>
    $ build/cbfstool build/coreboot.rom \
        add-payload -n bios.bin.elf -f <your/path/to/seabios/out/bios.bin.elf>
    $ build/cbfstool build/coreboot.rom \
        print

Please read section “Adding SeaBIOS Payload” of the [GRUB How-To][] for
more information.


### Add Background Images


The ZC-T430 machine comes with a special 1366x768px PNG background
image. Note the module `png` has already been packed in section "Build
GRUB", therefore you can just add your image like so:

    $ build/cbfstool build/coreboot.rom \
        add -t raw -n background.png -f <your/path/to/background.png>
    $ build/cbfstool build/coreboot.rom \
        print

You may add up to three more images named `background_1.png`,
`background_2.png` and `background_3.png`. This feature provides space
for additional information, such as a documented flash procedure for
example. Use hotkey 'i' in GRUB’s Boot Menu to cycle through the
images, “no image” included.


Tweak Parameters in `cmos.default`
----------------------------------


Get an overview of tweakable parameters:

    $ build/util/nvramtool/nvramtool -C build/coreboot.rom -a

Tweak parameters `gfx_uma_size`, `wwan` and `bluetooth` in the ROM’s `cmos.default` file:

    $ build/util/nvramtool/nvramtool -C build/coreboot.rom -w gfx_uma_size=224M
    $ build/util/nvramtool/nvramtool -C build/coreboot.rom -w wwan=Disable
    $ build/util/nvramtool/nvramtool -C build/coreboot.rom -w bluetooth=Disable

Inquire parameter’s possible values with option `-e`, i.e.:

    $ build/util/nvramtool/nvramtool -C build/coreboot.rom -e gfx_uma_size

As a result, these are the ROM’s default settings for the NVRAM:

    $ build/util/nvramtool/nvramtool -C build/coreboot.rom -a
    boot_option = Fallback
    reboot_counter = 0x0
    debug_level = Spew
    nmi = Enable
    power_on_after_fail = Disable
    first_battery = Primary
    bluetooth = Disable
    wwan = Disable
    touchpad = Enable
    wlan = Enable
    trackpoint = Enable
    fn_ctrl_swap = Disable
    sticky_fn = Disable
    usb_always_on = Disable
    sata_mode = AHCI
    backlight = Both
    gfx_uma_size = 224M
    hybrid_graphics_mode = Integrated Only
    volume = 0x3

Note you will be able to modify these settings with the NVRAMCUI
Payload upon boot time.


Split into Top and Bottom ROM
-----------------------------


As two individual flash chips are used to form a virtual 12M BIOS chip
on the ThinkPad T430 systemboard, we have to split the generated ROM:

    $ cd coreboot
    $ dd if=build/coreboot.rom of=build/coreboot-bottom.rom bs=1M count=8
    $ dd if=build/coreboot.rom of=build/coreboot-top.rom bs=1M skip=8

The file `coreboot-bottom.rom` belongs into chip #1, located close to
the sysboard’s HDD SATA Connector.  
The file `coreboot-top.rom` belongs into chip #2, located between chip
#1 and the SATA Connector of the CD/DVD-Slot.  


Done!
-----


Your ROM files should now be ready to go!

Remember to clean up folder `util/ifdtool/` by removing binaries or by
creating a backup, i.e.:

    $ cd coreboot/util/ifdtool
    $ mkdir backup-t430
    $ mv *.bin backup-t430

Don't forget to reset the checksum of your NVRAM Option Table to zero
by unplugging the small coin battery for some seconds.



[GRUB How-To]:                ../doc/grub-how-to.md
[Coreinfo CPU Exceptions]:    ../doc/coreinfo-cpu-exceptions.md
[grub@2.02_zerocat.cfg]:      ../templates/grub@2.02_zerocat.cfg
