Boots into initramfs then switch_root
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,3 @@
|
|||||||
packages/
|
packages/
|
||||||
out/
|
out/
|
||||||
.swp
|
*.swp
|
||||||
|
|||||||
@@ -7,6 +7,14 @@ set -euo pipefail
|
|||||||
mkdir -p "$ROOTFS/var/cache/apk"
|
mkdir -p "$ROOTFS/var/cache/apk"
|
||||||
mkdir -p "$ROOTFS/opt/monok8s/config"
|
mkdir -p "$ROOTFS/opt/monok8s/config"
|
||||||
mkdir -p "$ROOTFS/build"
|
mkdir -p "$ROOTFS/build"
|
||||||
|
mkdir -p \
|
||||||
|
"$ROOTFS/dev" \
|
||||||
|
"$ROOTFS/proc" \
|
||||||
|
"$ROOTFS/sys" \
|
||||||
|
"$ROOTFS/run" \
|
||||||
|
"$ROOTFS/data" \
|
||||||
|
"$ROOTFS/var" \
|
||||||
|
"$ROOTFS/tmp"
|
||||||
|
|
||||||
mount --bind /var/cache/apk "$ROOTFS/var/cache/apk"
|
mount --bind /var/cache/apk "$ROOTFS/var/cache/apk"
|
||||||
mount --bind /dev "$ROOTFS/dev"
|
mount --bind /dev "$ROOTFS/dev"
|
||||||
@@ -72,6 +80,8 @@ mount "${TMP_LOOP}p4" /mnt/data
|
|||||||
|
|
||||||
# Put the real /var onto the data partition
|
# Put the real /var onto the data partition
|
||||||
cp -a "$ROOTFS/var" /mnt/data/
|
cp -a "$ROOTFS/var" /mnt/data/
|
||||||
|
mkdir -p /mnt/data/etc-overlay/work
|
||||||
|
mkdir -p /mnt/data/etc-overlay/upper
|
||||||
|
|
||||||
# Copy rootfs to root partition, but exclude /var
|
# Copy rootfs to root partition, but exclude /var
|
||||||
cp -a "$ROOTFS"/. /mnt/img-root/
|
cp -a "$ROOTFS"/. /mnt/img-root/
|
||||||
@@ -79,9 +89,7 @@ rm -rf /mnt/img-root/var
|
|||||||
mkdir -p /mnt/img-root/var
|
mkdir -p /mnt/img-root/var
|
||||||
|
|
||||||
mkdir -p /mnt/img-root/boot
|
mkdir -p /mnt/img-root/boot
|
||||||
cp /build/Image.gz /mnt/img-root/boot/Image.gz
|
|
||||||
cp /build/board.itb /mnt/img-root/boot/kernel.itb
|
cp /build/board.itb /mnt/img-root/boot/kernel.itb
|
||||||
cp /build/${DEVICE_TREE_TARGET}.dtb /mnt/img-root/boot/${DEVICE_TREE_TARGET}.dtb
|
|
||||||
|
|
||||||
sync
|
sync
|
||||||
umount /mnt/img-root
|
umount /mnt/img-root
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ cd /build
|
|||||||
echo "##################################################### Installing basic packages"
|
echo "##################################################### Installing basic packages"
|
||||||
apk add alpine-base \
|
apk add alpine-base \
|
||||||
openrc busybox-openrc bash nftables \
|
openrc busybox-openrc bash nftables \
|
||||||
lm-sensors lm-sensors-fancontrol lm-sensors-fancontrol-openrc
|
lm-sensors lm-sensors-fancontrol lm-sensors-fancontrol-openrc e2fsprogs
|
||||||
|
|
||||||
# For diagnotics
|
# For diagnotics
|
||||||
apk add \
|
apk add \
|
||||||
iproute2 iproute2-ss curl bind-tools procps strace tcpdump lsof jq \
|
iproute2 iproute2-ss curl bind-tools procps strace tcpdump lsof jq binutils \
|
||||||
openssl nftables conntrack-tools ethtool findmnt kmod coreutils util-linux
|
openssl nftables conntrack-tools ethtool findmnt kmod coreutils util-linux
|
||||||
echo '[ -x /bin/bash ] && exec /bin/bash -l' >> "/root/.profile"
|
echo '[ -x /bin/bash ] && exec /bin/bash -l' >> "/root/.profile"
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
PARTLABEL=config /opt/monok8s/config vfat defaults,noatime 0 0
|
PARTLABEL=config /opt/monok8s/config vfat defaults,noatime 0 0
|
||||||
PARTLABEL=data /data ext4 defaults,noatime 0 21
|
PARTLABEL=data /data ext4 rw,noatime,nodiratime 0 0
|
||||||
/data/var /var none rbind,noatime 0 0
|
|
||||||
|
/data/var /var none rbind 0 0
|
||||||
|
|
||||||
|
tmpfs /run tmpfs defaults,nosuid,nodev,mode=0755 0 0
|
||||||
|
tmpfs /tmp tmpfs defaults,nosuid,nodev,noexec,mode=1777 0 0
|
||||||
|
|||||||
16
alpine/rootfs-extra/etc/init.d/root.override
Executable file
16
alpine/rootfs-extra/etc/init.d/root.override
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/sbin/openrc-run
|
||||||
|
|
||||||
|
description="Keep root filesystem read-only for immutable boot"
|
||||||
|
|
||||||
|
depend()
|
||||||
|
{
|
||||||
|
after clock
|
||||||
|
need fsck
|
||||||
|
keyword -docker -podman -jail -lxc -openvz -prefix -systemd-nspawn -vserver -wsl
|
||||||
|
}
|
||||||
|
|
||||||
|
start()
|
||||||
|
{
|
||||||
|
ebegin "Keeping root filesystem read-only"
|
||||||
|
eend 0
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/dts-v1/;
|
/dts-v1/;
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
description = "LS1046A-RDB FIT Image";
|
description = "LS1046A-RDB-SDK FIT Image";
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
|
|
||||||
images {
|
images {
|
||||||
|
|||||||
@@ -18,8 +18,9 @@ ARCH=arm64
|
|||||||
|
|
||||||
CROSS_COMPILE=aarch64-linux-gnu-
|
CROSS_COMPILE=aarch64-linux-gnu-
|
||||||
|
|
||||||
# Busybox for initramfs
|
# Tools for initramfs
|
||||||
BUSYBOX_VERSION=1_36_1
|
BUSYBOX_VERSION=1_36_1
|
||||||
|
E2FSPROGS_VERSION=1.47.4
|
||||||
|
|
||||||
## Alpine Linux
|
## Alpine Linux
|
||||||
ALPINE_VER=3.23.3
|
ALPINE_VER=3.23.3
|
||||||
|
|||||||
@@ -25,6 +25,23 @@ RUN make ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} defconfig \
|
|||||||
RUN make CROSS_COMPILE=${CROSS_COMPILE} -j"$(nproc)"
|
RUN make CROSS_COMPILE=${CROSS_COMPILE} -j"$(nproc)"
|
||||||
RUN make CROSS_COMPILE=${CROSS_COMPILE} CONFIG_PREFIX=/out/initramfs install
|
RUN make CROSS_COMPILE=${CROSS_COMPILE} CONFIG_PREFIX=/out/initramfs install
|
||||||
|
|
||||||
|
ARG E2FSPROGS_VERSION
|
||||||
|
|
||||||
|
WORKDIR /build
|
||||||
|
COPY packages/e2fsprogs-v${E2FSPROGS_VERSION}.tar.gz ./
|
||||||
|
RUN tar -xf e2fsprogs-v${E2FSPROGS_VERSION}.tar.gz && mv "e2fsprogs-${E2FSPROGS_VERSION}" e2fsprogs
|
||||||
|
|
||||||
|
WORKDIR /build/e2fsprogs
|
||||||
|
|
||||||
|
RUN ./configure \
|
||||||
|
--host=aarch64-linux-gnu \
|
||||||
|
--prefix=/usr
|
||||||
|
RUN make -j"$(nproc)"
|
||||||
|
RUN make DESTDIR=/out/initramfs install
|
||||||
|
RUN mkdir -p /out/initramfs/lib \
|
||||||
|
&& cp /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 /out/initramfs/lib/ \
|
||||||
|
&& cp /usr/aarch64-linux-gnu/lib/libc.so.6 /out/initramfs/lib/
|
||||||
|
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
|
|
||||||
ARG BUILD_TAG
|
ARG BUILD_TAG
|
||||||
|
|||||||
@@ -3,10 +3,9 @@ Booting release image with bootusb
|
|||||||
```
|
```
|
||||||
setenv bootusb '
|
setenv bootusb '
|
||||||
usb start;
|
usb start;
|
||||||
setenv bootargs "console=ttyS0,115200 root=/dev/sda2 rw rootwait";
|
setenv kernel_addr_r 0xa0000000;
|
||||||
ext4load usb 0:2 ${kernel_addr_r} /boot/Image.gz;
|
ext4load usb 0:2 ${kernel_addr_r} /boot/kernel.itb;
|
||||||
ext4load usb 0:2 ${fdt_addr_r} /boot/mono-gateway-dk-sdk.dtb;
|
bootm ${kernel_addr_r};
|
||||||
booti ${kernel_addr_r} - ${fdt_addr_r}
|
|
||||||
'
|
'
|
||||||
|
|
||||||
run bootusb
|
run bootusb
|
||||||
|
|||||||
@@ -1,24 +1,114 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
mount -t devtmpfs devtmpfs /dev
|
log() {
|
||||||
mount -t proc proc /proc
|
echo "[init] $*" >&2
|
||||||
mount -t sysfs sysfs /sys
|
}
|
||||||
|
|
||||||
# Spin the fan
|
panic() {
|
||||||
echo 100 > /sys/class/hwmon/hwmon0/pwm1
|
echo "initramfs panic: $*" >&2
|
||||||
|
exec sh
|
||||||
|
}
|
||||||
|
|
||||||
|
mount_or_panic() {
|
||||||
|
mount "$@" || panic "mount failed: $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
mount_retry() {
|
||||||
|
dev="$1"
|
||||||
|
target="$2"
|
||||||
|
fstype="$3"
|
||||||
|
opts="$4"
|
||||||
|
|
||||||
|
i=0
|
||||||
|
while :; do
|
||||||
|
if mount -o "$opts" -t "$fstype" "$dev" "$target"; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
i=$((i + 1))
|
||||||
|
[ "$i" -ge 50 ] && panic "Timed out mounting $dev on $target"
|
||||||
|
sleep 0.2
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_path() {
|
||||||
|
path="$1"
|
||||||
|
i=0
|
||||||
|
while [ ! -e "$path" ]; do
|
||||||
|
i=$((i + 1))
|
||||||
|
[ "$i" -ge 50 ] && panic "Timed out waiting for $path"
|
||||||
|
sleep 0.2
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdir -p /dev /proc /sys /run
|
||||||
|
mount_or_panic -t devtmpfs devtmpfs /dev
|
||||||
|
mount_or_panic -t proc proc /proc
|
||||||
|
mount_or_panic -t sysfs sysfs /sys
|
||||||
|
mount_or_panic -t tmpfs tmpfs /run
|
||||||
|
|
||||||
|
echo 1 > /proc/sys/kernel/printk
|
||||||
|
|
||||||
# Optional but nice
|
|
||||||
mkdir -p /dev/pts
|
mkdir -p /dev/pts
|
||||||
mount -t devpts devpts /dev/pts
|
mount_or_panic -t devpts devpts /dev/pts
|
||||||
|
|
||||||
echo "Booting kernel took $(cut -d' ' -f1 /proc/uptime) seconds."
|
# Optional early fan kick. Do not fail boot if this path is not ready yet.
|
||||||
echo "Dropping to shell on ttyS0..."
|
if [ -w /sys/class/hwmon/hwmon0/pwm1 ]; then
|
||||||
|
echo 100 > /sys/class/hwmon/hwmon0/pwm1 || true
|
||||||
|
fi
|
||||||
|
|
||||||
. /etc/build-info
|
log "Booting kernel took $(cut -d' ' -f1 /proc/uptime) seconds."
|
||||||
|
|
||||||
while true; do
|
. /etc/build-info || panic "failed to source /etc/build-info"
|
||||||
setsid cttyhack /bin/sh
|
|
||||||
echo "Shell exited. Starting another one..."
|
ROOT_DEV=""
|
||||||
|
DATA_DEV=""
|
||||||
|
|
||||||
|
for arg in $(cat /proc/cmdline); do
|
||||||
|
case "$arg" in
|
||||||
|
root=*)
|
||||||
|
ROOT_DEV="${arg#root=}"
|
||||||
|
;;
|
||||||
|
data=*)
|
||||||
|
DATA_DEV="${arg#data=}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
exec poweroff -f
|
[ -n "$ROOT_DEV" ] || {
|
||||||
|
log "No root= specified in cmdline"
|
||||||
|
exec sh
|
||||||
|
}
|
||||||
|
|
||||||
|
[ -n "$DATA_DEV" ] || {
|
||||||
|
log "No data= specified in cmdline"
|
||||||
|
exec sh
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_path "$DATA_DEV"
|
||||||
|
|
||||||
|
e2fsck -p "$DATA_DEV" || {
|
||||||
|
echo "Auto fsck failed, forcing repair"
|
||||||
|
e2fsck -y "$DATA_DEV" || panic "fsck failed on $DATA_DEV"
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdir -p /newroot
|
||||||
|
mount_retry "$ROOT_DEV" /newroot ext4 ro
|
||||||
|
mount_retry "$DATA_DEV" /newroot/data ext4 rw
|
||||||
|
|
||||||
|
mount_or_panic --bind /newroot/data/var /newroot/var
|
||||||
|
|
||||||
|
mount_or_panic -t overlay overlay \
|
||||||
|
-o lowerdir=/newroot/etc,upperdir=/newroot/data/etc-overlay/upper,workdir=/newroot/data/etc-overlay/work \
|
||||||
|
/newroot/etc
|
||||||
|
|
||||||
|
mount_or_panic --move /dev /newroot/dev
|
||||||
|
mount_or_panic --move /proc /newroot/proc
|
||||||
|
mount_or_panic --move /sys /newroot/sys
|
||||||
|
mount_or_panic --move /run /newroot/run
|
||||||
|
|
||||||
|
log "Switching root to $ROOT_DEV"
|
||||||
|
exec switch_root /newroot /sbin/init
|
||||||
|
|
||||||
|
panic "switch_root returned unexpectedly"
|
||||||
|
|||||||
14
makefile
14
makefile
@@ -6,10 +6,11 @@ TAG ?= dev
|
|||||||
PACKAGES_DIR := packages
|
PACKAGES_DIR := packages
|
||||||
OUT_DIR := out
|
OUT_DIR := out
|
||||||
|
|
||||||
BUSYBOX_TAR := $(PACKAGES_DIR)/busybox-$(BUSYBOX_VERSION).tar.gz
|
E2FSPROGS_TAR := $(PACKAGES_DIR)/e2fsprogs-$(E2FSPROGS_VERSION).tar.gz
|
||||||
ALPINE_TAR := $(PACKAGES_DIR)/alpine-minirootfs-$(ALPINE_VER)-$(ALPINE_ARCH).tar.gz
|
BUSYBOX_TAR := $(PACKAGES_DIR)/busybox-$(BUSYBOX_VERSION).tar.gz
|
||||||
NXP_TAR := $(PACKAGES_DIR)/$(NXP_VERSION).tar.gz
|
ALPINE_TAR := $(PACKAGES_DIR)/alpine-minirootfs-$(ALPINE_VER)-$(ALPINE_ARCH).tar.gz
|
||||||
CRIO_TAR := $(PACKAGES_DIR)/$(CRIO_VERSION).tar.gz
|
NXP_TAR := $(PACKAGES_DIR)/$(NXP_VERSION).tar.gz
|
||||||
|
CRIO_TAR := $(PACKAGES_DIR)/$(CRIO_VERSION).tar.gz
|
||||||
|
|
||||||
# Kubernetes components
|
# Kubernetes components
|
||||||
KUBELET_BIN := $(PACKAGES_DIR)/kubernetes/kubelet
|
KUBELET_BIN := $(PACKAGES_DIR)/kubernetes/kubelet
|
||||||
@@ -62,6 +63,7 @@ KERNEL_DEPS := \
|
|||||||
INITRAMFS_DEPS := \
|
INITRAMFS_DEPS := \
|
||||||
$(KERNEL_IMAGE) \
|
$(KERNEL_IMAGE) \
|
||||||
$(BUSYBOX_TAR) \
|
$(BUSYBOX_TAR) \
|
||||||
|
$(E2FSPROGS_TAR) \
|
||||||
docker/initramfs.Dockerfile \
|
docker/initramfs.Dockerfile \
|
||||||
$(INITRAMFS_SRCS) \
|
$(INITRAMFS_SRCS) \
|
||||||
$(BUILD_INFO_FILE) \
|
$(BUILD_INFO_FILE) \
|
||||||
@@ -111,6 +113,9 @@ $(KUBECTL_BIN): | $(PACKAGES_DIR)
|
|||||||
$(BUSYBOX_TAR): | $(PACKAGES_DIR)
|
$(BUSYBOX_TAR): | $(PACKAGES_DIR)
|
||||||
curl -L -o $@ "https://github.com/mirror/busybox/archive/refs/tags/$(BUSYBOX_VERSION).tar.gz"
|
curl -L -o $@ "https://github.com/mirror/busybox/archive/refs/tags/$(BUSYBOX_VERSION).tar.gz"
|
||||||
|
|
||||||
|
$(E2FSPROGS_TAR): | $(PACKAGES_DIR)
|
||||||
|
curl -L -o $@ "https://github.com/tytso/e2fsprogs/archive/refs/tags/v$(E2FSPROGS_VERSION).tar.gz"
|
||||||
|
|
||||||
$(ALPINE_TAR): | $(PACKAGES_DIR)
|
$(ALPINE_TAR): | $(PACKAGES_DIR)
|
||||||
curl -L -o $@ "https://dl-cdn.alpinelinux.org/alpine/v$(ALPINE_SERIES)/releases/$(ALPINE_ARCH)/alpine-minirootfs-$(ALPINE_VER)-$(ALPINE_ARCH).tar.gz"
|
curl -L -o $@ "https://dl-cdn.alpinelinux.org/alpine/v$(ALPINE_SERIES)/releases/$(ALPINE_ARCH)/alpine-minirootfs-$(ALPINE_VER)-$(ALPINE_ARCH).tar.gz"
|
||||||
|
|
||||||
@@ -158,6 +163,7 @@ $(INITRAMFS): $(INITRAMFS_DEPS) | $(OUT_DIR)
|
|||||||
--build-arg ARCH=$(ARCH) \
|
--build-arg ARCH=$(ARCH) \
|
||||||
--build-arg CROSS_COMPILE=$(CROSS_COMPILE) \
|
--build-arg CROSS_COMPILE=$(CROSS_COMPILE) \
|
||||||
--build-arg BUSYBOX_VERSION=$(BUSYBOX_VERSION) \
|
--build-arg BUSYBOX_VERSION=$(BUSYBOX_VERSION) \
|
||||||
|
--build-arg E2FSPROGS_VERSION=$(E2FSPROGS_VERSION) \
|
||||||
--build-arg BUILD_TAG=$(BUILD_TAG) \
|
--build-arg BUILD_TAG=$(BUILD_TAG) \
|
||||||
--output type=local,dest=./$(OUT_DIR) .
|
--output type=local,dest=./$(OUT_DIR) .
|
||||||
test -f $@
|
test -f $@
|
||||||
|
|||||||
Reference in New Issue
Block a user