XENIAL-RECOVERY 是甚麼呢? 我在這個 Project 中使用 Arm 平台, 以 Nfs 開機, 復原 Ubuntu Xenial 16.04 作業系統. 請看下述 Youtube 影片:
RamFs (InitRd / InitRamFs)
mkird 是本人寫的 script, 用途是製作 XENIAL-RECOVERY .
# vi ./mkird
#!/bin/bash RECOVERY=1 [ ! -f ./mkird ] && exit 1 [ ! -f ./prebuild/tarball/dev.tgz ] && exit 1 # Housekeeping... CWD=`pwd` rm -rf tmp/* boot/* ; mkdir -p tmp mnt boot # Ramdisk Constants RDSIZE=30000 BLKSIZE=1024 # Create an empty ramdisk image dd if=/dev/zero of=tmp/ramdisk.img bs=$BLKSIZE count=$RDSIZE # Make it an ext2 mountable file system /sbin/mke2fs -L initrd -F -m 0 -b $BLKSIZE tmp/ramdisk.img $RDSIZE # Mount it so that we can populate #mount tmp/ramdisk.img mnt/initrd -t ext2 -o loop=/dev/loop0 #mount tmp/ramdisk.img mnt/initrd -t ext2 -o loop mount tmp/ramdisk.img mnt/initrd -t ext2 mkdir -p mnt/initrd/bin mnt/initrd/etc mnt/initrd/proc mnt/initrd/sys mnt/initrd/dev mnt/initrd/etc/init.d mnt/initrd/var mnt/initrd/lib mnt/initrd/usr/lib mkdir -p mnt/initrd/var/run mnt/initrd/etc/init.d mnt/initrd/mnt/initramfs mnt/initrd/mnt/sda1 mnt/initrd/mnt/sda2 mkdir -p mnt/initrd/mnt/tmp mnt/initrd/mnt/nfs mnt/initrd/mnt/rootfs mnt/initrd/mnt/asec mkdir -p mnt/initrd/bin mnt/initrd/sbin mnt/initrd/lib ############################################################ #ls /opt/CodeSourcery/arm-none-linux-gnueabi/libc/lib/ make -C busybox ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- defconfig make -C busybox ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- #make -C busybox ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- install CONFIG_PREFIX=../mnt/initrd make -C busybox ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- install CONFIG_PREFIX=${CWD}/mnt/initrd cd ${CWD}/e2fsprogs LDFLAGS=-static ./configure --host=arm-none-linux-gnueabi --prefix=${CWD}/e2fsprogs/install LDFLAGS=-static make V=1 rm -rf ${CWD}/e2fsprogs/install MKFS_PATH=`find ${CWD}/e2fsprogs -name mke2fs` #echo "MKFS_PATH=$MKFS_PATH" /bin/cp -Rpf $MKFS_PATH ${CWD}/mnt/initrd/sbin/mkfs cd ${CWD} ############################################################ /bin/cp -Rpf prebuild/bin/* mnt/initrd/bin/ /bin/cp -Rpf prebuild/sbin/netrecovery mnt/initrd/sbin/ /bin/cp -Rpf prebuild/etc/* mnt/initrd/etc/ [ $? -ne 0 ] && umount mnt/initrd && echo 'cannot copy ...' && exit 1 tar zxvf prebuild/tarball/dev.tgz -C mnt/initrd/dev/ [ $? -ne 0 ] && umount mnt/initrd && echo 'cannot copy ...' && exit 1 rm -rf mnt/initrd/lost+found rm -rf mnt/initrd/dev/block/* rm -rf mnt/initrd/dev/disk/* ############################################################ ls mnt/initrd/ && echo " " ls mnt/initrd/bin/ && echo " " ls mnt/initrd/sbin/ && echo " " ls mnt/initrd/lib/ && echo " " # netrecovery if [ $RECOVERY -eq 1 ]; then sed -i s/^#netrecovery/netrecovery/g mnt/initrd/etc/init.d/rcS else sed -i s/^netrecovery/#netrecovery/g mnt/initrd/etc/init.d/rcS fi ############################################################ umount mnt/initrd gzip -9 tmp/ramdisk.img if [ $RECOVERY -eq 1 ]; then cp tmp/ramdisk.img.gz boot/recovery.img else cp tmp/ramdisk.img.gz boot/ramfs.img fi
dev.tgz 我就不詳述了 請自行 tar 起來, 或用 mknod 來製作.
Cross 編譯 busybox & install 至 initrd, 差不多就是這樣....
make -C busybox ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- defconfig
make -C busybox ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- install CONFIG_PREFIX=${CWD}/mnt/initrd
....
Utility 的部分 我使用 esf2prog, 請注意它 Cross 的編譯方式
LDFLAGS=-static ./configure --host=arm-none-linux-gnueabi --prefix=${CWD}/e2fsprogs/install
LDFLAGS=-static make V=1
...
Prebuild 裡面的內容
# ls prebuild/ bin etc lib sbin tarball # ls prebuild/tarball/ dev.tgz # ls prebuild/bin/ busybox # ls prebuild/sbin/ mke2fs mkfs.ext2 mkfs.ext4 netrecovery # ls prebuild/etc/ fstab host.conf hostname hosts ifplugd inetd.conf init.d inittab mke2fs.conf network nsswitch.conf passwd profile resolv.conf services shells shutdown udhcpc.sh # ls prebuild/lib/ root@monta:/home/arm-ubuntu/xenial-recovery-armhf #
# cat prebuild/etc/fstab proc /proc proc defaults 0 0 devtmpfs /dev devtmpfs defaults 0 0 sysfs /sys sysfs defaults 0 0
# cat prebuild/etc/host.conf order hosts,bind multi on
# cat prebuild/etc/hostname monta
# cat prebuild/etc/hosts 127.0.0.1 localhost 127.0.1.1 monta
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
# cat prebuild/etc/ifplugd/ifplugd.action #!/bin/sh ifname="$1" action="$2" case "$action.$ifname" in up.eth0) if [ -f /var/run/udhcpc.pid ]; then kill `cat /var/run/udhcpc.pid` fi /sbin/udhcpc -i eth0 -p /var/run/udhcpc.pid ;; down.eth0) if [ -f /var/run/udhcpc.pid ]; then kill `cat /var/run/udhcpc.pid` fi ;; esac
# cat prebuild/etc/inetd.conf #telnet stream tcp nowait root /usr/sbin/telnetd telnetd -i
# cat prebuild/etc/inittab ::sysinit:/etc/init.d/rcS #::askfirst:-/bin/sh # Stuff to do when restarting the init process ::restart:/sbin/init # Stuff to do before rebooting ::ctrlaltdel:/sbin/reboot ::shutdown:/etc/shutdown # ttyAMA0 #::respawn:/sbin/inetd -f ::respawn:/sbin/getty 115200 ttyAMA0
# cat prebuild/etc/mke2fs.conf [defaults] base_features = sparse_super,large_file,filetype,resize_inode,dir_index,ext_attr default_mntopts = acl,user_xattr enable_periodic_fsck = 0 blocksize = 4096 inode_size = 256 inode_ratio = 16384 [fs_types] ext3 = { features = has_journal } ext4 = { features = has_journal,extent,huge_file,flex_bg,metadata_csum,64bit,dir_nlink,extra_isize inode_size = 256 } ext4dev = { features = has_journal,extent,huge_file,flex_bg,metadata_csum,inline_data,64bit,dir_nlink,extra_isize inode_size = 256 options = test_fs=1 } small = { blocksize = 1024 inode_size = 128 inode_ratio = 4096 } floppy = { blocksize = 1024 inode_size = 128 inode_ratio = 8192 } big = { inode_ratio = 32768 } huge = { inode_ratio = 65536 } news = { inode_ratio = 4096 } largefile = { inode_ratio = 1048576 blocksize = -1 } largefile4 = { inode_ratio = 4194304 blocksize = -1 } hurd = { blocksize = 4096 inode_size = 128 }
# cat prebuild/etc/network/interfaces auto lo iface lo inet loopback auto eth0 iface eth0 inet dhcp
# cat prebuild/etc/nsswitch.conf passwd: files shadow: files group: files hosts: files dns protocols: files rpc: files services: files
# cat prebuild/etc/passwd root::0:0::/root:/bin/sh
# cat prebuild/etc/profile # begin_generated_IBM_copyright_prolog # # This is an automatically generated copyright prolog. # After initializing, DO NOT MODIFY OR MOVE # ================================================================ # # Licensed Materials - Property of IBM # # Blue Gene/Q # # (C) Copyright IBM Corp. 2010, 2012 # # US Government Users Restricted Rights - # Use, duplication or disclosure restricted # by GSA ADP Schedule Contract with IBM Corp. # # This software is available to you under the # Eclipse Public License (EPL). # # ================================================================ # # end_generated_IBM_copyright_prolog export PATH=/sbin:/usr/sbin:$PATH for i in /etc/profile.d/*.sh ; do if [ -r "$i" ]; then if [ "$PS1" ]; then . $i else . $i >/dev/null 2>&1 fi fi done export LC_ALL=C #. /etc/bg_profile # root@q01i3j01 [Q01-I3-J01 10000] #export PS1="\u@\h [$ASF_RANKNAME $ASF_COORDS]:\w # " #export HOSTNAME=monta #hostname $HOSTNAME export PS1='$(whoami)@$(hostname):$(pwd)# '
# cat prebuild/etc/resolv.conf nameserver 168.95.1.1
# cat prebuild/etc/services # Network services, Internet style # # Note that it is presently the policy of IANA to assign a single well-known # port number for both TCP and UDP; hence, officially ports have two entries # even if the protocol doesn't support UDP operations. # # Updated from http://www.iana.org/assignments/port-numbers and other # sources like http://www.freebsd.org/cgi/cvsweb.cgi/src/etc/services . # New ports will be added on request if they have been officially assigned # by IANA and used in the real-world or are needed by a debian package. # If you need a huge list of used numbers please install the nmap package. tcpmux 1/tcp # TCP port service multiplexer echo 7/tcp echo 7/udp discard 9/tcp sink null discard 9/udp sink null systat 11/tcp users daytime 13/tcp daytime 13/udp netstat 15/tcp ...
# cat prebuild/etc/shells /bin/sh /bin/ash /bin/hush
# cat prebuild/etc/shutdown #!/bin/sh true
# cat prebuild/etc/udhcpc.sh #!/bin/sh # udhcpc script edited by Tim Riker <Tim@Rikers.org> [ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1 RESOLV_CONF="/etc/resolv.conf" [ -n "$broadcast" ] && BROADCAST="broadcast $broadcast" [ -n "$subnet" ] && NETMASK="netmask $subnet" case "$1" in deconfig) /sbin/ifconfig $interface 0.0.0.0 ;; renew|bound) /sbin/ifconfig $interface $ip $BROADCAST $NETMASK if [ -n "$router" ] ; then echo "deleting routers" while route del default gw 0.0.0.0 dev $interface ; do : done for i in $router ; do route add default gw $i dev $interface done fi echo -n > $RESOLV_CONF [ -n "$domain" ] && echo search $domain >> $RESOLV_CONF for i in $dns ; do echo adding dns $i echo nameserver $i >> $RESOLV_CONF done ;; esac exit 0
制定 rcS 開機 Script
把我們要做的事放入 rcS. netrecovery 劇本待會兒會提到. 在這兒把它以 # mark 起來, 就是 netboot
# vi prebuild/etc/init.d/rcS
#!/bin/sh export HOSTNAME=monta hostname monta mkdir -p /etc/network/if-up.d mkdir -p /etc/network/if-pre-up.d mkdir -p /root mkdir -p /sys mkdir -p /proc mkdir -p /tmp mount -o remount,rw / mount -t sysfs none /sys mount -t tmpfs none /var mkdir -p /var/log mkdir -p /var/run mount -t tmpfs none /dev mount -t proc none /proc echo /sbin/mdev > /proc/sys/kernel/hotplug /sbin/mdev -s # telnetd requires this mkdir -p /dev/pts && mount -t devpts none /dev/pts ln -sf /proc/mounts /etc/mtab ip addr add 127.0.0.1/8 dev lo ip link set lo up ip link set eth0 up #udhcpc -v -i eth0 -S -p /var/run/udhcpc.pid | grep 'Lease of ' | awk '{print $3}' | xargs ifconfig eth0 udhcpc -v -i eth0 -p /var/run/udhcpc.pid -S -s /etc/udhcpc.sh [ $? -ne 0 ] && exit 0 ########################################################### ########################################################### netrecovery exit 0
Netrecovery
# vi prebuild/sbin/netrecovery
#!/bin/sh ########################################################### echo 'preparing recoverying ... ' sleep 3 ########################################################### NFS=`route | grep default | awk '{print $2}'` mount -t nfs -o nolock,tcp ${NFS}:/tftpboot/xenial/netboot /mnt/tmp #mount -t nfs -o nolock,tcp 10.100.11.12:/tftpboot/xenial/netboot /mnt/tmp [ $? -ne 0 ] && exit 0 [ ! -f /mnt/tmp/rootfs.tgz ] && exit 0 [ ! -f /mnt/tmp/boot.tgz ] && exit 0 ########################################################### /bin/rm -rf /dev/sda /dev/sda1 /dev/sda2 /dev/sda5 mknod /dev/sda b 8 0 mknod /dev/sda1 b 8 1 mknod /dev/sda2 b 8 2 mknod /dev/sda5 b 8 5 #echo 'fdisk ing ..., sda1=' dd if=/dev/zero of=/dev/sda bs=512 count=1 sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' << EOF | fdisk /dev/sda o n p 1 1 +1024M n p 2 +51200M n e 3 +2048M n l t 5 82 a 1 w q EOF [ $? -ne 0 ] && exit 0 fdisk -l /dev/sda #mkswap --uuid 44546f01-0bd1-440c-bfa5-1e87bc7d254d -L swap /dev/sda5 mkswap -L swap /dev/sda5 [ $? -ne 0 ] && exit 0 #mkfs -t ext4 -F -U 9676373c-97a9-4278-ac24-3c854c434e98 -L rootfs /dev/sda2 -E lazy_itable_init mkfs -t ext4 -F -U 9676373c-97a9-4278-ac24-3c854c434e98 -L rootfs /dev/sda2 [ $? -ne 0 ] && exit 0 mount -t ext4 /dev/sda2 /mnt/sda2 [ $? -ne 0 ] && exit 0 tar zxvf /mnt/tmp/rootfs.tgz -C /mnt/sda2 rm -rf /mnt/sda2/dev/block/* rm -rf /mnt/sda2/dev/disk/* rm -rf /mnt/sda2/lost+found find /mnt/sda2/ -name .bash_history | xargs rm -rf echo '###' > /mnt/sda2/etc/fstab echo '#UUID=9676373c-97a9-4278-ac24-3c854c434e98 / ext4 errors=remount-ro 0 1' >> /mnt/sda2/etc/fstab echo '#UUID=7113ee79-3b3d-4e8e-8c16-fdb78f0d9c6f /boot ext2 defaults 0 2' >> /mnt/sda2/etc/fstab echo '/dev/sda2 / ext4 errors=remount-ro 0 1' >> /mnt/sda2/etc/fstab echo '/dev/sda1 /boot ext2 defaults 0 2' >> /mnt/sda2/etc/fstab echo '/dev/sda5 none swap sw 0 0' >> /mnt/sda2/etc/fstab #sed -i s/^#\\/dev\\/sda2/\\/dev\\/sda2/ /mnt/sda2/etc/fstab #sed -i s/^#\\/dev\\/sda1/\\/dev\\/sda1/ /mnt/sda2/etc/fstab #sed -i s/^#\\/dev\\/sda5/\\/dev\\/sda5/ /mnt/sda2/etc/fstab #mkfs -t ext2 -F -U 7113ee79-3b3d-4e8e-8c16-fdb78f0d9c6f -L boot /dev/sda1 -E lazy_itable_init mkfs -t ext2 -F -U 7113ee79-3b3d-4e8e-8c16-fdb78f0d9c6f -L boot /dev/sda1 [ $? -ne 0 ] && exit 0 mount -t ext2 /dev/sda1 /mnt/sda1 [ $? -ne 0 ] && exit 0 tar zxvf /mnt/tmp/boot.tgz -C /mnt/sda1 rm -rf /mnt/sda1/lost+found umount /mnt/tmp umount /mnt/sda1 umount /mnt/sda2 sync ; sync ; sync sync ; sync ; sync sync ; sync ; sync ls / echo 'system recovery ok, rebooting now ...' sleep 3 ; echo b > /proc/sysrq-trigger
下面提到的 boot.tgz 以及 rootfs.tgz 如何獲得? 請將正常開機的 Ubuntu ArmHf xenial /boot 以及 / TARBALL 起來.
Pxe 設定檔案內容
# cat /tftpboot/pxelinux.cfg/default.xenial-recovery LABEL xenial recovery KERNEL xenial/netinstall/vmlinuz APPEND initrd=xenial/netinstall/recovery.img console=ttyAMA0 init=/linuxrc root=/dev/ram0 rw noquiet
Try Deploy Ubuntu Boot I:
1. DETERMINE IF TRAGET ROOTFS IS MOUNT ON `/dev/sda1` , IF YES TRY THE FOLLOWING 2. COPY TARGET /boot/initrd*,vmlinuz*,System.map* to HOST /boot/ 不用覆蓋 3. BACKUP HOST /etc/default/grub , /boot/grub/grub.cfg 4. COPY TARGET /etc/default/grub to HOST /etc/default/grub 5. COPY /boot/grub/grub.cfg to HOST 6. EDIT the /etc/default/grub IF /dev/sda1 is TARGET ROOTFS and TARGET vmlinuz-4.15.0-54-generic, initrd.img-4.15.0-54-generic add the following to the first menuentry for /boot/grub/grub.cfg menuentry 'Atgames' { recordfail load_video gfxmode $linux_gfx_mode insmod gzio if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi insmod part_msdos insmod ext2 set root='hd0,msdos1' linux /boot/vmlinuz-4.15.0-54-generic root=/dev/sda1 ro initrd /boot/initrd.img-4.15.0-54-generic } ... can MASK this line `set root='hd0,msdos1'` , I GUESS vmlinuz-XXXX-generic initrd.img-XXXX-generic, refer to TARGET 7. update-grub -o ./grub.cfg ONLY GENERATE the ./grub.cfg, DON'T AFFECT THE HOST GRUB SETTING 8. COPY the ./grub.cfg to TARGET /boot/grub/grub.cfg 9. RESTORE the HOST /etc/default/grub from BACKUP 10. RESTORE the HOST /boot/grub/grub.cfg from BACKUP
Try Deploy Ubuntu Boot II:
$ cp initrd.img-4.15.0-54-generic ./initrd.gz $ gunzip initrd.gz $ mkdir -p rootfs $ cd rootfs $ cpio -id < ../initrd $ mkdir -p mnt
EDIT the init
#!/bin/sh export PATH=/sbin:/usr/sbin:/bin:/usr/bin /bin/mount proc /proc -t proc /bin/mount sysfs /sys -t sysfs /bin/mount none /debug -t debugfs mount -t ext2 /dev/sda1 /mnt exec switch_root /mnt /sbin/init
$ sudo chmod +x ./init $ sudo find . | cpio -o -H newc | gzip > ../initrd.gz $ cd .. $ cp initrd.gz initrd.img-4.15.0-54-generic
如果你覺得這篇文章對你有幫助, 請於留言板留個言, 以茲鼓勵. 謝謝! Email: jasonc@mail2000.com.tw
留言列表