firmware icon indicating copy to clipboard operation
firmware copied to clipboard

Support bigtreetech CB1?

Open seanhagen opened this issue 9 months ago • 5 comments

I know this is probably a big ask, but I'm hoping that supporting the bigtreetech CB1 would be possible.

The CB1 is a board similar to the Raspberry Pi Compute Module 4 but, you know, available at non-scalper prices.

Here's the GitHub releases page for the Debian 11 base they use.

I'd be willing to try and get this working myself, I just need some pointers on what I would need to pull out of that CB1-Kernel repo ( or out of a release from the CB1 repo? ).

seanhagen avatar Sep 24 '23 18:09 seanhagen

We’re not currently looking to expand the officially supported platforms by anything non-Raspberry Pi. However, anyone can provide a community-supported kernel.

Have a look at our community-supported platforms for inspiration: https://gokrazy.org/platforms/#community

In principle, you need to make the gokrazy packer write a booting FAT partition to the SD card. Or, for development, write an SD card, then re-create the FAT file system to more easily experiment with it (gokrazy’s FAT file system offers 0 free space).

In practice, this means putting not just a working Linux kernel image on the partition, but also all device-specific bootloader configuration and extra files, if any.

stapelberg avatar Sep 25 '23 06:09 stapelberg

Thanks for the info!

If I have follow-up questions, where would be the best place to ask? I think I might have a way to make this work without having to dive too deep into how to compile kernels and whatnot -- I just need someone to to bounce ideas off of to see if I'm on the right track.

seanhagen avatar Sep 27 '23 00:09 seanhagen

You can ask questions here in this issue and I’ll try to answer them :)

stapelberg avatar Sep 27 '23 06:09 stapelberg

Alrighty!

So I downloaded the minimal Debian 11 image for the CB1, and after some fiddling with losetup I managed to get the two partitions within the image mounted to two folders on my machine. The first partition is a boot partition, with the following stuff in it:

-rwxr-xr-x 1 root root 1.3K Mar  3  2023  BoardEnv.txt
  -rwxr-xr-x 1 root root 9.4K Mar  3  2023   boot.bmp
  -rwxr-xr-x 1 root root 3.2K Mar  3  2023   boot.cmd
  -rwxr-xr-x 1 root root 3.2K Mar  3  2023   boot.scr
  -rwxr-xr-x 1 root root 177K Mar  3  2023   config-5.16.17-sun50iw9
  drwxr-xr-x 3 root root 4.0K Mar  3  2023   dtb
  drwxr-xr-x 3 root root 4.0K Mar  3  2023   dtb-5.16.17-sun50iw9
  drwxr-xr-x 2 root root 4.0K Mar  3  2023   gcode
  -rwxr-xr-x 1 root root  21M Mar  3  2023   Image
  -rwxr-xr-x 1 root root 8.9M Mar  3  2023   initrd.img-5.16.17-sun50iw9
  -rwxr-xr-x 1 root root    0 Mar  3  2023   .next
  -rwxr-xr-x 1 root root 1.4K Mar  3  2023   system.cfg
  -rwxr-xr-x 1 root root 4.2M Mar  3  2023   System.map-5.16.17-sun50iw9
  -rwxr-xr-x 1 root root 8.9M Mar  3  2023   uInitrd
  -rwxr-xr-x 1 root root  21M Mar  3  2023   vmlinuz-5.16.17-sun50iw9

The gcode folder is empty, and both dtb and dtb-5.16.17-sun50iw9 seem to contain the same things.

The second partition seems to be a standard Debian 11 install?
lrwxrwxrwx  1 root root    7 Feb 26  2023   bin -> usr/bin
  drwxrwxr-x  2 root root 4.0K Mar  3  2023   boot
  drwxr-xr-x  2 root root 4.0K Feb 26  2023   dev
  drwxr-xr-x 80 root root 4.0K Mar  3  2023   etc
  drwxr-xr-x  3 root root 4.0K Mar  3  2023   home
  lrwxrwxrwx  1 root root    7 Feb 26  2023   lib -> usr/lib
  drwx------  2 root root  16K Mar  3  2023   lost+found
  drwxr-xr-x  2 root root 4.0K Feb 26  2023   media
  drwxr-xr-x  2 root root 4.0K Feb 26  2023   mnt
  drwxr-xr-x  2 root root 4.0K Feb 26  2023   opt
  drwxr-xr-x  2 root root 4.0K Dec  9  2022   proc
  drwx------  2 root root 4.0K Mar  3  2023   root
  drwxr-xr-x  3 root root 4.0K Mar  3  2023   run
  lrwxrwxrwx  1 root root    8 Feb 26  2023   sbin -> usr/sbin
  drwxrwxr-x  2 root root 4.0K Mar  3  2023   selinux
  drwxr-xr-x  2 root root 4.0K Feb 26  2023   srv
  drwxr-xr-x  2 root root 4.0K Dec  9  2022   sys
  drwxrwxrwt  2 root root 4.0K Mar  3  2023   tmp
  drwxr-xr-x 11 root root 4.0K Feb 26  2023   usr
  drwxr-xr-x 11 root root 4.0K Feb 26  2023   var

Looking at config-5.16.17-sun50iw9, it contains this at the top:

#
# Automatically generated file; DO NOT EDIT.
# Linux/arm64 5.16.17 Kernel Configuration
#
And searching through that file it would appear the kernel was compiled with SquashFS suppport!
CONFIG_SQUASHFS=y
# CONFIG_SQUASHFS_FILE_CACHE is not set
CONFIG_SQUASHFS_FILE_DIRECT=y
CONFIG_SQUASHFS_DECOMP_SINGLE=y
# CONFIG_SQUASHFS_DECOMP_MULTI is not set
# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set
CONFIG_SQUASHFS_XATTR=y
CONFIG_SQUASHFS_ZLIB=y
CONFIG_SQUASHFS_LZ4=y
CONFIG_SQUASHFS_LZO=y
CONFIG_SQUASHFS_XZ=y
CONFIG_SQUASHFS_ZSTD=y
# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set
# CONFIG_SQUASHFS_EMBEDDED is not set
CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3

So if that's the case, I figure if I can just point the kernel at the right place to continue after booting up, I might be able to use the boot partition almost as-is. That means next is figuring out what the equivalent of cmdline.txt would be here.

As you can see from the directory listing, here's no cmdline.txt like you see in gokrazy/kernel, but BoardEnv.txt seems to serve a similar function -- if this section from boot.cmd is any indication:

if test -e ${devtype} ${devnum} ${prefix}BoardEnv.txt; then
	load ${devtype} ${devnum} ${load_addr} ${prefix}BoardEnv.txt
	env import -t ${load_addr} ${filesize}
fi

The contents of BoardEnv.txt is stuff like this ( this is the first 8 lines of the file, out of 45 ):

bootlogo=true
overlay_prefix=sun50i-h616

## 'sun50i-h616-biqu-sd' for CB1, 'sun50i-h616-biqu-emmc' for CB1 eMMC version
fdtfile=sun50i-h616-biqu-sd

## default 'display' for debug, 'serial' for /dev/ttyS0
console=display

Those values are used in boot.cmd, like so:

if test "${console}" = "detail"; then setenv consoleargs "console=tty0 console=ttyS0,115200"; fi
if test "${console}" = "display"; then setenv consoleargs "console=ttyS0,115200 console=tty1"; fi
if test "${console}" = "serial"; then setenv consoleargs "console=tty1"; fi
if test "${console}" = "cancel_lcd"; then setenv consoleargs "console=ttyS0,115200"; fi

if test "${bootlogo}" = "true"; then setenv consoleargs "bootsplash.bootfile=bootsplash.armbian ${consoleargs}"; fi

Additionally ( and probably most importantly ) there's this line in boot.cmd:

setenv bootargs "root=${rootdev} rootwait rootfstype=${rootfstype} ${consoleargs} consoleblank=0 loglevel=7 ubootpart=${partuuid} usb-storage.quirks=${usbstoragequirks} ${extraargs} ${extraboardargs}"

That... looks exactly like what can be found in cmdline.txt. So this boot.cmd basically seem to be in charge of building up the same arguments found in cmdline.txt in a normal Raspberry Pi boot partition, just in a more scripted way.

What I found most interesting was this bit at the bottom of BoardEnv.txt:

rootdev=UUID=680f8206-1a5c-4dd7-b39f-1229d5017302
rootfstype=ext4

That looks similar to the root=/dev/mmcblk0p2 found in the cmdline.txt in gokrazy/kernel!

So -- all of that was setup so you've got context for my "theory":

It really seems like by editing BoardEnv.txt I could point it at a gokrazy partition, and by editing boot.cmd I could add the init=/gokrazy/init found in the cmdline.txt in gokrazy/kernel.

I think I'd have to re-create boot.scr after those edits though, as boot.cmd seems to be turned into boot.scr ( a u-boot legacy uImage according the output of file boot.scr ), using this bit from the bottom of boot.cmd:

# Recompile with:
# mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr

The one thing I'm not sure about though is that I didn't see anything like init=/gokrazy/init in boot.cmd, and the last few commands are these ones:

load ${devtype} ${devnum} ${ramdisk_addr_r} ${prefix}uInitrd
load ${devtype} ${devnum} ${kernel_addr_r} ${prefix}Image

booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}

So I'm not sure if that uInitrd and Image have more things in them that are required and control the rest of the boot for the CB1; or of those could be ignored entirely.

To sum up:

  1. I think I can modify BoardEnv.txt so that it's pointing at a gokrazy root partition instead of the apparently standard Debian root partition used in the CB1 image
  2. I think I can edit boot.cmd to include init=/gokrazy/init ( I'd just have to re-create boot.scr using that mkimage command )
  3. I'm not sure how the uInitrd or Image files would get in the way of these changes, but I can do more digging to find out what's inside those

Is there anything that jumps out as you as being particularly wrong in my thinking or assumptions? I'm not super familiar with the Linux boot process; it's been a long time since I've compiled a kernel 😅

seanhagen avatar Sep 27 '23 17:09 seanhagen

Thanks for the nice write-up! This all sounds reasonable to me :)

gokrazy is a bit unusual in its usage of the init= kernel parameter. Typically, Linux distributions arrange for /sbin/init to be a symlink to the desired init (typically systemd).

When gokrazy was created, we used FAT for the boot and root partition, which meant that symlinks weren’t possible, and we wanted the gokrazy directory to be called /gokrazy, not /sbin. That’s why we started out with init=/gokrazy/init, and then when we switched to SquashFS for the root partition, we didn’t bother changing it.

stapelberg avatar Oct 01 '23 19:10 stapelberg