From a19218ad25eac323ead61ec5ff1fbb04a6dc2539 Mon Sep 17 00:00:00 2001
From: liyuanr <liyuanrong1@huawei.com>
Date: Fri, 3 Dec 2021 11:16:22 +0800
Subject: [PATCH] KubeOS:add arm architecture support to the OS image

Signed-off-by: liyuanr <liyuanrong1@huawei.com>
---
 cmd/agent/server/server.go             |  5 +-
 files/{boot-grub2.mount => boot.mount} |  6 +-
 scripts/bootloader.sh                  | 40 +++++++++++++
 scripts/generate.sh                    | 83 +++++++++++++++-----------
 scripts/grub.cfg                       | 16 ++---
 scripts/rpmlist                        |  3 +-
 scripts/set_in_chroot.sh               |  2 +-
 7 files changed, 107 insertions(+), 48 deletions(-)
 rename files/{boot-grub2.mount => boot.mount} (92%)
 create mode 100644 scripts/bootloader.sh

diff --git a/cmd/agent/server/server.go b/cmd/agent/server/server.go
index 711e0c8..e4db02e 100644
--- a/cmd/agent/server/server.go
+++ b/cmd/agent/server/server.go
@@ -174,7 +174,10 @@ func install(imagePath string, mainPart string, partB string) error {
 	if side != partB {
 		next = "A"
 	}
-	return runCommand("grub2-set-default", next)
+	if err := runCommand("grub2-set-default", next); err != nil {
+		return err
+	}
+	return runCommand("cp", "/boot/grub2/grubenv", "/boot/efi/EFI/openEuler")
 }
 
 func (s *Server) reboot() error {
diff --git a/files/boot-grub2.mount b/files/boot.mount
similarity index 92%
rename from files/boot-grub2.mount
rename to files/boot.mount
index a53fff7..a228aae 100644
--- a/files/boot-grub2.mount
+++ b/files/boot.mount
@@ -15,9 +15,9 @@ Conflicts=umount.target
 Before=local-fs.target umount.target
 
 [Mount]
-What=/dev/disk/by-label/GRUB2
-Where=/boot/grub2
-Type=ext4
+What=/dev/disk/by-label/BOOT
+Where=/boot
+Type=vfat
 Options=defaults
 
 [Install]
diff --git a/scripts/bootloader.sh b/scripts/bootloader.sh
new file mode 100644
index 0000000..b93c314
--- /dev/null
+++ b/scripts/bootloader.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+set -eu
+set -o pipefail
+set -x
+ARCH=`arch`
+
+function install_grub2_x86 ()
+{
+    # make boot.img/core.img and setup, to support legacy boot mode
+    GRUBNAME=$(which grub2-install)
+    echo "Installing GRUB2..."
+    GRUB_OPTS=${GRUB_OPTS:-"--force"}
+    GRUB_OPTS="$GRUB_OPTS --target=i386-pc"
+
+    $GRUBNAME --modules="biosdisk part_msdos" $GRUB_OPTS $DEVICE
+
+    # make efi file, and save in FAT16 partition, to support UEFI boot mode
+    cp -r /usr/lib/grub/x86_64-efi boot/efi/EFI/openEuler
+    eval "grub2-mkimage -d /usr/lib/grub/x86_64-efi -O x86_64-efi --output=/boot/efi/EFI/openEuler/grubx64.efi '--prefix=(,msdos1)/efi/EFI/openEuler' fat part_gpt part_msdos linux"
+
+    mkdir -p /boot/EFI/BOOT/
+    cp -f /boot/efi/EFI/openEuler/grubx64.efi /boot/EFI/BOOT/BOOTX64.EFI
+}
+
+function install_grub2_efi ()
+{
+    cp -r /usr/lib/grub/arm64-efi /boot/efi/EFI/openEuler/
+    eval "grub2-mkimage -d /usr/lib/grub/arm64-efi -O arm64-efi --output=/boot/efi/EFI/openEuler/grubaa64.efi '--prefix=(,msdos1)/efi/EFI/openEuler' fat part_gpt part_msdos linux"
+
+    mkdir -p /boot/EFI/BOOT/
+    cp -f /boot/efi/EFI/openEuler/grubaa64.efi /boot/EFI/BOOT/BOOTAA64.EFI
+}
+
+if [ $ARCH == "x86_64" ]; then
+    install_grub2_x86
+fi
+
+if [ $ARCH == "aarch64" ]; then
+    install_grub2_efi
+fi
diff --git a/scripts/generate.sh b/scripts/generate.sh
index 73830ea..c481e30 100644
--- a/scripts/generate.sh
+++ b/scripts/generate.sh
@@ -22,6 +22,7 @@ TMP_MOUNT_PATH="${PWD}/mnt"
 RPM_ROOT="${PWD}/rootfs"
 LOCK=./test.lock
 CHECK_REGEX='\||;|&|&&|\|\||>|>>|<|,|#|!|\$'
+ARCH=$(arch)
 
 function show_options() {
 	cat << EOF
@@ -76,9 +77,14 @@ function init_part() {
 	offset=$(echo "${offset}*512" | bc)
 	local loop=$(losetup -f)
 	losetup -o "${offset}" --sizelimit "${sizelimit}" "${loop}" system.img
-	mkfs.ext4 -L "$2" "${loop}"
-	mount -t ext4 "${loop}" "$3"
-	rm -rf "$3/lost+found"
+        if [ $2 == "BOOT" ];then
+                mkfs.vfat -n "$2" "${loop}"
+                mount -t vfat "${loop}" "$3"
+        else
+                mkfs.ext4 -L "$2" "${loop}"
+                mount -t ext4 "${loop}" "$3"
+                rm -rf "$3/lost+found"      
+        fi
 }
 
 function delete_dir() {
@@ -183,12 +189,15 @@ function install_packages() {
 	fi
 
 	local rpms=$(cat ./rpmlist | tr "\n" " ")
-	yum -y --installroot="${RPM_ROOT}" install --nogpgcheck --setopt install_weak_deps=False ${rpms}
-	yum -y --installroot="${RPM_ROOT}" clean all
+        if [ "${ARCH}" == "x86_64" ]; then
+                yum -y --installroot="${RPM_ROOT}" install --nogpgcheck --setopt install_weak_deps=False ${rpms} grub2 grub2-efi-x64-modules grub2-pc-modules
+        elif [ "${ARCH}" == "aarch64" ]; then
+                yum -y --installroot="${RPM_ROOT}" install --nogpgcheck --setopt install_weak_deps=False ${rpms} grub2-efi-aa64-modules
+        fi
+        yum -y --installroot="${RPM_ROOT}" clean all
 }
 
 function install_misc() {
-	cp grub.cfg "${RPM_ROOT}/boot/grub2/"
 	cp ../files/*mount ../files/os-agent.service "${RPM_ROOT}/usr/lib/systemd/system/"
 	cp ../files/os-release "${RPM_ROOT}/usr/lib/"
 	cp "${AGENT_PATH}" "${RPM_ROOT}/usr/bin"
@@ -204,38 +213,46 @@ EOF
 	mv "${RPM_ROOT}"/boot/initramfs* "${RPM_ROOT}/boot/initramfs.img"
 
 	cp set_in_chroot.sh "${RPM_ROOT}"
-	ROOT_PWD="${PASSWD}" chroot "$RPM_ROOT" bash /set_in_chroot.sh
+	ROOT_PWD="${PASSWD}" chroot "${RPM_ROOT}" bash /set_in_chroot.sh
 	rm "${RPM_ROOT}/set_in_chroot.sh"
 }
 
 function create_img() {
 	rm -f system.img update.img
 	qemu-img create system.img ${IMG_SIZE}G
-	parted system.img -- mklabel msdos
-	parted system.img -- mkpart primary ext4 1MiB 20MiB
-	parted system.img -- mkpart primary ext4 20MiB 2120MiB
-	parted system.img -- mkpart primary ext4 2120MiB 4220MiB
-	parted system.img -- mkpart primary ext4 4220MiB 100%
-
-	local device=$(losetup -f)
-	losetup "${device}" system.img
-
-	mkdir -p "${TMP_MOUNT_PATH}"
-
-	init_part system.img2 ROOT-A "${TMP_MOUNT_PATH}"
-	local grub2_path="${TMP_MOUNT_PATH}/boot/grub2"
-	mkdir -p "${grub2_path}"
-	init_part system.img1 GRUB2 "${grub2_path}"
-
-	tar -x -C "${TMP_MOUNT_PATH}" -f os.tar
-	sync
-
-	dd if=/dev/disk/by-label/ROOT-A of=update.img bs=8M
-	mount_proc_dev_sys "${TMP_MOUNT_PATH}"
-	chroot "${TMP_MOUNT_PATH}" grub2-install --modules="biosdisk part_msdos" "${device}"
-	sync
-	unmount_dir "${TMP_MOUNT_PATH}"
-
+        parted system.img -- mklabel msdos
+        parted system.img -- mkpart primary fat16 1MiB 60MiB
+        parted system.img -- mkpart primary ext4 60MiB 2160MiB
+        parted system.img -- mkpart primary ext4 2160MiB 4260MiB
+        parted system.img -- mkpart primary ext4 4260MiB 100%
+
+        local device=$(losetup -f)
+        losetup "${device}" system.img
+
+        mkdir -p "${TMP_MOUNT_PATH}"
+
+        init_part system.img2 ROOT-A "${TMP_MOUNT_PATH}"
+        local BOOT_PATH=${TMP_MOUNT_PATH}/boot
+        mkdir -p ${BOOT_PATH}
+        chmod 755 ${BOOT_PATH}
+        init_part system.img1 BOOT "${BOOT_PATH}"
+
+        mv -f ${RPM_ROOT}/boot/* ${BOOT_PATH} || true
+        [ -d ${RPM_ROOT}/boot/ ] && rm -rf ${RPM_ROOT}/boot/
+        sudo mv -t ${TMP_MOUNT_PATH} ${RPM_ROOT}/* || true
+        cp bootloader.sh "${TMP_MOUNT_PATH}"
+        mount_proc_dev_sys "${TMP_MOUNT_PATH}"
+        DEVICE="${device}" chroot "${TMP_MOUNT_PATH}" bash bootloader.sh
+        cp grub.cfg ${TMP_MOUNT_PATH}/boot/grub2
+        cp grub.cfg ${TMP_MOUNT_PATH}/boot/efi/EFI/openEuler
+        rm -rf "${TMP_MOUNT_PATH}/bootloader.sh"     
+        sync
+	
+        dd if=/dev/disk/by-label/ROOT-A of=update.img bs=8M
+        sync
+        unmount_dir "${TMP_MOUNT_PATH}"
+
+	
 	init_part system.img3 ROOT-B "${TMP_MOUNT_PATH}"
 	umount "${TMP_MOUNT_PATH}"
 
@@ -251,8 +268,6 @@ function create_os_tar() {
 	install_packages
 	install_misc
 	unmount_dir "${RPM_ROOT}"
-
-	tar -C "${RPM_ROOT}" -cf ./os.tar .
 }
 
 test_lock
diff --git a/scripts/grub.cfg b/scripts/grub.cfg
index d10e4cf..90507c4 100644
--- a/scripts/grub.cfg
+++ b/scripts/grub.cfg
@@ -92,12 +92,12 @@ menuentry 'A' --class KubeOS --class gnu-linux --class gnu --class os --unrestri
         insmod ext2
         set root='hd0,msdos2'
         if [ x$feature_platform_search_hint = xy ]; then
-          search --no-floppy --file --set=root --hint-bios=hd0,msdos2 --hint-efi=hd0,msdos2 --hint-baremetal=ahci0,msdos2 /boot/vmlinuz
+          search --no-floppy --file --set=root --hint-bios=hd0,msdos2 --hint-efi=hd0,msdos2 --hint-baremetal=ahci0,msdos2 /vmlinuz
         else
-          search --no-floppy --file --set=root /boot/vmlinuz
+          search --no-floppy --file --set=root /vmlinuz
         fi
-        linux   /boot/vmlinuz root=/dev/sda2 ro rootfstype=ext4 nomodeset quiet oops=panic softlockup_panic=1 nmi_watchdog=1 rd.shell=0 selinux=0 crashkernel=256M panic=3
-        initrd  /boot/initramfs.img
+        linux   /vmlinuz root=/dev/sda2 ro rootfstype=ext4 nomodeset quiet oops=panic softlockup_panic=1 nmi_watchdog=1 rd.shell=0 selinux=0 crashkernel=256M panic=3
+        initrd  /initramfs.img
 }
 
 menuentry 'B' --class KubeOS --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'KubeOS-B' {
@@ -108,12 +108,12 @@ menuentry 'B' --class KubeOS --class gnu-linux --class gnu --class os --unrestri
         insmod ext2
         set root='hd0,msdos3'
         if [ x$feature_platform_search_hint = xy ]; then
-          search --no-floppy --file --set=root --hint-bios=hd0,msdos3 --hint-efi=hd0,msdos3 --hint-baremetal=ahci0,msdos3 /boot/vmlinuz
+          search --no-floppy --file --set=root --hint-bios=hd0,msdos3 --hint-efi=hd0,msdos3 --hint-baremetal=ahci0,msdos3 /vmlinuz
         else
-          search --no-floppy --file --set=root /boot/vmlinuz
+          search --no-floppy --file --set=root /vmlinuz
         fi
-        linux   /boot/vmlinuz root=/dev/sda3 ro rootfstype=ext4 nomodeset quiet oops=panic softlockup_panic=1 nmi_watchdog=1 rd.shell=0 selinux=0 crashkernel=256M panic=3
-        initrd  /boot/initramfs.img
+        linux   /vmlinuz root=/dev/sda3 ro rootfstype=ext4 nomodeset quiet oops=panic softlockup_panic=1 nmi_watchdog=1 rd.shell=0 selinux=0 crashkernel=256M panic=3
+        initrd  /initramfs.img
 }
 
 ### END /etc/grub.d/10_linux ###
diff --git a/scripts/rpmlist b/scripts/rpmlist
index 93c277c..7a9adfa 100644
--- a/scripts/rpmlist
+++ b/scripts/rpmlist
@@ -1,6 +1,7 @@
 kernel
 passwd
-grub2
+grub2-efi
+grub2-tools
 dhcp
 NetworkManager
 openssh-server
diff --git a/scripts/set_in_chroot.sh b/scripts/set_in_chroot.sh
index 3b8313f..49e3894 100644
--- a/scripts/set_in_chroot.sh
+++ b/scripts/set_in_chroot.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 ln -s /usr/lib/systemd/system/os-agent.service /usr/lib/systemd/system/multi-user.target.wants/os-agent.service
 ln -s /usr/lib/systemd/system/kubelet.service /usr/lib/systemd/system/multi-user.target.wants/kubelet.service
-ln -s /usr/lib/systemd/system/boot-grub2.mount /lib/systemd/system/local-fs.target.wants/boot-grub2.mount
+ln -s /usr/lib/systemd/system/boot.mount /lib/systemd/system/local-fs.target.wants/boot.mount
 ln -s /usr/lib/systemd/system/etc.mount /lib/systemd/system/local-fs.target.wants/etc.mount
 
 str=`sed -n '/^root:/p' /etc/shadow | awk -F "root:" '{print $2}'`
-- 
2.30.0

