2020年12月13日日曜日

Lichee Pi Zeroのソフト開発環境構築3

br2-external を使ってカスタマイズファイルを分離する

Buildrootの設定とか、オレオレでやっていたのだけど、そろそろお作法に習ってやらないとあとでわからなくなりそうとおもった。

https://www.slideshare.net/linuxlab_conf/angelo-compagnucci-upgrading-buildroot-based-devices-with-swupdate
https://qiita.com/pu_ri/items/8cdef8f7bb79a2ea0863
https://titanwolf.org/Network/Articles/Article?AID=dee8991f-d9d6-4a55-86ec-a4d3598c4ba0#gsc.tab=0
https://buildroot.org/downloads/manual/manual.html

ファイル構成

上記の説明にならって以下のようにした。

ex_licheepizerodock$ tree
.
├── Config.in
├── board
│   ├── boot.cmd
│   ├── dts
│   │   └── sun8i-v3s-licheepi-zero-dock-with-lcd.dts
│   ├── genimage.cfg
│   └── rootfs-overlay
│       ├── etc
│       │   └── init.d
│       │       └── S99photoframe.app
│       ├── root
│       │   └── photo
│       │       ├── chihiro001.jpg
<略>
│       │       └── chihiro050.jpg
│       └── usr
│           └── share
│               └── X11
│                   └── xorg.conf.d
│                       └── 15-monitor.conf
├── configs
│   ├── licheepi_zero_custom_x_touch_backlight_ext_defconfig
│   └── licheepi_zero_custom_x_touch_defconfig
├── external.desc
└── external.mk

external.desc

あまり何も考えずに以下の感じで

name: LICHEEPI_ZERO_DOCK_EX
desc: LicheePi Zero Dock external tree.

br2-externalの有効化

make list-defconfigs BR2_EXTERNAL=./ex_licheepizerodock
make menuconfig

defconfigファイルの保存

make manuconfig
Location to save buildroot config
BR2_DEFCONFIG='$(BR2_EXTERNAL_LICHEEPI_ZERO_DOCK_EX_PATH)/configs/licheepi_zero_custom_x_touch_backlight_ext_defconfig'

rootfs-overlay

BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_LICHEEPI_ZERO_DOCK_EX_PATH)/board/rootfs-overlay"

boot.cmd

BR2_TARGET_UBOOT_BOOT_SCRIPT_SOURCE="$(BR2_EXTERNAL_LICHEEPI_ZERO_DOCK_EX_PATH)/board/boot.cmd"

genimage.cfg

BR2_ROOTFS_POST_SCRIPT_ARGS="-c $(BR2_EXTERNAL_LICHEEPI_ZERO_DOCK_EX_PATH)/board/genimage.cfg"

kernelの方のdtsファイル

BR2_LINUX_KERNEL_CUSTOM_DTS_PATH="$(BR2_EXTERNAL_LICHEEPI_ZERO_DOCK_EX_PATH)/board/dts/sun8i-v3s-licheepi-zero-dock-with-lcd.dts"

再構築

makeして、生成できていたらdefconfigを保存しておく

make
make savedefconfig

一度make cleanしてから、再生成してみる

make clean
make list-defconfigs BR2_EXTERNAL=./ex_licheepizerodock
make licheepi_zero_custom_x_touch_backlight_ext_defconfig
make

これで、buildrootのツリーを汚さずに済んだ!

SWupdateを使ってみる(試行錯誤)

ソフト書き換えのたびにSDカードの挿抜がやっぱり面倒になってきたので、
何か良い方法が無いか、バージョンアップのしくみを探していたら
buildrootのパッケージでswupdateというものがあった。

https://sbabic.github.io/swupdate/index.html
https://afterhourscoding.wordpress.com/2020/07/26/integrating-swupdate-with-u-boot/
https://bootlin.com/blog/tag/swupdate/
https://boundarydevices.com/using-swupdate-upgrade-system/

パーティションの準備

まずはrootfsを2つ用意する。いわゆる2面持ちをやってみる。
genimage.cfgを修正して、u-boot領域の拡張と、rootfs1、rootfs2を準備した。

#genimage.cfg
image boot.vfat {
	vfat {
		files = {
			"zImage",
			"sun8i-v3s-licheepi-zero-dock-with-lcd.dtb",
			"boot.scr"
		}
	}
	size = 8M
}

