Debugging coreboot with Intel Simics

Make a simple coreboot

On my Ubuntu 21.03 host, I follow the coreboot doc to build a simple ROM: https://doc.coreboot.org/tutorial/part1.html

This is the steps I take and a few screenshot below. This coreboot’s payload is a ELF coreinfo application.

sudo apt-get install -y bison build-essential curl flex git gnat libncurses5-dev m4 zlib1g-dev
git clone https://review.coreboot.org/coreboot
cd coreboot
make crossgcc-i386 CPUS=$(nproc)
make -C payloads/coreinfo olddefconfig
make -C payloads/coreinfo
make menuconfig
   select 'Mainboard' menu
   Beside 'Mainboard vendor' should be '(Emulation)'
   Beside 'Mainboard model' should be 'QEMU x86 i440fx/piix4'
   select < Exit >

   select 'Payload' menu
   select 'Add a Payload'
   choose 'An Elf executable payload'
   select 'Payload path and filename'
   enter 'payloads/coreinfo/build/coreinfo.elf'
   select < Exit >
   select < Exit >
   select < Yes >
make

The goal is to boot this coreboot.rom (256KB) on Simics and it looks like this

Intel Simics

Download from Intel, https://www.intel.com/content/www/us/en/download/645996/30403/simics-simulator-public-release-preview.html

or

https://software.intel.com/content/www/us/en/develop/articles/simics-simulator.html

Extract and install according to the installation guide, https://downloadmirror.intel.com/30403/eng/installation%20and%20getting%20started%20guide.pdf

Once done, create a script based on the “qsp-client-core.simics”

decl {

 params from "%simics%/targets/qsp-x86/qsp-client-core.simics"
  default enable_efi = FALSE
  default bios_image = "/home/james/Works/coreboot/coreboot/build/coreboot.rom"
}

run-command-file "%simics%/targets/qsp-x86/qsp-client-core.simics"

Here is what printed on the serial console

then it reaches,

Debugging coreboot

To debug, Simics need to load the debug symbol, which located in the “build/cbfs/fallback/”

The very first elf file x86 run is bootblock (0xffff_fff0) -> romstage -> ramstage -> postcar

On Simics CLI or on the script we created earlier, add

enable-debugger
add-symbol-file "/home/james/Works/coreboot/coreboot/build/cbfs/fallback/bootblock.debug"

Now we are ready to do single stepping the code

Short tour from Conditional Probability to Bayes’ Theorem

Conditional Probability

Flipping a fair coin has a probability of 0.5 landing a tail, and 0.5*0.5=0.25 for landing tail twice in a row. There are no relationship between each coin flip.

It is more interesting when we can improve a probability from observing from others.

This is a short tour about conditional probability in a few diagrams and a simple example attached.

Notation

p(A) refers to the probability of A

p(A|B) refers to the probability of A, given B already happens.

p(A*B|B) refers to the probability of both (A and B), given B already happens

p(A*B)/p(B) refers to the probability of both (A and B), scale respect to the probability of B happens

p(A|B)
= p(A*B|B)
= p(A*B)/p(B)

Example

Consider the following table and diagram:

Anot A
B2 (Blue)1 (Green)
not B4 (Red)3 (Black)
S = 10, refers to the sampling space (10 dots)
p(A) = 6/10 = 0.6
p(B) = 3/10 = 0.3
p(A*B) = 2/10 = 0.2

p(A|B) = p(A*B|B) = p(A*B) / p(B) => 0.2 / 0.3 = 0.667
p(B|A) = p(B*A|A) = p(A*B) / p(A) => 0.2 / 0.6 = 0.333

The conditional probability shows us that, both probability improves by 11% after adding new condition to restrict sampling space accordingly.

p(A) = 0.6
p(A|B) = 0.667 <-- 11% improvement

p(B) = 0.3
p(B|A) = 0.333 <-- 11% improvement

Bayes’ Theorem

It is an interpretation of conditional probability that: Continuously updating hypothesis by its test evidences

Notation

p(A|B) refers to the probability of A (hypothesis or belief) , given B already happens (observation)

p(B|A) refers to the probability of B (observation), when A happens

p(A) refers to probability of A, prior to observation.

p(B) refers to probability of B, observation happens in both correctly and incorrectly (false positive).

p(A|B) = p(A*B) / p(B)
p(B|A) = p(B*A) / p(A) 
=> p(B|A)*p(A) = p(B*A)

where p(A*B) = p(B*A),

p(A|B) = p(B|A)*p(A) / p(B)

Example

Consider the following table and diagram:

Anot A
B21
not B43
S = 10, refers to the sampling space (10 dots)
p(A) = 6/10 = 0.6
p(B) = 3/10 = 0.3
p(A*B) = 2/10 = 0.2

