MNT Reform
Hardware
root #
lspci
0000:00:00.0 PCI bridge: Synopsys, Inc. DWC_usb3 / PCIe bridge (rev 01) 0000:01:00.0 Network controller: Qualcomm Atheros AR928X Wireless Network Adapter (PCI-Express) (rev 01) 0001:00:00.0 PCI bridge: Synopsys, Inc. DWC_usb3 / PCIe bridge (rev 01) 0001:01:00.0 Non-Volatile memory controller: Silicon Motion, Inc. Device 2263 (rev 03)
root #
lsusb
Bus 001 Device 006: ID 03eb:2042 Atmel Corp. LUFA Keyboard Demo Application Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 005: ID 03eb:2041 Atmel Corp. LUFA Mouse Demo Application Bus 001 Device 002: ID 0451:8142 Texas Instruments, Inc. TUSB8041 4-Port Hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 002: ID 0451:8140 Texas Instruments, Inc. TUSB8041 4-Port Hub Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
root #
cat /proc/cpuinfo
processor : 0 BogoMIPS : 16.66 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4 processor : 1 BogoMIPS : 16.66 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4 processor : 2 BogoMIPS : 16.66 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4 processor : 3 BogoMIPS : 16.66 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4
Installation
Installing Gentoo on the MNT Reform is very similar to how one installs Gentoo on just about any desktop / laptop system. The only parts that need special attention are the bootloader and the kernel.
u-boot
The MNT Reform boots using the u-boot bootloader. There is a patched version available in a separate repository. This bootloader can be used on either an SD-card or on the internal storage, or on both of them.
Unmodified, the bootloader will first attempt to find an OS on the SD card when one is present. For that purpose, it will search the SD-cards first partition for a file /boot.scr and if it can't find that file, for /boot/boot.scr with boot.scr being a u-boot script. If no SD-card is present or none of the above files can be found on the SD-card, the bootloader will then proceed to search for the same files on the first partition of the internal storage.
The exact behavior can be studied and / or modified in the file board/boundary/nitrogen8m_som/nitrogen8m_som.c of the above-mentioned repository.
To build the bootloader, run these commands:
root #
cd /usr/src
root #
git clone https://source.mnt.re/reform/reform-boundary-uboot u-boot
root #
cd u-boot
root #
cp mntreform-config .config
root #
make flash.bin
To install the bootloader to a device, run this command:
root #
dd if=./flash.bin of=/dev/mmcblk1 conv=notrunc bs=1k seek=33
With /dev/mmcblk1 being the SD-card to install it to.
boot script
The bootloader, as prepared above, will load a boot script. This boot script contains the further details on how to load the kernel, device tree, initrd and pass the kernel command line parameters.
The official images for the MNT Reform use a Debian tool called flash-kernel to generate the boot script. But it can pretty easily be done by hand.
First, install the u-boot utilities:
root #
emerge --ask dev-embedded/u-boot-tools
Now, a boot script is needed in human-readable text form. Start out with the same template as used by Debian's flash-kernel. The file is located at: https://salsa.debian.org/installer-team/flash-kernel/-/blob/master/bootscript/arm64/bootscr.uboot-generic
Place that in a file boot.txt, then edit it. Primarily, replace the @@LINUX_KERNEL_CMDLINE_DEFAULTS@@
and @@LINUX_KERNEL_CMDLINE@@
values. The values used in the official Image (as of v3) are ro no_console_suspend cma=512M pci=nomsi
and console=ttymxc1,115200 console=tty1
respectively.
Replace @@KERNEL_VERSION@@
with the kernel version information and remove the @@UBOOT_ENV_EXTRA@@
part.
Once satisfied, compile it by running:
root #
mkimage -A arm -O linux -T script -C none -a 0x0 -e 0x0 -n "boot script" -d boot.txt boot.scr
The while compiling, the file's header information will be printed. To show that information later, run:
root #
dumpimage -l boot.scr
The output is supposed to look a bit like this:
Image Name: boot script Created: Mon Mar 14 15:31:46 2022 Image Type: ARM Linux Script (uncompressed) Data Size: 2441 Bytes = 2.38 KiB = 0.00 MiB Load Address: 00000000 Entry Point: 00000000 Contents: Image 0: 2433 Bytes = 2.38 KiB = 0.00 MiB
Here is the complete boot script used when creating this tutorial:
root #
cat boot.txt
# # flash-kernel: bootscr.uboot-generic # # Bootscript using the new unified bootcmd handling # # Expects to be called with the following environment variables set: # # devtype e.g. mmc/scsi etc # devnum The device number of the given type # bootpart The partition containing the boot files # distro_bootpart The partition containing the boot files # (introduced in u-boot mainline 2016.01) # prefix Prefix within the boot partiion to the boot files # kernel_addr_r Address to load the kernel to # fdt_addr_r Address to load the FDT to # ramdisk_addr_r Address to load the initrd to. # # The uboot must support the booti and generic filesystem load commands. if test -n "${console}"; then setenv bootargs "${bootargs} console=${console}" fi setenv bootargs ro no_console_suspend cma=512M pci=nomsi ${bootargs} console=ttymxc1,115200 console=tty1 root=UUID=8709fad5-63c9-48db-83f3-5bf64ac2873b rd.luks.uuid=03741e41-0882-4327-8805-bb4c5b3be2da rd.luks.allow-discards root_trim=yes # setenv bootpart "1" # setenv prefix "/" # setenv kernel_addr_r "0x40480000" # setenv fdt_addr_r "0x50000000" # setenv ramdisk_addr_r "0x51000000" if test -z "${fk_kvers}"; then setenv fk_kvers '5.12.0' fi # These two blocks should be the same apart from the use of # ${fk_kvers} in the first, the syntax supported by u-boot does not # lend itself to removing this duplication. if test -n "${fdtfile}"; then setenv fdtpath dtbs/${fk_kvers}/${fdtfile} else setenv fdtpath dtb-${fk_kvers} fi if test -z "${distro_bootpart}"; then setenv partition ${bootpart} else setenv partition ${distro_bootpart} fi # place here any u-boot commands to be executed before boot load ${devtype} ${devnum}:${partition} ${kernel_addr_r} ${prefix}vmlinuz-${fk_kvers} \ && load ${devtype} ${devnum}:${partition} ${fdt_addr_r} ${prefix}${fdtpath} \ && load ${devtype} ${devnum}:${partition} ${ramdisk_addr_r} ${prefix}initrd.img-${fk_kvers} \ && echo "Booting Debian ${fk_kvers} from ${devtype} ${devnum}:${partition}..." \ && booti ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r} load ${devtype} ${devnum}:${partition} ${kernel_addr_r} ${prefix}vmlinuz \ && load ${devtype} ${devnum}:${partition} ${fdt_addr_r} ${prefix}dtb \ && load ${devtype} ${devnum}:${partition} ${ramdisk_addr_r} ${prefix}initrd.img \ && echo "Booting Debian from ${devtype} ${devnum}:${partition}..." \ && booti ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r}
Install to SD-card
Having u-boot and the boot script, install them to an SD-card. Since the SD-card will only hold the kernel and initrd, it can be relatively small.
First, prepare the partition table:
root #
parted --script /dev/mmcblk1 "mklabel msdos"
root #
parted --script /dev/mmcblk1 "mkpart primary ext4 4MiB -1"
root #
mkfs.ext4 /dev/mmcblk1p1
Next, write the bootloader to the exact location it needs to be at:
root #
dd if=./flash.bin of=/dev/mmcblk1 conv=notrunc bs=1k seek=33
Now, mount the SD-card's first partition, and place the files in a structure like so (using kernel version 5.12.0 in the below example):
├── boot.scr # The boot script ├── dtb-5.12.0 # The device tree ├── initrd.img-5.12.0 # The initramfs └── vmlinuz-5.12.0 # The kernel
initrd
When generating an initrd make sure the following kernel modules are included and loaded early, to ensure the display output is working:
- pwm_imx27
- pwm_bl
- nwl-dsi
- ti-sn65dsi86
- imx-dcss
- panel-edp
- mux-mmio
- mxsfb
- usbhid
- imx8mq-interconnect
- nvme
Depending on which tool you use to generate the initrd, all or some of those might be included automatically.
When using dracut to build the initrd, add a configuration file that looks like this:
/etc/dracut.conf.d/20_mnt-reform-2.conf
force_drivers+=" pwm_imx27 pwm_bl nwl-dsi ti-sn65dsi86 imx-dcss panel-edp mux-mmio mxsfb usbhid imx8mq-interconnect nvme "
f0 respawning
With a default arm64 system, error messages like this will appear both on the default TTY
in the system log:
Id "f0" respawning too fast: disabled for 5 minutes
To get rid of those, edit the inittab
at /etc/inittab and remove or comment out the last line, that looks something like this:
/etc/inittab
# Architecture specific features f0:12345:respawn:/sbin/agetty 9600 ttyAMA0 vt100
Then, restart the system.
Clock loses time on reboot
The Reform has two Real-time clocks installed in the system - a battery backed up PCF8523
and an on-CPU SNVS
. The SNVS
clock is powered by the same rail as the i.MX8M
CPU and will reset together with the system.
By default, the hwclock
is using /dev/rtc0, which might be the wrong clock.
To fix this issue, either remove the rtc-snvs
kernel driver, or edit the following line in /etc/conf.d/hwclock
/etc/conf.d/hwclock
clock_args="--rtc /dev/rtc1"
Check which RTC has been assigned to which device by looking at the kernel ring buffer:
user $
dmesg | grep --ignore-case rtc
[ 3.556883] rtc-pcf8523 2-0068: registered as rtc0 [ 3.563641] rtc-pcf8523 2-0068: setting system clock to 2020-07-13T17:27:26 UTC (1594661246)
In the above example, the PCF8523
is the only RTC and it is assigned to /dev/rtc0.
Boot from (internal) eMMC using initrd
At some point you will probably want to be able to start the laptop without having an SD card inserted. Also, if you are booting from an encrypted disk, which really you should, you will need a mechanism to open the disk at startup. This chapter will explain how you can achieve both of these goals.