#!/bin/bash -xe PS4='+ ($LINENO) ' # To ease debugging VERSION="1.0" # Config # ########## WORKDIR=./work # Must not be with "nodev" mount option DLDIR=./downloads OUTDIR=./out OUTUSB=/dev/sdb # Will wreck everything here ! LEGACY=n # make USB bootable key compatible with non UEFI-BIOS DEVEL_MODE=n # Adds debugging tools in the generated image ROOTCMD=sudo WGET="wget" # "wget --no-check-certificate" could help but is a security concern KERNEL_TARBALL_URL=https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.9.39.tar.xz KCONFIGLIB_MAIN_URL=https://raw.githubusercontent.com/ulfalizer/Kconfiglib/7eace27993ad3aa1d6911866d9c60a11f32d36d9/kconfiglib.py KCONFIGLIB_PATCH_URL=https://raw.githubusercontent.com/ulfalizer/Kconfiglib/7eace27993ad3aa1d6911866d9c60a11f32d36d9/makefile.patch NIC_FIRMWARE_URL=http://fr.archive.ubuntu.com/ubuntu/pool/main/l/linux-firmware/nic-firmware_1.165_all.udeb BUSYBOX_BIN_URL=https://busybox.net/downloads/binaries/1.26.2-defconfig-multiarch/busybox-x86_64 PCI_IDS_URL=https://pci-ids.ucw.cz/v2.2/pci.ids USB_IDS_URL=https://usb-ids.gowdy.us/usb.ids # Utilities # ############# function add_initrd_script { ( echo "#!/bin/busybox sh" ; cat ) > "$WORKDIR/initrd/$1" chmod +x "$WORKDIR/initrd/$1" } # From https://landley.net/writing/rootfs-programming.html # Its first argument is the new directory, and the rest of its arguments are executables to copy. function mkchroot { [ $# -lt 2 ] && return 0 dest=$1 shift for i in "$@" do # Get an absolute path for the file p=$i [ "${p:0:1}" == "/" ] || p=$(which $i) || true if [ ! -e "$p" ] then echo "mkchoot not found: $i" return 1 fi # Skip files that already exist at target. [ -f "$dest/$p" ] && continue # Create destination path d=$(echo "$p" | grep -o '.*/') && mkdir -p "$dest/$d" && # Copy file echo + cp --dereference --preserve=all "$p" "$dest/$p" && cp --dereference --preserve=all "$p" "$dest/$p" && # Recursively copy shared libraries' shared libraries. mkchroot "$dest" $(ldd "$p" | egrep -o '/.* ') || return $? done } # Environement and dependencies # ################################# codename=$(lsb_release -sc || true) if [ "x$codename" != "xjessie" ] then cat >&2 < "$WORKDIR/apt-done" fi # Kernel build setup # ###################### kernel_tarball=$DLDIR/$(basename $KERNEL_TARBALL_URL) [ -f "$kernel_tarball" ] || $WGET -O "$kernel_tarball" "$KERNEL_TARBALL_URL" if [ ! -d "$WORKDIR/kernel" ] then mkdir "$WORKDIR/kernel" tar xf "$kernel_tarball" --strip-components=1 -C "$WORKDIR/kernel" fi if [ ! -d "$WORKDIR/kernel/scripts/Kconfiglib" ] then [ -f "$DLDIR/kconfiglib.py" ] || $WGET -O "$DLDIR/kconfiglib.py" "$KCONFIGLIB_MAIN_URL" [ -f "$DLDIR/makefile.patch" ] || $WGET -O "$DLDIR/makefile.patch" "$KCONFIGLIB_PATCH_URL" mkdir "$WORKDIR/kernel/scripts/Kconfiglib" cp "$DLDIR/kconfiglib.py" "$WORKDIR/kernel/scripts/Kconfiglib/kconfiglib.py" patch -t -p1 -d "$WORKDIR/kernel" < "$DLDIR/makefile.patch" fi cat >"$WORKDIR/kernel/scripts/Kconfiglib/customize.py" <<"EOT" #!/usr/bin/env python import kconfiglib import sys def sset(sym, value=None): if not sym.is_modifiable(): print("%s is not modifiable at all"%(sym.get_name())) return True if value is None and sym.get_type() in [ kconfiglib.BOOL, kconfiglib.TRISTATE ]: value = sym.get_upper_bound() old_value = sym.get_value() if old_value == value: return False print("CONFIG_%s=%s [was: %s]"%(sym.get_name(),value,old_value)) sym.set_user_value(value) return True debug = '--debug' in sys.argv; conf = kconfiglib.Config(sys.argv[1]) conf.load_config('.config') support_xz = conf['KERNEL_XZ'] is not None menu_netfs = conf['NETWORK_FILESYSTEMS'] i = 0 more_work = True while more_work and i < 10: more_work = False i += 1 print("Kconfiglib/customize.py pass %i"%i) for sym in conf.get_symbols(): name = sym.get_name() # Default hostname is (none) and could make FreeBSD's dhcpd complain because unallowed '()' if name in ['DEFAULT_HOSTNAME']: more_work = sset(sym, 'eficast') or more_work # Embed initrd in the EFI bootable kernel if name in ['INITRAMFS_SOURCE']: more_work = sset(sym, '../initrd/') or more_work # Make kernel directly loadable by EFI, add USB3, Dell flash if name in ['EFI_STUB', 'EFI_VARS', 'DELL_RBU', 'USB_XHCI_HCD', 'IKCONFIG']: more_work = sset(sym) or more_work # Support FUSE for ntfs-3g if name in ['FUSE_FS']: more_work = sset(sym) or more_work # Support soft RAID (linux) and hard RAID (some cards) if name in ['DM_RAID', 'SCSI_LOWLEVEL', 'MEGARAID_SAS', 'MEGARAID_NEWGEN']: more_work = sset(sym) or more_work # If --debug passed as arg, make kernel aware of virtual drivers (used for testing eficast on qemu/kvm) if debug and name in ['VIRTIO_PCI', 'VIRTIO_MMIO', 'VIRTIO_NET', 'VIRTIO_BLK', 'SCSI_LOWLEVEL', 'SCSI_VIRTIO']: more_work = sset(sym) or more_work # Disable all Network Filesystems support except after-boot NFSv3 client if name not in ['NET_FS', 'NFS_V3'] and menu_netfs in sym.get_referenced_symbols(): more_work = sset(sym, 'n') or more_work # Disable thing that are unneeded or annoying for the purpose of disk cloning if name in ['LOGO', 'SUSPEND', 'HIBERNATION', 'CPU_FREQ', 'PCCARD', 'HAMRADIO', 'WIRELESS', 'RFKILL', 'WLAN', 'SOUND', 'NFS_V2', 'NFS_V4', 'ROOT_NFS', 'SECURITY', 'VIRTUALIZATION']: more_work = sset(sym, 'n') or more_work # Compress everything with XZ if available (slower, smaller) if support_xz: if name in ['KERNEL_XZ']: more_work = sset(sym, 'y') or more_work if name in ['RD_GZIP', 'RD_BZIP2', 'RD_LZMA', 'RD_LZO', 'RD_LZ4']: more_work = sset(sym, 'n') or more_work # Following generic actions are meant for features, not choices if not sym.is_choice_symbol(): # Build all available net/ethernet drivers if sym.is_modifiable() and sym.get_type() in [ kconfiglib.BOOL, kconfiglib.TRISTATE ] \ and True in [ ('drivers/net/ethernet' in filename) for (filename,_) in sym.get_def_locations() ]: more_work = sset(sym) or more_work # Try to get everything in kernel, not as a module if sym.get_value() == 'm' and sym.get_upper_bound() == 'y': more_work = sset(sym, 'y') or more_work if i == 10: print("ERROR : can't set some of kernel config symbols after 10 passes") sys.exit(1) else: sys.exit( conf.write_config(".config") ) EOT chmod +x "$WORKDIR/kernel/scripts/Kconfiglib/customize.py" # Kernel prepare + make tools # ############################### ( cd "$WORKDIR/kernel" if [ ! -f .config ] then make defconfig if [ "x$DEVEL_MODE" == "xy" ] then extra="SCRIPT_ARG=--debug" else extra="" fi make scriptconfig SCRIPT=scripts/Kconfiglib/customize.py $extra fi ) p="$WORKDIR/kernel/tools/perf/perf" if [ "x$DEVEL_MODE" == "xy" -a ! -f "$p" ] then ( cd "$WORKDIR/kernel" make tools/perf ) fi # Initial Ram Disk building (embed in kernel) # ############################################### if [ ! -d "$WORKDIR/initrd" ] then mkdir -p "$WORKDIR/initrd/"{bin,dev,etc/rc.d,mnt/nfs,root,proc,root,sbin,sys,run/lock,run,tmp,usr/share/udhcpc,var/log} $ROOTCMD cp -a /dev/{null,console,tty1} "$WORKDIR/initrd/dev/" $ROOTCMD chmod 1777 "$WORKDIR/initrd/run/lock" ln -s "/proc/mounts" "$WORKDIR/initrd/etc/mtab" ln -s "../run" "$WORKDIR/initrd/var/run" ln -s "../run/lock" "$WORKDIR/initrd/var/lock" fi # XXX workaround, kernel makefile's cpio preseves everything and it is not so cool for us $ROOTCMD chown -R $USER: "$WORKDIR/initrd" if [ ! -f "$WORKDIR/initrd/bin/busybox" ] then [ -f "$DLDIR/busybox" ] || $WGET -O "$DLDIR/busybox" "$BUSYBOX_BIN_URL" cp -a "$DLDIR/busybox" "$WORKDIR/initrd/bin/busybox" chmod +x "$WORKDIR/initrd/bin/busybox" ln -s /bin/busybox "$WORKDIR/initrd/init" fi if [ ! -f "$WORKDIR/initrd/etc/keys.bmap" ] then # When using sudo with password auth, ask and cache pass first $ROOTCMD true # The following compound command will suck at asking pass $ROOTCMD dumpkeys | $ROOTCMD loadkeys -b > "$WORKDIR/initrd/etc/keys.bmap" cp -a /etc/localtime "$WORKDIR/initrd/etc/" fi if [ ! -f "$WORKDIR/initrd/usr/sbin/partclone.restore" ] then ( set +x PATH="$WORKDIR/kernel/tools/perf:/usr/sbin:/usr/bin:/sbin:/bin" # Diagnostic tools mkchroot "$WORKDIR/initrd" dmidecode iftop iostat lshw lspci lsblk lsusb mpstat # Console tools and manpages display mkchroot "$WORKDIR/initrd" tput setterm strace groff nroff troff grotty gtbl tmux bc pv figlet beep # Filesystem tools mkchroot "$WORKDIR/initrd" mkfs mke2fs /sbin/mkfs.ext* mkntfs mkfs.ntfs mkfs.fat mkexfatfs mkfs.exfat mkfs mkchroot "$WORKDIR/initrd" ntfs-3g mount.ntfs mount.fuse mount.exfat-fuse mount.exfat mkchroot "$WORKDIR/initrd" /sbin/ntfs* /bin/ntfs* # Disk tools mkchroot "$WORKDIR/initrd" fdisk gdisk sfdisk sgdisk # Cloning tools mkchroot "$WORKDIR/initrd" /usr/sbin/partclone* efibootmgr pigz udp-receiver # Some dyn-loaded libraries (ldd will not display them) mkchroot "$WORKDIR/initrd" /lib/x86_64-linux-gnu/libusb-1.0.so.0 # Some needed data files cp -ar /lib/terminfo "$WORKDIR/initrd/lib/" ) fi if [ "x$DEVEL_MODE" == "xy" ] then ( # tcpdump costs few Mb with libcrypto mkchroot "$WORKDIR/initrd" tcpdump # Perf tool p="$WORKDIR/kernel/tools/perf/perf" cp -a "$p" "$WORKDIR/initrd/sbin/" set +x mkchroot "$WORKDIR/initrd" $(ldd "$p" | egrep -o '/.* ') ) fi if [ ! -d "$WORKDIR/initrd/usr/man" ] then mkdir -p "$WORKDIR"/initrd/usr/man/man{1,6,8} "$WORKDIR"/initrd/usr/share/groff/current/font mkdir -p "$WORKDIR"/initrd/etc/groff/ "$WORKDIR"/initrd/usr/share/figlet/ cp -a /usr/share/man/man1/{beep,iostat,lshw,mpstat,setterm,bc,pv,strace,tmux,pigz,udp-receiver}* "$WORKDIR"/initrd/usr/man/man1/ cp -a /usr/share/man/man6/figlet* "$WORKDIR"/initrd/usr/man/man6/ cp -a /usr/share/man/man8/{dmidecode,iftop,lspci,lsblk,lsusb,partclone,efibootmgr,mkfs}* "$WORKDIR"/initrd/usr/man/man8/ cp -a /usr/share/man/man8/{ntfs,mkntfs,mkexfatfs,mount.ntfs,mount.fuse,mount.exfat-fuse}* "$WORKDIR"/initrd/usr/man/man8/ cp -a /usr/share/man/man8/{mount.exfat,fdisk,gdisk,sfdisk,sgdisk,tcpdump}* "$WORKDIR"/initrd/usr/man/man8/ cp -ra /usr/share/groff/current/font/devascii "$WORKDIR"/initrd/usr/share/groff/current/font/ cp -ra /usr/share/groff/current/tmac "$WORKDIR"/initrd/usr/share/groff/current/ cp -a /usr/share/figlet/{standard,mono12}* "$WORKDIR"/initrd/usr/share/figlet/ cp -a /etc/groff/man.local "$WORKDIR"/initrd/usr/share/groff/current/ fi p="$WORKDIR/kernel/tools/perf/perf" if [ "x$KERNEL_TOOLS" == "xy" -a ! -f "$p" ] then ( cp -a "$p" "$WORKDIR/initrd/sbin/" set +x mkchroot "$WORKDIR/initrd" $(ldd "$p" | egrep -o '/.* ') ) fi if [ ! -d "$WORKDIR/initrd/var/lib" ] then [ -f "$DLDIR/pci.ids" ] || $WGET -O "$DLDIR/pci.ids" "$PCI_IDS_URL" [ -f "$DLDIR/usb.ids" ] || $WGET -O "$DLDIR/usb.ids" "$USB_IDS_URL" mkdir -p "$WORKDIR/initrd/var/lib/usbutils" "$WORKDIR/initrd/usr/share/misc" cp "$DLDIR/usb.ids" "$WORKDIR/initrd/var/lib/usbutils/" cp "$DLDIR/pci.ids" "$WORKDIR/initrd/usr/share/misc/" fi if [ ! -d "$WORKDIR/initrd/lib/firmware" ] then [ -f "$DLDIR/nic-firmware.deb" ] || $WGET -O "$DLDIR/nic-firmware.deb" "$NIC_FIRMWARE_URL" dpkg -x "$DLDIR/nic-firmware.deb" "$WORKDIR/initrd/" find "$WORKDIR/initrd/lib/firmware/" \( -name 'ipw*' -o -name 'brcmfmac*' -o -name '*wifi*' \) -print0 | xargs -r0 rm -v fi echo $VERSION > "$WORKDIR/initrd/etc/eficast_version" cat > "$WORKDIR/initrd/etc/rc.d/funcs" <<"EOF" # echo_color [prefix_string] echo_color() { [ $# -eq 4 ] && echo -n "$3" setterm --foreground "$1" --background "$2" [ $# -eq 4 ] && echo -n "$4" || echo -n "$3" setterm --foreground white --background black echo " (eficast v"$(cat /etc/eficast_version)")" } # if no args, print colored message, wait 1 minute and reboot eficast_end() { echo_color white green "----- EFICAST end of execution ------" read -t10 -p 'Ctrl+C to have a shell, Enter to skip wait time...' reboot } # note : rcS rescue_shell is slighly different because 'sh' and 'reboot' need cautions to work rescue_shell() { echo echo_color white red "Something went wrong. Dropping to a shell." sfx_failure PS1='\h:\w# ' HOME='/root/' /bin/busybox sh } machine_info() { setterm -bold on grep -F MemTotal: /proc/meminfo for k in system-manufacturer system-product-name \ baseboard-manufacturer baseboard-product-name \ bios-version bios-release-date do echo $k: $(dmidecode -s $k) done lspci -nn | cut -d' ' -f2- | sed -ne 's/^Ethernet[^:]*/network-card/p' ip -o l | sed -ne 's/[0-9]*: \([^:]*\):[^\\]*\\\s*link\/ether\s/network-mac-\1: /p' lsblk -dnl | sed 's/^/disk: /' lsusb 2>/dev/null | grep -vE hub$ | cut -d: -f2- | sed 's/^ ID/usb-device:/' setterm -bold off } network_conf() { ip -oneline link | grep LOWER_UP | cut -d: -f2 | grep -v sit | grep -v lo | while read iface do udhcpc -b $iface -t 15 done } network_show() { setterm -bold on ip -o addr show | sed -ne 's/[0-9]*:\s*\(\S*\)\s*inet6*\s\(\S*\)\s.*$/\1: \2/p' setterm -bold off } nfs_autorun() { if [ -x /mnt/nfs/autorun.sh ] then echo_color white green "----- NFS server ready ------" echo_color green black "autorun.sh script will run on tty1 now" autorun.sh else echo_color white red "----- NFS server NOT ready ------" fi } notes() { echo 'print "n=CCDEEFFGAABB\na=nsnbnnsnbnbn\n(\n"; for (d=21;d<109;d++) { scale=20; f=440*e((d-69)/12*l(2)); fr=f+0.5; scale=0; fr=fr/1; o=d/12-1; t=d%12; print "echo ${n:",t,":1}${a:",t,":1}",o,"=",fr,"\n" }; print ") | tr -d n"' | bc -l | busybox sh } sound() { mode=$1; dur=$2; shift 2; args="-l0" while [ -n "$1" ]; do case $mode in 1) args="$args -n -f$1 -l$dur";; 2) args="$args -n -f$1 -l$(($2*dur))";; 3) args="$args -n -f$1 -l$(($2*dur)) -D$(($3*dur))";; esac shift $mode done beep $args } sfx_question() { sound 2 50 $E7 2 $C7 2 $E7 2 $C7 3; } sfx_success() { sound 1 140 $E6 $G6 $E7 $C7 $D7 $G7 ; } sfx_failure() { sound 3 100 $C5 1 3 $G4 1 3 $E4 3 0 $A4 2 0 $B4 2 0 $A4 2 0 $Ab4 3 0 $Bb4 3 0 $Ab4 3 0 $G4 6 0 ; } sfx_starting() { sound 1 25 $C5 $G4 $C5 $E5 $G5 $C6 $G5 $Ab4 $C5 $Eb5 $Ab5 $Eb5 $Ab5 $C6 $Eb6 $Ab6 $Eb6 $Bb4 $D5 $F5 $Bb5 $D6 $F6 $Bb6 $F6 ; } eval $(notes) EOF cat > "$WORKDIR/initrd/etc/inittab" <<"EOF" # Custom init scripts ::sysinit:/etc/rc.d/rcS # Standard things follow ::ctrlaltdel:/sbin/reboot -f ::shutdown:/sbin/swapoff -a ::shutdown:/bin/umount -a -r ::restart:/sbin/init tty1::respawn:/etc/rc.d/rc2_once.sh tty2::askfirst:/bin/sh tty3::askfirst:/bin/sh tty4::askfirst:/bin/sh EOF add_initrd_script "/etc/rc.d/rcS" <<"EOF" echo -e '\033[37;43m'----- rcS script started -----'\033[0m' # Hint for user about boot steps if its hangs # Declare some funcs to have a tidy output with trace mode # note : rc.d/funcs rescue_shell is slighly different the environnement is ready to go rescue_shell() { echo_color white red "Something went wrong. Dropping to a shell." PS1='\h:\w# ' setsid cttyhack /bin/busybox sh /bin/busybox sync; /bin/busybox umount /dev/pts /dev /sys /proc /bin/busybox reboot -f } mount_pseudofilesystems() { # Mount pseudo-filesystems mount -t proc none /proc || return $? mount -t sysfs none /sys || return $? mount -t devtmpfs -o size=1m none /dev || return $? mkdir /dev/pts || return $? mount -t devpts none /dev/pts || return $? ln -s /proc/self/fd/2 /dev/stderr return 0 } network_up() { ip -oneline link | grep DOWN | cut -d: -f2 | grep -v sit | while read iface do echo ip link set dev $iface up ip link set dev $iface up done } # Trace execution set -v /bin/busybox --install -s||rescue_shell # Setup busybox symlinks for all applets mount_pseudofilesystems || rescue_shell # Setup /dev, /proc, /sys and so loadkmap < /etc/keys.bmap # Load keyboard layout mount -o remount -o size=80% / # Allow using most of RAM for rootfs network_up # Bring net interfaces up (no config) sleep 5 # Wait for physical link detection + STP + IPv6 DAD & Autoconf set +v # Hint users about boot steps to help them if it hangs echo -e '\033[32m/etc/rc.d/rc2 script will run on tty1 now\033[0m' echo -e '\033[37;43m----- rcS script ended -----\033[0m' EOF add_initrd_script "/etc/rc.d/rc2" <<"EOF" echo -e '\033[37;43m'----- rc2 script started -----'\033[0m' # Hint for user about boot steps if its hangs . /etc/rc.d/funcs # Load helper functions export TERM=linux # FIXME: wrong default TERM=vt102, why? setterm -blank 60 # screen sleep mode after 60 minutes set -v # Trace execution network_conf network_show machine_info mount -v -t nfs -o nolock 172.16.2.28:/masters /mnt/nfs nfs_autorun || rescue_shell eficast_end set +v echo -e '\033[37;43m'----- rc2 script ended -----'\033[0m' # Hint for user about boot steps if its hangs EOF add_initrd_script "/usr/share/udhcpc/default.script" <<"EOF" #!/bin/sh case $1 in bound) # Configure interface and default gateway busybox ifconfig $interface ${mtu:+mtu $mtu} $ip netmask $subnet ${broadcast:+broadcast $broadcast} busybox ip -4 route add default via $router dev $interface # Update resolver configuration file [ -n "$domain" ] && R="domain $domain" || R="" for i in $dns; do R="$R\nnameserver $i" done echo -e "$R" > /etc/resolv.conf # Update in-kernel-memory hostname [ -n "$hostname" ] && hostname $hostname ;; renew | deconf) echo "no action taken: $1: $interface" >&2 ;; leasefail | nak) echo "configuration failed: $1: $message" >&2 ;; esac EOF add_initrd_script "/etc/rc.d/rc2_once.sh" <<"EOF" if [ -f /run/rc2_once ] then source /etc/rc.d/funcs rescue_shell else touch /run/rc2_once /etc/rc.d/rc2 fi EOF add_initrd_script "/bin/autorun.sh" <<"EOF" # Helper script to have retries handy cd /mnt/nfs ./autorun.sh EOF add_initrd_script "/bin/restore-script" <<"EOF" # Dummy restore script for testing the tmux inegration pigz -dc testimg.partclone.gz | partclone.restore -o /dev/sda1 sleep 60 EOF add_initrd_script "/bin/iftop-watch" <<"EOF" printf '\033]2;'"$*"'\033\\' # Term title (tmux) iftop -nNl EOF add_initrd_script "/bin/iostat-watch" <<"EOF" # Emulates watch command with iostat (filtered info, minimal height) printf '\033]2;'"$*"'\033\\' # Term title (tmux) iostat -cdmz 1 | awk '$1=="avg-cpu:" { system("clear"); } length($0) > 0 { print $0; }' EOF add_initrd_script "/bin/pigz-watch" <<"EOF" # Emulate watch command using pipeview (pv) for a running pigz printf '\033]2;'"$*"'\033\\' # Term title (tmux) while true do pid=$(pidof -s pigz) [ -n "$pid" ] && pv -D5 -F "%N %b %T %t %r %a %p %I" -d $pid sleep 1 done EOF add_initrd_script "/bin/pstree-watch" <<"EOF" printf '\033]2;'"$*"'\033\\' # Term title (tmux) watch -t pstree -p EOF add_initrd_script "/bin/tmux-wrap" <<"EOF" tmux new-session -d "if $* ; then tmux kill-server; else tmux select-pane -P bg=red; rescue_shell ; fi" \; \ set-window-option status off \; \ split-window -t %0 -l1 pigz-watch \; \ split-window -t %0 -l5 iftop-watch \; \ split-window -t %0 -l6 iostat-watch \; \ split-window -h -p30 pstree-watch \; \ select-pane -t:.0 \; \ attach EOF add_initrd_script "/bin/message" <<"EOF" # Output some center ASCII-art text, one line per argument printf '\033]2;'"$*"'\033\\' # Term title (tmux) CMDFIG="figlet -t -f mono12" while [ -n "$1" ]; do termwidth=$(tput cols) textlen=$(echo $1 | $CMDFIG | head -n1 | wc -c) offset=$(( (termwidth-textlen)/2 )) echo $1 | $CMDFIG | awk "{printf \"%${offset}s\"; print}" shift done EOF # XXX workaround, kernel makefile's cpio preseves everything and it is not so cool for us $ROOTCMD chown -R root: "$WORKDIR/initrd" # Kernel build (with embed initramfs) # ####################################### ( cd "$WORKDIR/kernel" # Workaround : some kernel version forget to update embed initramfs in certain cases [ -f usr/initramfs_data.cpio.gz ] && rm usr/initramfs_data.cpio.gz nproc=$(nproc --all) nproc=${nproc:-4} make -j $((nproc+1)) ) # Copy / run result EFI file # ############################## # Workaround : direct kernel boot with libvirt/virt-manager do a chown on BOOTX64.EFI and cp won't overwrite [ -f "$OUTDIR/BOOTX64.EFI" ] && rm -f "$OUTDIR/BOOTX64.EFI" cp "$WORKDIR/kernel/arch/x86/boot/bzImage" "$OUTDIR/BOOTX64.EFI" # Prepare an USB bootable disk if $OUTUSB is set and is has at least 1 primary partition if [ -n "$OUTUSB" -a -b "${OUTUSB}1" ] then [ -d "$WORKDIR/mountpoint" ] || mkdir "$WORKDIR/mountpoint" mount | grep -E "^${OUTUSB}1" -q && $ROOTCMD umount "${OUTUSB}1" if [ "x$LEGACY" == "xy" ] then $ROOTCMD install-mbr "${OUTUSB}" $ROOTCMD sfdisk --activate=1 "$OUTUSB" sleep 1 # XXX do a proper udev wait $ROOTCMD mount "${OUTUSB}1" "$WORKDIR/mountpoint" $ROOTCMD tee "$WORKDIR/mountpoint/syslinux.cfg" > /dev/null <<"EOT" default eficast label eficast kernel /EFI/BOOT/BOOTX64.EFI append from=syslinux label debug kernel /EFI/BOOT/BOOTX64.EFI append debug ignore_loglevel bootmem_debug apic=debug show_lapic=all acpi.debug_layer=0xffffffff acpi.debug_level=0xffffffff debugpat initcall_debug pnp.debug=1 sched_debug label noacpi kernel /EFI/BOOT/BOOTX64.EFI append noacpi timeout 10 prompt 1 EOT else $ROOTCMD mount "${OUTUSB}1" "$WORKDIR/mountpoint" fi [ -d "$WORKDIR/mountpoint/BOOT/EFI" ] || $ROOTCMD mkdir -p "$WORKDIR/mountpoint/EFI/BOOT" $ROOTCMD cp "$OUTDIR/BOOTX64.EFI" "$WORKDIR/mountpoint/EFI/BOOT" $ROOTCMD umount "$WORKDIR/mountpoint" fi [ "x$DEVEL_MODE" == "xy" ] && qemu-system-x86_64 -M q35 -m 256 -kernel "$OUTDIR/BOOTX64.EFI" -enable-kvm -serial stdio -append "console=ttyAMA0 console=ttyS0"