p(A|B) = p(B|A) * p(A)/p(B) =>  0.333 * 0.6/0.3 = 0.666

Building another small uboot XIP Linux for ARM Cortex M4

Using STM32F429I-DISCO (gen 0)

Background

I must have own this STM32F429I-DISCO for over 6 years, comparing DISCO with the newer DISC1 (32F429IDISCOVERY – Discovery kit with STM32F429ZI MCU * New order code STM32F429I-DISC1 (replaces STM32F429I-DISCO) – STMicroelectronics), the main different is the debugger that does not support VCP. Hence, the very first thing needed to sort out is a USB-UART adaptor cable.

This cable needs to connects with USART1 via the P1 header

P1 Header
- RX (yellow) to PA9
- TX (red) to PA10
- GND (black) to one of the GND available on the board
The UART is configured at 115200.

Detail documentation for the MCU, https://www.st.com/resource/en/reference_manual/rm0090-stm32f405415-stm32f407417-stm32f427437-and-stm32f429439-advanced-armbased-32bit-mcus-stmicroelectronics.pdf

The board has 2MB Flash (0x0800_0000) and 8MB Ram (0x9000_0000), there is no mmc interface nor ethernet port available. Therefore the goal is to create XIP Linux to boot from this 2MB flash memory.

Uboot 2021.07 and booting Kernel 5.13.0
Linux booted in 2 sec, and 3MB RAM left for application to run

Building uBoot

This goal is to reduce uBoot to under 128Kbytes, so it fits to Sector 0 to 4.

Buildroot

Kernel headers – 5.13.x and GCC compiler version – gcc 11.x
rootfs – cpio.gz
don’t build kernel
don’t build bootloader

XIP Kernel

CROSS_COMPILE=arm-none-eabi- ARCH=arm make menuconfig
CROSS_COMPILE=arm-none-eabi- ARCH=arm make -j 8
mkimage -A arm -O linux -T kernel -C none -a 0x08020000 -e 0x08020040 -d arch/arm/boot/xipImage uxipImage
Add Initramfs from the rootfs.cpio.gz by Buildroot
Enable Kernel XIP, the actual XIP location is offset by uboot header (0x40) ** VERY IMPORTANT **

Programming flash

Using the official STM32 Programmer is fairly easy

.\STM32_Programmer_CLI.exe --connect port=SWD -d C:\st\u-boot.bin 0x08000000

Openocd is the opensource alternative, openocd.org/getting-openocd/

.\openocd.exe -f board/stm32f4discovery.cfg `
-c "program C:\\stm32f4\\u-boot.bin 0x08000000 verify" `
-c "program C:\\stm32f4\\uxipImage_0x08020000.bin 0x08020000 verify" `
-c "program C:\\stm32f4\\stm32f429-disco.dtb 0x081e0000 verify" `
-c "reset run" -c "shutdown"

Reference

Here are some links I found it useful

  1. https://youtu.be/p5LxCXbhSCo
  2. https://youtu.be/A21I6NrLszE
  3. Running Linux 4.9 on Cortex-M4 STM32F4 (29I-DISC1) – Stack Overflow
  4. 32F429IDISCOVERY – Discovery kit with STM32F429ZI MCU * New order code STM32F429I-DISC1 (replaces STM32F429I-DISCO) – STMicroelectronics
  5. OpenOCD User’s Guide: Top
  6. microcontroller – Trying to program an STM32 device with ST-LINK_CLI.exe – Electrical Engineering Stack Exchange
  7. arm – Why Device Tree Structure (DTS) file is needed both in bootloader and kernel source code? – Stack Overflow
  8. embedded – How to override U-Boot “bootcmd” variable – Stack Overflow
  9. [PATCH] ARM: add dtbImage.<dt> and dtbuImage.<dt> rules – 摩斯电码 – 博客园 (cnblogs.com)
  10. embedded linux – What is different between u-boot.bin and u-boot.img – Stack Overflow
  11. memory – Linux kernel cannot execute any binary (error -12) – Unix & Linux Stack Exchange
  12. LinuxRamdiskRoot < DULG < DENX

Building a small uboot, Linux and rootfs for ARM Cortex M7

Using STM32F769i Discovery board

Background

I used to work with 8051/2 and Microchip PIC18/24. Comparing them with recent MCU like ARM Cortex M, the M4/M7 has so much more processing power and the ability to access much more memory resources.

This is a short documentation about my findings on building uboot, Linux kernel and root file systems for the STM32F769i discovery board.

Latest stable Uboot 2104 config for ARM Cortex M7 to boot from internal flash
Latest (as of 1st July 2021), Linux Kernel 5.13

Keypoints

  1. uBoot: Disable Falcone Mode
  2. Linux kernel: Change DRAM address to 0x0c000000 and size to 0x01000000
  3. Rootfs: Based on default config for stm32f469

