Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LS104x] ostree制作sd卡 #196

Open
carloscn opened this issue Oct 19, 2023 · 0 comments
Open

[LS104x] ostree制作sd卡 #196

carloscn opened this issue Oct 19, 2023 · 0 comments

Comments

@carloscn
Copy link
Owner

carloscn commented Oct 19, 2023

1. 服务器端配置

本文使用HTTP而不是HTTPS,并且服务器使用本机HOST局域网更新。

1.1 仓库配置

  • 需要进行ostree仓库的初始化
  • 需要在ostree仓库中增加busybox的rootfs文件
  • 对rootfs文件进行部署标准化改造
  • 需要commit仓库变化
  • 需要生成summary文件
  • 需要启动服务器监听程序

创建初始化仓库:

mkdir -p repo && ostree --repo=repo init --mode=archive-z2 && mkdir -p rootfs

  • rootfs文件为存放busybox rootfs文件的路径;
  • repo文件夹为仓库的配置文件;

1.1.1 rootfs改造

需要把rootfs下面根目录的etc转移到/usr/下面:

The deployment should not have a traditional UNIX /etc; instead, it should include /usr/etc. This is the “default configuration”. When OSTree creates a deployment, it performs a 3-way merge using the old default configuration, the active system’s /etc, and the new default configuration. In the final filesystem tree for a deployment then, /etc is a regular writable directory.
https://ostreedev.github.io/ostree/deployment/

1.1.2 kernel文件

除此之外,还需要创建kernel、devicetree和initramfs的文件到下面的文件路径:

命名规则如下所示:

Note,不要使用软链接符号。

没有以上两步,ostree无法在板子上部署

1.2 仓库上传

可能有的需要sudo命令:

ostree --repo=repo commit --branch=master --subject="image v1 (ls104x) rootfs)" rootfs

不需要sudo:

ostree log master --repo=repo

ostree summary --repo=repo ./repo/branch.summary -u

使用服务器监听repo:

python3 -m http.server 8000 --bind 10.10.192.121 --directory repo

2. 客户端配置(板级)

2.1 初始化版本的rootfs

部署ostree的SD卡是在Host Linux完成。挂载SD卡:

准备一个空的rootfs,格式化通过:

sudo mkfs.ext4 -L "rootfs" -b 4096 /dev/sda3

SD卡会在host的linux生成rootfs文件夹:

2.2 部署ostree

部署之前请检查你的板子:

  • 联网功能(包括ip是否正确)
  • 时间正确
  • 足够的空间

2.2.1 创建标准的sysroot

初始化一个标准的sysroot文件夹:

sudo ostree admin init-fs rootfs

此时会生成一个最小的rootfs,这个rootfs的作用是支持initramfs的最小启动,而不是真正的rootfs。

在这个rootfs创建一个newroot文件夹,作为initramfs挂载真正rootfs的根文件夹和mnt文件夹,并创建update文件,作为initramfs检测update的标志。

sudo mkdir -p rootfs/newroot && sudo mkdir -p rootfs/mnt && sudo touch rootfs/update

最后的rootfs格式应该是:

2.2.2 增加远程repo

给仓库增加

sudo ostree remote add --repo=./rootfs/ostree/repo --no-gpg-verify origin http://10.10.192.121:8000/

从远程仓库拉去数据:

sudo ostree pull --repo=./rootfs/ostree/repo origin:master

sync

sudo ostree log --repo=./rootfs/ostree/repo origin:master

2.2.3 部署仓库

创建操作系统,本文叫做tcu:

sudo ostree admin os-init tcu --sysroot=rootfs

Note,如果不创建该操作系统,而是在deploy文件夹手动创建tcu的文件夹,selinux检查会不通过的。报错为:# SELinux relabel /var 参考 ostreedev/ostree#872

部署tcu系统到rootfs

sudo ostree admin --sysroot=rootfs --os=tcu deploy origin:master

查看部署情况: sudo ostree admin --sysroot=rootfs status

部署之后的文件:

./rootfs/ostree/deploy/tcu/deploy目录就可以看到。

