coreboot Console via SMBus — Part II

Husni Faiz
4 min readSep 9, 2022

--

In the Part I of the article we saw how to access the SMBus of a mainboard. In this article we’ll see how SMBus console is implemented in coreboot and the final results. Read the coreboot Console via SMBus — Part I article to learn how we setup the development environment.

The first task of the project was to choose a coreboot supported mainboard with socketed RAM. The board status page is not always upto date. It is recommended to check in the community channels (Mailing list, IRC) to know the last status.

I used a Gigabyte GA-H61m-S2PV (Rev 2.2) mainboard and an Ivy bridge (Intel 3rd Gen) processor. This board has an internal flash programmer and DualBIOS feature. A DualBIOS system is where a mainboard has a main BIOS and a backup BIOS so if the main BIOS fails to boot the backup BIOS will take control (if triggered) and restore the main BIOS to a functional version. The recovery process is that the code in the backup chip rewrites the main chip. This combination of DualBIOS and internal programmer eliminates the need for an external flash programmer. The coreboot documentation for this board here.

Main and Backup BIOS chips

DualBIOS triggering mechanism for this board is to connect the M_BIOS flashchip’s pins 4 and 7 to its GND (HOLD# to GND) and power on the board . This will automatically power off and power on the board a couple of times and enter into the recovery mode. After entering into recovery mode you should disconnect the GND connections made earlier to M_BIOS chip.

MX25L3206E Flashchip

Flashing coreboot

First you have to clone the coreboot repo and build the x86 crossgcc toolchain. You can follow the coreboot getting started tutorial here. We only need the steps 1, 2 and 3 but you can complete the full tutorial to verify that the toolchain works fine.

Now we’ll build coreboot for GA-H61M-S2PV. If you already built coreboot for another board make sure you run `make distclean`. Now set the following configurations.

select 'Mainboard' menu
For 'Mainboard vendor' select '(GIGABYTE)'
For 'Mainboard model' select '(GA-H61M-S2PV)'
select < Exit >

You can set the CBFS filesystem in ROM to a maximum of `0x280000` if required but the default size should be enough. We’ll use SeaBIOS as the payload which is the the default payload configuration. Remember that SeaBIOS can’t boot UEFI systems so you need to (re)install your operating system for legacy BIOS mode. If you need to boot an UEFI OS you should check the Tianocore payload.

To flash the coreboot.rom with the internal programmer, create a layout file as follows and run the given flashrom command.

00000000:00000fff fd
00180000:003fffff bios
00001000:0017ffff me
sudo flashrom -p internal -l layout.txt -i bios -w coreboot.rom -c MX25L3206E/MX25L3208E

You can find more information about the board in coreboot board documentation here.

I2C to UART Converter

Now to capture I2C packets we need an I2C slave device. Initially I tried to use an Arduino but the Arduino wire library didn’t work for me for some reason. Then we found an easier way to do this which is using an I2C to UART converted chip. This chip made the work a lot easier. I used an SC16IS750 chip from NXP. The one I bought is this.

SC16IS750

[PATCH 0/5] SMBus Console — Start Coding

The first step of the development is understanding implementation of the coreboot console. Refering the UART, SPI and other console codes will give an idea of what interfaces we should implement for the SMBus console.

coreboot has multiple stages in its execution. RAM initialization happens in the ROMSTAGE so the SMBus is usually initialized in this stage. That means in the BOOTBLOCK stage the SMBus is not initialized. So if we are to get the BOOTBLOCK console output through SMBus we have to initialize the SMBus early on in the BOOTBLOCK.

Now to use the SC16IS7XX I2C to UART converter chip, we have to initialize it first with the required UART configuration. A common UART configuration used is 115200baud rate, 8 data bits, no parity and one stop bit (8-N-1). So SC16IS7XX initialization should also be done along with SMBus initialization.

Refer the coreboot console documentaion to see how to enable the SMBus console in coreboot.

All the patches are listed below.

Commit 1 : SMBus console driver
Commit 2 : Enable SMBus in bootblock
Commit 3 : Attach SMBus console driver
Commit 4 : Initialize SC16IS7XX I2C to UART converter
Commit 5 : Document the SMBus console implementation

Console Output : https://gist.github.com/drac98/64737dd1200d191fb56dc20319b2ec25

--

--