There are four lines of uBoot commands:

setenv bootargs console=ttySTM0,115200 earlyprintk consoleblank=0 ignore_loglevel
fatload mmc 0 0xc0000000 zImage
fatload mmc 0 0xc0500000 rootfs.cpio.uboot
bootz 0xc0000000 0xc0500000 0x081c0000
It loads kernel & rootfs from mmc, dtb from internal flash
Boots takes 1.45sec and ready for login

Preparing uBoot

wget https://source.denx.de/u-boot/u-boot/-/archive/v2021.04/u-boot-v2021.04.tar.gz

tar xzf u-boot-v2021.04.tar.gz

cd u-boot-v2021.04

make stm32f769-disco_defconfig

make menuconfig

From “SPL/TPL” uncheck “Activate Falcon Mode”

Save & exit

CROSS_COMPILE=arm-none-eabi- ARCH=arm make -j 8

The binaries we need are “u-boot.bin” and “spl/u-boot-spl.bin”

Preparing Linux Kernel

wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.13.tar.xz

tar xJf linux-5.13.tar.xz

cd linux-5.13

CROSS_COMPILE=arm-none-eabi- ARCH=arm make stm32_defconfig

CROSS_COMPILE=arm-none-eabi- ARCH=arm make menuconfig

update “System Type” > “DRAM Base” = 0xc0000000 and “DRAM Size” = 0x01000000

uncheck “Boot options” -> “XIP Kernel”

CROSS_COMPILE=arm-none-eabi- ARCH=arm make -j 8

The files we need are zImage and stm32f769-disco.dtb

Preparing rootfs with Buildroot

wget https://buildroot.org/downloads/buildroot-2021.05.tar.gz

tar zxf buildroot-2021.05.tar.gz

cd buildroot-2021.05

Since there is no default configs for stm32f769, will based on stm32f469 instead

make stm32f469_disco_defconfig

make menuconfig

update “Target options” -> “Target Architecture Variant” = cortex-M7

check “Filesystem images” -> “TARGET_ROOTFS_CPIO_UIMAGE”

Not fix.. KNOW PROBLEM: Kernel Headers only have Linux 5.12.x, it would be good if it has 5.13, anyway 5.12.x header still works for the case.

Save & exit

make -j 8

the file we need is “output/images/rootfs.cpio.uboot”

Using it

Here is how the memory map looks like,

Here is how it looks like from uboot to prepare kernel to boot from,

Reference

I won’t be able to do all that without the follow blog/people/projects who kindly share their knowledge online. Thank you very much and you might find they are useful too.

  1. STM32F746 Discovery and U-boot | Clockwork Bird (wordpress.com)
  2. STM32 – eLinux.org
  3. buildroot-labs.pdf (bootlin.com)
  4. Building uClinux for STM32F7 Discovery board | A else B (wordpress.com)
  5. STM32F769I-disco_Buildroot/Makefile at master · fdu/STM32F769I-disco_Buildroot · GitHub
  6. Build Linux for STM32F769I DISCO Using Buildroot // Embedded Linux (adrianalin.gitlab.io)
  7. Linux Boot Options on STM32F769I DISCO // Embedded Linux (adrianalin.gitlab.io)
  8. STM32F7 SOM Release 2.4.0 Resource Directory (emcraft.com)
  9. Building uClinux for STM32F7 Discovery board | A else B (wordpress.com)
  10. (5) Cross-Compiling GCC Toolchain for ARM Cortex-M Processors | LinkedIn
  11. Buildroot with Raspberry Pi – U-Boot (ltekieli.com)

Baking sweet loaf based on Shokupan

Shokupan

There are many recipes online and I follow Shinoko from Chopstick Chronicles

Materials adjusted for my baking tin [12W, 33L, 12H] cm (inside)

Prepare dough
(manual mix 1 min)
Rough mix
(mixer speed 2 for 1 mins)
Mixing
(mixer speed 4 for 10 mins)
Finishing
(mixer speed 4 for 5 mins)
Flour
(> 12% proteins)
600 g
Salt6 g
Suger90 g
Water
(35-45 degreeC)
330 g
Milk powder20 g
Yeast14 g
Egg60 g
Butter60 g

After mixing, cover with cling film and rest about 60-120 mins until double its size (temperature depending)

The whole dough should weight 1200g, shape into 4 pieces 300g each. Rest about 10 mins.

Reshape into rolls, place into the baking tin and cover with cling film. Rest 60 mins until it reaches 80% of the baking tin’s capacity


Variances

Anpan

  1. Divide the dough into 60g each, rest for 10 mins.
  2. Weight 20g Anko, red bean paste and shape into ball
  3. Prepare oven at 100 degreeC, turn off after 2 mins. Place a cup of boiling water in the oven.
  4. Place Anko into dough, reshape into ball.
  5. Put dough into oven and rest 30 mins to double its size.
  6. Apply egg wash then black sesame on top
  7. Bake 10 mins at 180degreeC