upgrade:

sudo ostree admin --sysroot=rootfs --os=tcu upgrade

通过这个命令,可以看到,ostree把最新的部署rootfs中的etc从/usr/etc拿了出来:

之后可以通过一些脚本,在部署完成之后,拿到rootfs的地址,然后在ramdisk里面配合一些脚本解析进行切换。

2.2.4 ramdisk脚本

prepare-root

ostree提供了prepare-root的工具,主要功能参考: https://ostreedev.github.io/ostree/man/ostree-prepare-root.html 大致意思为,切换部署的sysroot里面。

这部分程序是:

https://github.com/ostreedev/ostree/blob/v2018.8/src/switchroot/ostree-prepare-root.c

其开发成为一个单独的工具,可以很简单的进行交叉编译。

https://github.com/carloscn/ls104x-bsp/tree/master/initramfs/prepare_root

#!/bin/sh
set -eu

# -------------------------------------------

log_info() { echo "[INFO] $0[$$]: $*" >&2; }
log_error() { echo "[ERR] $0[$$]: ERROR $*" >&2; }

do_mount_fs() {
	log_info "mounting FS: $*"
	[[ -e /proc/filesystems ]] && { grep -q "$1" /proc/filesystems || { log_error "Unknown filesystem"; return 1; } }
	[[ -d "$2" ]] || mkdir -p "$2"
	[[ -e /proc/mounts ]] && { grep -q -e "^$1 $2 $1" /proc/mounts && { log_info "$2 ($1) already mounted"; return 0; } }
	mount -t "$1" "$1" "$2"
}

bail_out() {
	log_error "$@"
	log_info "Rebooting..."
	#exec reboot -f
	exec sh
}

get_ostree_sysroot() {
	for opt in $(cat /proc/cmdline); do
		arg=$(echo "$opt" | cut -d'=' -f1)
		if [ "$arg" == "ostree_root" ]; then
			echo "$opt" | cut -d'=' -f2-
			return
		fi
	done
	echo "LABEL=otaroot"
}

export PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/lib/ostree

log_info "Starting OSTree initrd script"

do_mount_fs proc /proc
do_mount_fs sysfs /sys
do_mount_fs devtmpfs /dev
do_mount_fs devpts /dev/pts
do_mount_fs tmpfs /dev/shm
do_mount_fs tmpfs /run

# check if smack is active (and if so, mount smackfs)
grep -q smackfs /proc/filesystems && {
	do_mount_fs smackfs /sys/fs/smackfs

adjust current label and network label
	echo System >/proc/self/attr/current
	echo System >/sys/fs/smackfs/ambient
}

MOUNT_R=/sysroot
mkdir -p ${MOUNT_R}
ostree_sysroot=$(get_ostree_sysroot)

mount "$ostree_sysroot" ${MOUNT_R} || {
        log_info "Retry the mount if it fails the first time"
	log_info "Mounting $ostree_sysroot failed, waiting 5s for the device to be available..."
	sleep 5
	mount "$ostree_sysroot" ${MOUNT_R} || bail_out "Unable to mount $ostree_sysroot as physical sysroot"
}

ls ${MOUNT_R}
if [ $? -ne 0 ];then
    bail_out "No ${MOUNT_R} directory!! reboot device!"
fi

/usr/bin/ostree-prepare-root ${MOUNT_R}

log_info "exec /bin/busybox switch_root ${MOUNT_R} /sbin/init"
exec switch_root ${MOUNT_R} /sbin/init
sleep 1
bail_out "Failed to switch_root to ${MOUNT_R}"

同时uboot的env也需要配置,ramdisk会从uboot提取deploy部署的路径:

setenv bootargs "earlycon=uart8250,mmio,0x21c0500 console=ttyS0,115200 root=/dev/ram0 rw rootfstype=ext4 rootwait rootdelay=2 ostree=ostree/boot.0/tcu/0fe7a1e6cd1c37a4d82bbb83633d0bf6ecb8b8ec2b6131a32059549244582dd6/0 ostree_root=/dev/mmcblk0p3"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant