# helper functions

These functions focus on the installation of devuan directly to disk using the
zfs filesystem as the root fs.

you can find these blend helper functions in `blends/${blend_name}/helpers`.

additional or overridden helper functions to add or test functionality or workarounds
specific to the blend to avoid changes to the sdk.

## build_arm_dist()

defines the sequence of calls that will result in an SDcard image with gpt
partition table and u-boot.

- partition_type, gpt_boot and gpt_root must be set to gpt, and the boot and
  root size respectively in the blend

- partition_type=gpt
- gpt_boot=
- gpt_root=

## build_metal_dist()

defines the sequence of calls that will result in a devuan install with root
and boot zfs to one or two disks (mirrored) using either grub-pc or grub-efi to boot.

## image_partition_raw_gpt()

a partitioning function using cgpt to produce gpt partition table rather thanparted
parted to product dos partion table.

## blend_bootstrap_setup()

- Overide the post 'debootstrap stage 2' placeholder function of
  zlib/debootstrap bootstrap_complete_base.
- The default is return 0

## install-custdebs()

Override the helper function:

- takes the 'apt-get -f' out of the loop so that dependency provided by other
  debs can be resolved.
- inside the loop it just uninstalls the deb because of unfullfilled deps.

## install-deb-from-dsc() : WIP

- In the style of install-custdebs above but building from the source package
  using dsc
- takes a list of package names, looks up the corresponding dsc using it to
  build and install.

## install-deb-from-git_gbp() : WIP

- take a list of package names and for each select the appropriate salsa/devuangit
  git repo
- pull in sources, build using gbp
- place the resulting debs in the custdebs location.

## install-custscripts()

Added function:

- In the style of install-custdebs above but for a collection of arbitrary
  scripts placed in a
- directory alongside the blend custom debs called automate.
- The scripts are copied from the blends scripts directory ${blend_scripts}
  to $R/extra/custom-scripts in blend_preinst() above.
- Called after install-customdebs because some need checkinstall which
  disappears from archives.

## add-user()

Override the helper function:

- Allow an alternative skel directory

## enable_apt-proxy()

## disable_apt-proxy()

## bootstrap_cpio_unpack()

Overide the sdk version of this function to prevent deletion prior to unpackingthe
the cpio as we have mountpoints in place.

## image_partition_disk_zfs()

- partition available disks using sgdisk

## image_format_partitions_zfs()

- format the efi partions to fat32
- make the swap partitions
- create the zfs root and boot pools

## use_swap_partition()

- calls swapon on the new swap partitions

## image_zfs_mount()

- mounts the zfs pools to the bootstrap directory
- mounts the efi partition to the bootstrap /boot
- mounts dev proc and sys

## image_zfs_umount()

- the reverse of image_zfs_mount

## get_selections()

- gets dpkg selections and places three files in /var/tmp:
- /var/tmp/packages.list
- /var/tmp/pkgs_auto.lst
- /var/tmp/pkgs_manual.lst

## set_selections()

uses three files to replicate the installed packages of another system.

- /var/tmp/packages.list
- /var/tmp/pkgs_auto.lst
- /var/tmp/pkgs_manual.lst

## enablessh()

FIXME: currently changes /etc/ssh/ssh_config to allow password access.

Change this function will allow a root or user login in the bootstrapped
root using:

- ssh-copy-id <default@192.168.1.x>

## install_kernel_headers()

could go in blends/devuan-desktop-live/config $extra_packages and
remove headers in blends/devuan-desktop-live/chimaera/config $purge_packages

## install_zfs()

installs zfs and supporting packages and sets some parameters.

## install_grub()

installs grub related packages, configures and runs the appropriate grub for the
install type pc or efi.

---

arm64 spi, sd and mmc related, may duplicate functions of arm-sdk

## install_u-boot()

When installing to metal we will install the os plus grub as usual and
then boot grub from u-boot written to SPI.
u-boot gets build as a part of the board definition in arm-sdk. We add
zfs support there in case we wish to boot the kernel directly later.

<https://github.com/sigmaris/u-boot/wiki/RockPro64-boot-sequence>

The RK3399 Boot ROM will look for code with an ID block header for:
SPI flash at offset 0 bytes
eMMC at offset 0x8000 bytes (64 sectors, a sector is 0x200 bytes)
SDcard at offset 0x8000 bytes (64 sectors, a sector is 0x200 bytes)

this is where we write the idbloader.img (containing U-Boot TPL & SPL)

For SPI it must be written in rkspi format using the U-Boot mkimage tool.

## build_atf()

Builds the BL31.elf in $R/dist directory.

## build_uboot()

Builds u-boot for rockpro64 rk3399 in the $R/dist directory outputing u-boot-spl.bin
and rkspi_u-boot-spl.bin boot images and u-boot.itb

Uses the linux/scripts/config to change defconfig options.

## create_spi_image()

Create single SPI image called flash_spi.scr with u-boot.itb at 0x60000 in
$R/dist including the flash_spi.cmd, calls create-u-boot-spi-scripts()

## spi_flash_img()

Creates SD card image to flash u-boot to SPI using the result of
create_spi_image() as:
boot.scr
with:
spi_combined.img
idbloader.img
u-boot.itb
from $R/tmp/kernels/u-boot-rockpro64 to producing flash-spi.img.gz

## copy-kernel-config() override

extend the function to accept a kernel config name that includes a version
not just device_name

## copy-root-overlay() override

re-write fstab to use PARTUUID as kernel does not guarantee the order of
discovery and it is known to change between kernel versions.

We set boot*partuuid in image_partition_raw*${parted_type}

## set-bootloader()

Change SPI_LOADER to rksip or rksd depending on board. Called with
-rockchip-rockpro64- sets the variable SD_LOADER, SPI_LOADER and BOARD to
values consistant for the board, other boards: rock64, pinebookpro and rockpi4b

## bootloader-version()

FIXME
<https://stackoverflow.com/questions/5781738/getting-u-boots-version-from-userspace>

There's no defined way to do this. Once Linux boots, u-boot is no longer running
and it's RAM is reclaimed for Linux's use. Linux doesn't even know about u-boot.
Nor does it have to have been booted by u-boot.

If you really want to do this, the only way to do it is to add the u-boot version
to the kernel's command line, write code to scan the u-boot image in flash for
it's version, or if u-boot is still a mounted partition then you can extract this
info from it with strings.

u-boot-tools packages fw_printenv in debian returns ver:

fw_printenv just looks for the printenv partition and dumps its data. So it's OK
for normal variables, but it's not OK for the "ver" variable, which is dynamic,
and whose value is initialized by u-boot when it boots. The value of this variable
doesn't remain after u-boot exit, except if you manually save it to environment.

U-Boot > printenv ver
ver=U-Boot 2009.11-00393-g5ca9497-dirty (Nov 26 2012 - 11:08:44)

$ fw_printenv | grep ver=
ver=U-Boot 2009.11-00323-gbcc6e0e (Sep 21 2012 - 11:07:19)

U-Boot > saveenv

$ fw_printenv | grep ver=
ver=U-Boot 2009.11-00393-g5ca9497-dirty (Nov 26 2012 - 11:08:44)

So running the a u-boot script with saveenv prior to booting the kernel will set
the ver properly in /boot/uboot.env:

<https://stackoverflow.com/questions/67974867/fw-printenv-not-showing-env-variables-from-uboot-env>

Find uboot partition, eg. for MTD device:
$ cat /proc/mtd

For /dev/mtd5:

```bash
$ cat /dev/mtd5 | hexdump -C -n 64

$ strings /dev/mtd0 | grep 'U-Boot [0-9]_\.[0-9]_._\(Build._)'
U-Boot 1.1.4-g1c8343c8-dirty (Feb 28 2014 - 13:56:54)
U-Boot
Now running in RAM - U-Boot at: %08lx
```

If you know for a fact that it's in the first megabyte, you can use dd to
siphon off the first meg of data before you run strings on it to save yourself
processing time.

The current strings method used by bootloader-version() sets DEVICE /dev/mtdp6
and mtdp1 to p1, if we strings "$DEVICE" | grep -b "^U-Boot [a-z0-9.-]*$" we
can discover where the ver strings are located and use dd to select just that
area rather than the complete partition.

If u-boot is residing in an MTD partition then this will work:

```bash
U_BOOT_VER=$(for part in \
                $(grep u-boot-[01] /proc/mtd | cut -f 1 -d ':'); \
            do strings /dev/${part} | grep "^U-Boot.\*("; break;
            done
            )
```

## upgrade-sd-bootloader()

FIXME # Assumes a mounted efi partion # Writes the rksd image only to a specific
partition number on sd/mvme/sd/mmc devices.

/dev/mmcblk*p6|/dev/sd*p6|/dev/mapper/loop*p6|/dev/mapper/nvme*p6)

with p6 being changed to p1

## erase-sd-bootloader()

FIXME
Writes /dev/zero to the partition returned by findmnt /boot/efi

## write-emmc-flash()

We need to prevent writing on an emmc when it is the current boot device.
Both the sdcard and emmc enumerate as mmc. how to tell the difference
between emmc and sdcard:
sdcard in the rockpro enumerates as /dev/mmcblkx
emmc in the rockpro64 enumerates as /dev/mmcblkx
When booting from sdcard:
the card appears as /dev/mmcblk1 and
the emmc appears as /dev/mmcblk2
cat /sys/block/mmcblk2/device/type returns SD or MMC

We find the device mounted on / with findmnt and compare it to the enumerated
type, we only write when they are different.

## erase-spi-flash()

uses flash_erase from mtd-utils
expects:

FIXME
Assumes contents of spi labels, we don't have 'loader' so fails.

```bash
mtd0: 00060000 00001000 "u-boot-spl"
mtd1: 00398000 00001000 "u-boot"
mtd2: 00008000 00001000 "u-boot-env"
mtd3: 00c00000 00001000 "user"
```

## write-spi-flash()

FIXME

The fix: put the if test for partition label inside the private function
replacing the grep for loader with the proper disk label.
ie

```bash
mtd0: 00060000 00001000 "u-boot-spl" # mtd1: 00398000 00001000 "u-boot"
mtd2: 00008000 00001000 "u-boot-env" # mtd3: 00c00000 00001000 "user"
```

uses: flash_erase followed by nandwrite both from mtd-utils
has: a private function
expects: $1 $2 where:
$1 is ...
$2 is ...

## create-u-boot-menu()

FIXME
Need to choose a default and fix the other calls

```text
#zfs specific commands can be seen in the boot loader prompt using

# UBOOT #help
# zfsls - list files in a directory (default /)
# zfsload- load binary file from a ZFS file system

#2. To list the files in zfs pool, device or partition, execute
zfsls <interface> <dev[:part]> [POOL/@/dir/file]

# For example:
UBOOT #zfsls mmc 0:5 /rpool/@/usr/bin/

#3. To read and load a file from an ZFS formatted partition to RAM, execute
# zfsload <interface> <dev[:part]> [addr] [filename] [bytes]
# For example:
# UBOOT #zfsload mmc 2:2 0x30007fc0 /rpool/@/boot/uImage
```

## create-u-boot-spi-scripts()

Creates the following scripts to be included in a u-boot image:

```bash
$R/tmp/kernels/u-boot-rockpro64/scripts/erase_spi.cmd
$R/tmp/kernels/u-boot-rockpro64/scripts/flash-spi.cmd
$R/tmp/kernels/u-boot-rockpro64/scripts/load-spi-from-usb.cmd"
```

## create-rockpro64-scripts()

```bash
Creates the following scripts in /usr/local/sbin :
/usr/local/sbin/rockpro64_enable_eth_gadget.sh
/usr/local/sbin/rockpro64_disable_otg.sh
/usr/local/sbin/rockpro64_reset_emmc.sh
/usr/local/sbin/rockpro64_reset_spi_flash.sh
```