Cheese-pan

  1. 60g dough and proof in oven, ~ 30mins
  2. Use a shape knife to cut a cross on dough
  3. Place 20g of shredded Cheddar cheese and some black sesame seeds
  4. Bake 10 mins at 180 degreeC

Baking the Cheesy Tomato Chicken Rice

Original posted by MASA’s Cooking ABC on YouTube: https://youtu.be/eYo956WY1Bc

Minor adjustments for 4 people portion

Step 1
Prepare chicken
Step 2
Stir fry
Step 3
Cook rice
Step 4
Finishing
Chicken legs2 pcs
Onion200g
Carrot100g
Celery100g
Garlic4 pcs (cloves)
Rice300g
White wine100g
Olive oil1 tsp
Chicken stock400g
Tomato200g
Salt20g5g
Sugar5g
Mix herb5g2g
Unsalted butter20g
Scamorza cheese150g

Making cinnamon buns

Orignial images and recipe by Richard Bertinet posted on Gozney : https://www.gozney.com/blogs/recipes/cinnamon-buns-recipe

Small adjustment to reduce the portion to 12 buns instead of 24 buns

DoughFillingEgg Glaze
Milk100g30g
Egg30g15g
White Bread Flour300g
Yeast10g
Sugar25g Caster125g Soft Brown
Salt5g
Unsalted Butter100g75g
Cinnamon5g
Make 12 buns, 60g each

A few important steps for me

  1. Wet ingredients mixed first before adding yeast, then flour… last item is butter. The order does matter.
  2. After cutting the dough, it is easier to roll the dough inwards (toward myself).
  3. Warning Warning.. the kitchen will filled with the nice cinnamon smell afterward, so make sure you use good quality cinnamon 👍
Anything look nicer with Icing sugar.. it is magical!
My healthier option… ;p

Minimum baremetal software for x86

What we need

  1. nasm
  2. qemu-system-x86 (for testing before trying it out on real hardware)

Print a character

Create a “print.asm” file,

ORG 0x7c00
BITS 16

main:
        mov ah, 0eh
        mov al, 'z'
        mov bx, 0
        int 0x10
        jmp $

times 510-($ - $$) db 0
dw 0xAA55

Create a “Makefile”,

all:
        nasm ./print.asm -o ./print.bin -f bin

.PHONY disasm:
        ndisasm print.bin

.PHONY run:
        qemu-system-x86_64 -hda ./print.bin
‘z’ is shown on the QEMU window

Notes:

0x55aa indicates end of boot record, Image from Master Boot Record | Microsoft Docs

Change default boot kernel

Once downloaded

This machine has Ubuntu 20.04 LTS. Once we have upgrade using,

sudo apt update
sudo apt upgrade
Umm.. I wonder which one I am using right now?
not good, why I am on the oldest one here
grep "menuentry '" /boot/grub/grub.cfg
good, the new kernel is on the top menu entry (number 0)
just making a backup.. just in case
sudo vi /etc/default/grub
uncomment (#) GRUB_DEFAULT=0 and commented out (#) the next line, which specify to boot Kernel 5.4.0-56
sudo grub-mkconfig -o /boot/grub/grub.cfg

or

sudo update-grub
generated a new /boot/grub/grub.cfg

Reboot and Clean up

confirmed I am on the new kernel
cleaning up to save some space…. nice!

Not clean enough

dpkg --list | egrep -i --color 'linux-image|linux-headers|linux-modules' | awk '{ print $2 }'
wowow.. hang on.. there are so many of them left here..
sudo apt purge linux-headers-5.7.1 linux-image-5.7.1 linux-image-5.7.1-dbg
Do I really need to do it all manually?

Script

dpkg --list | egrep -i --color 'linux-image|linux-headers|linux-modules' | awk '{ print $2 }' > list.txt
vi list.txt
now I get a list for what I want to remove

on vi, we can replace the newline to space, and adding “apt purge” on the front

:%s/\n/ /g
<ESC>
a
apt purge
<ESC>
:wq
sudo sh list.txt
ready to go!
ohh.. I made a mistake!.. lucky I get this warning, thanks Linux
phew… :p

x11 display on Windows 10 WSL2

What is needed

  1. VcXsrv Windows X Server – Browse /vcxsrv at SourceForge.net
  2. WSL 2 (I am using Alpine)

Setting up

Here are the steps to install VcXsrv

Basically it creates a x11config.xlaunch file like this,

Try it out

Creating a startup file “.profile” at home directory ~/

~/.profile

===

export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0
export LIBGL_ALWAYS_INDIRECT=1

Reference

Alpine On WSL2 – Qiita