image sdcard.img {
	hdimage {
	}

	partition u-boot {
		in-partition-table = "no"
		image = "u-boot-sunxi-with-spl.bin"
		offset = 8192
		# size = 516096 # 512KB - 8192
        size = 679936 # 664K 32KB(SPL) + 504KB(Uboot) + Env(128KB)
	}

	partition boot {
		partition-type = 0xC
		bootable = "true"
		image = "boot.vfat"
	}

	partition rootfs1 {
		partition-type = 0x83
		image = "rootfs.ext4"
		size = 200M
	}
	partition rootfs2 {
		partition-type = 0x83
		size = 200M
	}
}

これで、以下のようになったはず。

No 開始 サイズ 用途
0 0 8K 未使用のはず
1 8K 664K 32KB(SPL) + 504KB(Uboot) + Env(128KB)
2 672K 8M boot
3 - 200M rootfs1
4 - 200M rootfs2

未使用のはず:https://linux-sunxi.org/Bootable_SD_card#SD_Card_Layout

fw_setenv

linux側からu-boot環境変数の参照と書き換えをしたい。
fw_setenvとfw_printenvというのがあるらしい。

BR2_PACKAGE_UBOOT_TOOLS=y

を有効にしてmakeする

fw_setenv test 1
Cannot parse config file '/etc/fw_env.config': No such file or directory
Error: environment not initialized

/etc/fw_env.configが必要みたいなので、用意する。

cat /etc/fw_env.config
# device name   Device offset   Env. size
/dev/mmcblk0    0x88000 0x20000

記載内容は、デバイス名、開始アドレス、範囲というもので
dl/uboot/git/include/configs に対応させるみたい。
さっきのパーティションとも一致しているね(8k+32k+504k=554k)

#define CONFIG_ENV_OFFSET (544 << 10) /* (8 + 24 + 512) KiB /
#define CONFIG_ENV_SIZE (128 << 10) /
128 KiB */

これで、再度fw_setenvを実行してみる。

# fw_setenv test 1
Warning: Bad CRC, using default environment
# fw_printenv
bootcmd=bootp; setenv bootargs root=/dev/nfs nfsroot=${serverip}:${rootpath} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off; bootm
bootdelay=5
baudrate=115200
test=1

boot.scrを手動で作る

u-boot起動時に、rootfsを切り替えれるようにboot.scrを変更したい。
boot.scrだけちょいと変更できるようにしたい。
mkimageが欲しいので、u-boot-toolsをインストール

https://afterhourscoding.wordpress.com/2020/07/26/integrating-swupdate-with-u-boot/
を参考に、boot.cmdを変更する

echo -------------------- checking rootfspart ----------
if printenv rootfspart; 
    then echo rootfspart found; 
    else echo rootfspart not found; setenv rootfspart 2; setenv modify_save 1; 
fi

setenv bootargs console=ttyS0,115200 panic=5 console=tty0 rootwait root=/dev/mmcblk0p${rootfspart} earlyprintk rw
load mmc 0:1 0x41000000 zImage
load mmc 0:1 0x41800000 sun8i-v3s-licheepi-zero-dock-with-lcd.dtb

# echo -------------------- printenv --------------------
# printenv
# echo wait 10 sec ...
# sleep 10

echo -------------------- checking modify_save flag -------------------- 
if printenv modify_save; 
    then; 
        if test "${modify_save}" = "1"; 
            then echo modify_save is on.; setenv modify_save 0; saveenv; 
            else echo modify_save is off.;
        fi; 
    else echo modify_save is not found.; 
fi

bootz 0x41000000 - 0x41800000

保存先のディレクトリにて

cd ex_licheepizerodock/board
mkimage -A arm -O linux -T script -C none -n "U-Boot script" -d boot.cmd boot.scr

生成されたboot.scrをoutput/imageにコピーしてmakeする

これで、rootfspartをfw_setenv変更することで、rootfsの場所を変更することができるようになった。

sw-descriptionの準備

rootfsのフォーマット変更

sw-descriptionのサンプルに合わせて、ファイルをgzで圧縮する

BR2_TARGET_ROOTFS_EXT2_GZIP=y

genimage.cfgの修正

(省略)
	partition rootfs1 {
		partition-type = 0x83
		image = "rootfs.ext2"
		size = 200M
	}
(省略)

sw-descriptionの作成

software =
{
    version = "2.3.0";

    mylinuxboard = {
        hardware-compatibility: [ "1.0" ];
        rootfs1: {
            images: (
                {
                    filename = "rootfs.ext2.gz";
                    compressed = "zlib";
                    installed-directly = true;
                    device = "/dev/mmcblk0p2";
                }
            );
            bootenv: (
                {
                    name = "rootfspart";
                    value = "2";
                }
            );
        }
        rootfs2: {
            images: (
                {
                    filename = "rootfs.ext2.gz";
                    compressed = "zlib";
                    installed-directly = true;
                    device = "/dev/mmcblk0p3";
                }
            );
            bootenv: (
                {
                    name = "rootfspart";
                    value = "3";
                }
            );
        }
    }
}

