diff options
Diffstat (limited to 'bootstrap')
-rwxr-xr-x | bootstrap | 399 |
1 files changed, 307 insertions, 92 deletions
@@ -4,12 +4,16 @@ # # Assumptions/expectations: # -# - host debootstrap/debian-archive-keyring matching release +# - Bootstrapping for the host CPU (currently x86_64 or aarch64). +# +# - Host debootstrap/debian-archive-keyring matching release. # # - /btrfs/<user> is a btrfs directory where the current user can create -# snapshots +# snapshots. +# +# - sudo is passwordless (used to run debootstrap, systemd-nspawn, etc). # -# - sudo is passwordless (used to run debootstrap, systemd-nspawn, etc) +# - This script is executed from the buildos/ source directory. # # Options: # @@ -19,19 +23,48 @@ # # 1 - bootstrap phase 1 # 2 - bootstrap phase 2 -# 3 - kernel build +# 3 - kernel build (and package patching, if necessary) # 4 - setup # 5 - create footfs # 6 - create kernel image and initrd # +# --arch-variant +# Architecture variant, for example, m1 for aarch64-m1. +# +# --kernel-source +# Pre-configured Linux kernel source .tar.* archive. If unspecified, Debian +# source/configuration will be used. +# +# --firmware +# Firmware .tar.* archive to be unpackged into /lib/firmware/. +# usage="usage: $0" -macaddr="de:ad:be:ef:b8:da" # @@ TMP mac address for testing. +owd="$(pwd)" +trap "{ cd '$owd'; exit 1; }" ERR +set -o errtrace # Trap in functions. + +function info () { echo "$*" 1>&2; } +function error () { info "$*"; exit 1; } id="$(id -un)" btrfs=/btrfs root="$btrfs/$id/buildos" +arch="$(uname -m)" + +case "$arch" in + x86_64) + debian_arch=amd64 + ;; + aarch64) + debian_arch=arm64 + ;; + *) + error "unsupported architecture: $arch" + ;; +esac + # Source distribution and packages. Base packages are installed on stage 1 via # debootstrap. Extra packages are added on stage 4 via apt-get install. The # idea is to be able to add extra packages without upgrading the base system. @@ -41,45 +74,63 @@ root="$btrfs/$id/buildos" # # - some packages (such as CPU microcode updates) are in non-free. # - systemd-container seems to be required by host systemd-nspawn. -# - not installing linux-image-amd64 since building custom below +# - must explicitly select between dbus and dbus-broker +# - not installing linux-image-* since building custom below # release="testing" components="main,contrib,non-free" -mirror="http://deb.debian.org/debian/" -#mirror="https://deb.debian.org/debian/" +mirror="http://http.us.debian.org/debian/" +#mirror="https://http.us.debian.org/debian/" -base_pkgs="locales,klibc-utils,sudo,systemd-container,udev" +base_pkgs="locales,klibc-utils,sudo" +base_pkgs+=",udev,dbus,systemd-timesyncd,systemd-container" base_pkgs+=",kmod,linux-base,firmware-linux-free,irqbalance" -base_pkgs+=",intel-microcode,amd64-microcode" -base_pkgs+=",pciutils,usbutils,dmidecode,cpuid" +base_pkgs+=",pciutils,usbutils,dmidecode" base_pkgs+=",hdparm,btrfs-progs" -base_pkgs+=",lm-sensors,smartmontools" +base_pkgs+=",lm-sensors,smartmontools,linux-cpupower" base_pkgs+=",psmisc" base_pkgs+=",net-tools,iproute2,iptables,isc-dhcp-client" -base_pkgs+=",ifupdown,bridge-utils,dnsmasq,ntp,postfix" +base_pkgs+=",ifupdown,bridge-utils,dnsmasq,postfix" base_pkgs+=",iputils-ping,wget,curl,ca-certificates" base_pkgs+=",openssh-client,openssh-server" base_pkgs+=",tftp-hpa,tftpd-hpa" -base_pkgs+=",bzip2,xz-utils" +base_pkgs+=",zstd,xz-utils" base_pkgs+=",less,nano,time" - -base_pkgs+=",qemu-kvm,qemu-utils,socat" - -base_pkgs+=",g++,make,pkg-config" - -extra_pkgs="" - -owd="$(pwd)" -trap "{ cd '$owd'; exit 1; }" ERR -set -o errtrace # Trap in functions. - -function info () { echo "$*" 1>&2; } -function error () { info "$*"; exit 1; } - -stage="1" -stage_max="6" +base_pkgs+=",g++,make" + +base_pkgs+=",qemu-utils,socat" + +case "$arch" in + x86_64) + base_pkgs+=",cpuid" + base_pkgs+=",intel-microcode" #,amd64-microcode + base_pkgs+=",qemu-system-x86" + ;; + aarch64) + base_pkgs+=",qemu-system-arm" + ;; +esac + +extra_pkgs="ethtool" + +case "$arch" in + x86_64) + #extra_pkgs+="" + ;; + aarch64) + extra_pkgs+=",ipxe-qemu" + ;; +esac + +# Options. +# +stage=1 +stage_max=6 +arch_variant= +kernel_source= +firmware= while [ "$#" -gt 0 ]; do case "$1" in @@ -88,6 +139,21 @@ while [ "$#" -gt 0 ]; do stage="$1" shift ;; + --arch-variant) + shift + arch_variant="$1" + shift + ;; + --kernel-source) + shift + kernel_source="$1" + shift + ;; + --firmware) + shift + firmware="$1" + shift + ;; -*) error "unknown option: $1" ;; @@ -101,6 +167,11 @@ if [ "$stage" -lt "1" -o "$stage" -gt "$stage_max" ]; then error "invalid stage number $stage" fi +arch_with_variant="$arch" +if [ -n "$arch_variant" ]; then + arch_with_variant="$arch_with_variant-$arch_variant" +fi + # Extract version. # version="$(sed -n -re 's/^version: ([0-9]+\.[0-9]+\.[0-9]+).*$/\1/p' ./manifest)" @@ -154,14 +225,28 @@ function nspawn () # <root> <systemd-nspawn-args> local r="$1" shift + # systemd-nspawn appears to carry over the root directory owner into the + # container which then causes other issues (Debian bug#950684). + # + # @@ Looking around didn't reveal any way (e.g., an option) to fix this. + # Perhaps newer systemd-nspawn does the right thing automatically? + # + ug="$(stat --format="%G:%U" "$r")" + sudo chown root:root "$r" + sudo systemd-nspawn --register=no -D "$r" "$@" - # systemd-nspawn may create the /var/lib/machines subvolume which prevents - # the deletion of the containing submodule. So we clean it up. + sudo chown "$ug" "$r" + + # systemd-nspawn may create the /var/lib/{machines,portables} subvolumes + # which prevents the deletion of the containing submodule. So we clean'em + # up. # - if sudo btrfs subvol show "$r/var/lib/machines" 1>/dev/null 2>&1; then - sudo btrfs subvol delete "$r/var/lib/machines" - fi + for s in /var/lib/machines /var/lib/portables; do + if sudo btrfs subvol show "$r$s" 1>/dev/null 2>&1; then + sudo btrfs subvol delete "$r$s" + fi + done } # (Over)write or append to a file in the installation root, for example: @@ -196,7 +281,7 @@ if [ "$stage" -eq "1" ]; then sudo debootstrap \ --foreign \ - --arch=amd64 \ + --arch="$debian_arch" \ --merged-usr \ --variant=minbase \ --components="$components" \ @@ -234,15 +319,24 @@ trap "exit 1" ERR set -x # Hack around systemd bug#79306 (changes /etc/localtime) by removing it now -# and making readonly below. +# and making readonly below. @@ See --timezone systemd-nspawn option? # rm /etc/localtime # Both nspawn and debootstrap try to mount /proc /sys (Debian bug#840372). # -mkdir /tmp/proc /tmp/sys -mount --move /proc /tmp/proc -mount --move /sys /tmp/sys +# @@ TMP this now causes issues with newer systemd. +# +#mkdir /tmp/proc /tmp/sys +#mount --move /proc /tmp/proc +#mount --move /sys /tmp/sys + +# systemd-nspawn "helpfully" creates a /lib64 symlink that then trips +# up is-usr-merged package (Debain bug #1019575). +# +if [ $arch = aarch64 ]; then + rm /lib64 +fi # Run second stage of debootstrap. # @@ -354,47 +448,162 @@ EOF # Create the kernel build snapshot, write the script that does the build # from within the installation and boot it up via systemd-nspawn --boot. # - # Add this line before shutdown if need to debug/check things. - # - # setsid /bin/bash -c "exec /bin/bash -i <>/dev/console 1>&0 2>&1" + # Add `bash` before shutdown if need to debug/check things. But note that it + # does not work well with `... | tee bootstrap.log`! # subvol_delete "$root-3-kernel" subvol_snapshot "$root" "$root-3-kernel" + # Copy custom kernel source. + # + if [ -n "$kernel_source" ]; then + sudo cp "$kernel_source" "$root-3-kernel/usr/src/" + fi + + # Copy patches. + # + #sudo cp ./patches/tftp-hpa-partial-upload.patch "$root-3-kernel/bootstrap/" + write <<EOF /bootstrap/setup "$root-3-kernel" #!/bin/bash trap "exit 1" ERR set -x +# Add deb-src to each deb entry in /etc/apt/sources.list. +# +sed -ri -e 's/^deb (.+)/deb \1\ndeb-src \1/' /etc/apt/sources.list + +apt-get update +apt-get install -y build-essential devscripts + +# Build custom/patched packages. +# +cd /usr/src + +if false; then +mkdir tftpd-hpa +cd tftpd-hpa +apt-get install -y libwrap0-dev +apt-get source tftpd-hpa +cd tftp-hpa-*/ +patch -p1 </bootstrap/tftp-hpa-partial-upload.patch +dch -n "Apply patches." +cd ../tftp-hpa-*/ # May get renamed. +dpkg-buildpackage -us -uc +cd ../.. +fi + +# Build kernel. +# # This seems to be the simplest method of building the standard Debian # kernel with adjusted configuration. Taken from the Debian Kernel Handbook. # apt-get update -apt-get install -y build-essential linux-source +apt-get install -y bc apt-get install -y bison flex apt-get install -y libelf-dev apt-get install -y libssl-dev +apt-get install -y cpio rsync +apt-get install -y dwarves +apt-get install -y device-tree-compiler + cd /usr/src -tar xf linux-source-* -mv linux-source-*/ linux -xzcat linux-config-*/config.amd64_none_amd64.xz >linux/.config + +if [ -z "$kernel_source" ]; then + apt-get install -y linux-source + tar xf linux-source-* + mv linux-source-*/ linux + xzcat linux-config-*/config.${debian_arch}_none_${debian_arch}.xz >linux/.config +else + kernel_source=\$(basename $kernel_source) + tar xf \$kernel_source + mv \$(sed -re 's/(.+)\.tar\..+/\1/' <<<\$kernel_source) linux +fi + cd linux # Adjust configuration. # -echo 'CONFIG_SYSTEM_TRUSTED_KEYS=""' >>.config -echo 'CONFIG_BUILD_SALT=""' >>.config -echo 'CONFIG_MODULE_SIG=n' >>.config +# Note that we do some of these even for the pre-configured kernel. +# +# Note that SECURITY_LOCKDOWN_LSM forces MODULE_SIG ('select' in Kconfig). +# +# Generally, if you disable an option but it still appears enabled after +# the kernel build, search for 'select XXX' in Kconfig* and also disable +# any found symbols. +# +scripts/config --disable KCSAN +scripts/config --disable SECURITY_LOCKDOWN_LSM +scripts/config --disable MODULE_SIG +scripts/config --set-str BUILD_SALT '' +scripts/config --set-str SYSTEM_TRUSTED_KEYS '' + +scripts/config --enable INIT_STACK_NONE +scripts/config --disable INIT_STACK_ALL_PATTERN +scripts/config --disable INIT_STACK_ALL_ZERO + +scripts/config --enable DEBUG_INFO_NONE +scripts/config --disable DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT + +# aarch64/5.19 additions: +# +scripts/config --disable KCOV +scripts/config --disable SHADOW_CALL_STACK +scripts/config --disable ZERO_CALL_USED_REGS +scripts/config --disable VIDEO_ADV7511 + +if [ -z "$kernel_source" ]; then + + # Disable sound subsystem/drivers. + # + sed -i -re '/^CONFIG_SND_.+/d' .config + sed -i -re '/^CONFIG_SOUND_.+/d' .config + scripts/config --disable CONFIG_SOUND + scripts/config --disable CONFIG_SND + + # Disable GPU subsystem/drivers. + # + # NOTE: this seems to have killed the high-resolution console. + # + sed -i -re '/^CONFIG_DRM_.+/d' .config + scripts/config --disable CONFIG_DRM + + # Disable wireless network drivers. + # + scripts/config --disable CONFIG_WLAN + +fi # Adjust kernel command line size limit. # -sed -i -re 's/^(#define COMMAND_LINE_SIZE ).+\$/\1 4096/' arch/x86/include/asm/setup.h +sed -i -re 's/^(#define COMMAND_LINE_SIZE).+\$/\1 4096/' arch/x86/include/asm/setup.h +sed -i -re 's/^(#define COMMAND_LINE_SIZE).+\$/\1 4096/' arch/arm64/include/uapi/asm/setup.h + +# Change certain network diagnostics from pr_info() to pr_debug() (otherwise +# to drowns out any useful diagnostics). +# +patch net/core/dev.c <<EOP +@@ -0 +0 @@ +- pr_info("device %s %s promiscuous mode\n", ++ pr_debug("device %s %s promiscuous mode\n", +EOP +patch net/bridge/br_stp.c <<EOP +@@ -0 +0 @@ +- br_info(p->br, "port %u(%s) entered %s state\n", ++ br_debug(p->br, "port %u(%s) entered %s state\n", +EOP +patch net/ipv6/addrconf.c <<EOP +@@ -0 +0 @@ +- pr_info("ADDRCONF(NETDEV_CHANGE): %s: link becomes ready\n", ++ pr_debug("ADDRCONF(NETDEV_CHANGE): %s: link becomes ready\n", +EOP + +#bash make oldconfig -scripts/config --disable DEBUG_INFO make clean -make deb-pkg LOCALVERSION=-buildos KDEB_PKGVERSION=1 -j 8 +make deb-pkg LOCALVERSION=-buildos KDEB_PKGVERSION=1-1 -j 8 # Clean up and shutdown. # @@ -406,8 +615,9 @@ EOF nspawn "$root-3-kernel" --boot - # Copy the kernel over and install it. + # Copy the kernel and packages over and install them. # + #sudo cp "$root-3-kernel/usr/src/tftpd-hpa/tftpd-hpa_"*.deb "$root/usr/src/" sudo cp "$root-3-kernel/usr/src/linux-image-"*.deb "$root/usr/src/" write <<EOF /bootstrap/setup @@ -416,7 +626,9 @@ EOF trap "exit 1" ERR set -x +#dpkg -i /usr/src/tftpd-hpa_*.deb dpkg -i /usr/src/linux-image-*.deb + rm -rf /usr/src/* cd / ln -s boot/vmlinuz-* /vmlinuz @@ -438,6 +650,12 @@ fi # if [ "$stage" -le "4" ]; then + # Copy custom firmware. + # + if [ -n "$firmware" ]; then + sudo cp "$firmware" "$root/usr/src/" + fi + # Write the setup script that will finish the setup (the service is already # there from stage 3). # @@ -454,6 +672,17 @@ for p in \$(sed -e 's/,/ /g' <<<"$extra_pkgs"); do apt-get install -y --no-install-recommends "\$p" done +# Install custom firmware. +# +if [ -n "$firmware" ]; then + firmware=\$(basename $firmware) + tar -C /lib/firmware -xf /usr/src/\$firmware +fi + +# Final /usr/src cleanup. +# +rm -rf /usr/src/* + # We want the utility (smartctl) but not the daemon. # systemctl disable smartd @@ -464,15 +693,21 @@ systemctl disable smartd # consistent across builds. # addgroup --gid 2000 build -adduser --uid 2000 --gid 2000 --home /build --gecos "" --disabled-password build +adduser --uid 2000 --ingroup build --home /build --gecos "" --disabled-password build adduser build kvm echo "build ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/build echo "Defaults:build !syslog" >>/etc/sudoers.d/build chmod 0440 /etc/sudoers.d/build -# Clean up package cache. +# Clean up package cache and fetched repository information. # apt-get clean +rm -rf /var/lib/apt/lists + +# Strip GCC executables (Debian bug #998841). Fixed but let's keep the command +# around in case it pops up again. +# +#strip \$(find /usr/lib/gcc -type f -executable) # Clean up /bootstrap. # @@ -502,15 +737,18 @@ if [ "$stage" -le "5" ]; then # Quite a few files/directories are only accessible by root (e.g., /root) so # we run under sudo. # + # Note also that without --check=crc32 the kernel will not be able to + # decompress things. + # root_dirs="build dev etc mnt root usr var" root_links="bin sbin lib lib32 lib64" - info "generating buildos-rootfs.cpio.gz..." + info "generating buildos-rootfs.cpio.xz..." cd "$root" sudo find $root_dirs $root_links -print0 | \ sudo cpio --null -o -H newc | \ - gzip -9 > "$owd/buildos-rootfs.cpio.gz" + xz -9 --check=crc32 >"$owd/buildos-rootfs.cpio.xz" cd "$owd" subvol_snapshot -r "$root" "$root-5" @@ -537,11 +775,16 @@ if [ "$stage" -le "6" ]; then sudo ln -sf "$root/usr/lib/systemd/system/buildos.service" \ "$root/etc/systemd/system/multi-user.target.wants/buildos.service" - info "generating buildos-init.cpio.gz..." + # Patch in the arch variant. + # + sudo sed -i -e "s/^arch_variant=.*/arch_variant=$arch_variant/" \ + "$root/usr/sbin/buildos" + + info "generating buildos-init.cpio.xz..." cd "$root" sudo cpio -o -H newc <<EOF | \ - gzip -9 > "$owd/buildos-init.cpio.gz" + xz -9 --check=crc32 >"$owd/buildos-init.cpio.xz" usr/lib/os-release init usr/sbin/buildos @@ -550,41 +793,13 @@ etc/systemd/system/multi-user.target.wants/buildos.service EOF cd "$owd" - cat buildos-rootfs.cpio.gz buildos-init.cpio.gz >buildos-initrd + cat buildos-rootfs.cpio.xz \ + buildos-init.cpio.xz >"buildos-initrd-$arch_with_variant" # Copy the kernel image next to the initramfs for convenience. # - cp "$root/vmlinuz" buildos-image - echo "$buildid" >buildos-buildid + cp "$root/vmlinuz" "buildos-image-$arch_with_variant" + echo "$buildid" >"buildos-buildid-$arch_with_variant" subvol_snapshot -r "$root" "$root-6" fi - -exit 0 - -# Test. -# -if [ ! -e /tmp/buildos-state ]; then - qemu-img create -f raw /tmp/buildos-state 20M -fi - -if [ ! -e /tmp/buildos-machines ]; then - qemu-img create -f raw /tmp/buildos-machines 100M -fi - -# To test PXE boot, replace -kernel/-initrd/-append with '-boot n'. -# -sudo kvm \ - -m 16G \ - -cpu host -smp "sockets=1,cores=4,threads=2" \ - -device "e1000,netdev=net0,mac=$macaddr" \ - -netdev "tap,id=net0,script=./qemu-ifup" \ - -device "virtio-scsi-pci,id=scsi" \ - -device "scsi-hd,drive=disk1" \ - -drive "if=none,id=disk1,file=/tmp/buildos-state,format=raw" \ - -device "scsi-hd,drive=disk2" \ - -drive "if=none,id=disk2,file=/tmp/buildos-machines,format=raw" \ - -boot n - -# -kernel buildos-image -initrd buildos-initrd \ -# -append "buildos.smtp_relay=build2.org buildos.admin_email=admin@build2.org" |