swuアーカイブを作成する

今回は手動で、swuを作成する。今後はmake時に自動で実行するようにしたい

#!/bin/bash

TARGET_DIR=../output/images/
cp sw-description ${TARGET_DIR}
cd ${TARGET_DIR}

CONTAINER_VER="1.0.0"
PRODUCT_NAME="my-software"
FILES="sw-description rootfs.ext2.gz"

for i in $FILES;do 
    echo $i;done | cpio -ov -H crc > ${PRODUCT_NAME}_${CONTAINER_VER}.swu

これで、imagesディレクトリにswuファイルが作成される。

実行してみる

swupdate -v -e mylinuxboard,rootfs2 -i /mnt/my-software_1.0.0.swu 
Swupdate v2020.04.0

Licensed under GPLv2. See source distribution for detailed copyright notices.

Registered handlers:
	dummy
	raw
	rawfile
	rawcopy
software set: mylinuxboard mode: rootfs2
[TRACE] : SWUPDATE running :  [listener_create] : creating socket at /tmp/swupdateprog
[TRACE] : SWUPDATE running :  [network_initializer] : Main loop Daemon
[TRACE] : SWUPDATE running :  [extract_sw_description] : Found file:
	filename sw-description
	size 982
	checksum 0xd385 VERIFIED
[TRACE] : SWUPDATE running :  [get_common_fields] : Version 2.3.0
[TRACE] : SWUPDATE running :  [parse_images] : Found compressed Image: rootfs.ext2.gz in device : /dev/mmcblk0p3 for handler raw (installed from stream)
[TRACE] : SWUPDATE running :  [parse_bootloader] : Bootloader var: rootfspart = 3
[ERROR] : SWUPDATE failed [0] ERROR core/parser.c : parse : 282 : bootloader support absent but sw-description has bootloader section!
[ERROR] : SWUPDATE failed [0] ERROR core/swupdate.c : install_from_file : 335 : failed to parse sw-description!

make swupdate-menuconfig

にて

HAVE_LIBUBOOTENV
を有効化する

# swupdate -v -e mylinuxboard,rootfs2 -i /mnt/my-software_1.0.0.swu
Swupdate v2020.04.0

Licensed under GPLv2. See source distribution for detailed copyright notices.

Registered handlers:
	dummy
	uboot
	bootloader
	raw
	rawfile
	rawcopy
software set: mylinuxboard mode: rootfs2
[TRACE] : SWUPDATE running :  [listener_create] : creating socket at /tmp/swupdateprog
[TRACE] : SWUPDATE running :  [network_initializer] : Main loop Daemon
[TRACE] : SWUPDATE running :  [listener_create] : creating socket at /tmp/sockinstctrl
[TRACE] : SWUPDATE running :  [extract_sw_description] : Found file:
	filename sw-description
	size 982
	checksum 0xd385 VERIFIED
[TRACE] : SWUPDATE running :  [get_common_fields] : Version 2.3.0
[TRACE] : SWUPDATE running :  [parse_images] : Found compressed Image: rootfs.ext2.gz in device : /dev/mmcblk0p3 for handler raw (installed from stream)
[TRACE] : SWUPDATE running :  [parse_bootloader] : Bootloader var: rootfspart = 3
[TRACE] : SWUPDATE running :  [cpio_scan] : Found file:
	filename rootfs.ext2.gz
	size 29270917
	REQUIRED
[DEBUG] : SWUPDATE running :  [preupdatecmd] : Running Pre-update command
[TRACE] : SWUPDATE running :  [install_single_image] : Found installer for stream rootfs.ext2.gz raw
Software updated successfully
Please reboot the device to start the new software
[INFO ] : SWUPDATE successful ! 
[DEBUG] : SWUPDATE running :  [postupdate] : Running Post-update command

念の為 fw_printenv rootfspart で確認するとrootfspart = 3となっていた。
再起動すると、p3にて起動した!やった。

swupdate-configの保存

このままだと、make cleanしたときに消えてしまうので
configを外部ツリーに移動させる

BR2_PACKAGE_SWUPDATE_CONFIG="$(BR2_EXTERNAL_LICHEEPI_ZERO_DOCK_EX_PATH)/board/package/swupdate/swupdate.config"

また、swupdateの設定変更をした後は

make swupdate-update-config
  cp -f output/build/swupdate-2020.04/.config ex_licheepizerodock/board/package/swupdate/swupdate.config