build/debian: Allow booting the kernel directly

In this CL, we update the VM config to load the kernel directly,
as opposed to our current boot process with u-boot.
The motivation behind this is discussed in the linked bug reports.

- We add a `-u` build flag for the build script to generate images
  that boot using u-boot instead.
- We remove the unnecessary grub-related packages and configs
  from images generated without `-u` build flag.

Bug: 394995493
Bug: 401111452
Test: Tested the images built from each cmd below:
Test: - ./build_in_container.sh -a x86_64
Test: - ./build_in_container.sh -a aarch64
Test: - ./build_in_container.sh -a x86_64 -g
Test: - ./build_in_container.sh -a aarch64 -g
Change-Id: If56e8aecb19a4487694e80c5ddf58c0ab00ca972
diff --git a/build/debian/build.sh b/build/debian/build.sh
index 9c4d4b1..dfbf493 100755
--- a/build/debian/build.sh
+++ b/build/debian/build.sh
@@ -15,6 +15,7 @@
 	echo "-a ARCH    Architecture of the image [default is host arch: $(uname -m)]"
 	echo "-g         Use Debian generic kernel [default is our custom kernel]"
 	echo "-r         Release mode build"
+	echo "-u         Set VM boot mode to u-boot [default is to load kernel directly]"
 	echo "-w         Save temp work directory [for debugging]"
 }
 
@@ -25,7 +26,7 @@
 }
 
 parse_options() {
-	while getopts "a:ghrw" option; do
+	while getopts "a:ghruw" option; do
 		case ${option} in
 			h)
 				show_help ; exit
@@ -39,6 +40,9 @@
 			r)
 				mode=release
 				;;
+			u)
+				uboot=1
+				;;
 			w)
 				save_workdir=1
 				;;
@@ -114,6 +118,13 @@
 		)
 	fi
 
+	if [[ "$uboot" != 1 ]]; then
+		packages+=(
+			libguestfs-tools
+			linux-image-generic
+		)
+	fi
+
 	if [[ "$use_generic_kernel" != 1 ]]; then
 		packages+=(
 			bc
@@ -311,6 +322,14 @@
 }
 
 run_fai() {
+	# NOTE: Prevent FAI from installing grub packages and running related scripts,
+	#       if we are loading the kernel directly.
+	if [[ "$uboot" != 1 ]]; then
+		sed -i "/shim-signed/d ; /grub.*${debian_arch}.*/d" \
+		    "${config_space}/package_config/${debian_arch^^}"
+		rm "${config_space}/scripts/SYSTEM_BOOT/20-grub"
+	fi
+
 	local out="${raw_disk_image}"
 	make -C "${debian_cloud_image}" "image_bookworm_nocloud_${debian_arch}"
 	mv "${debian_cloud_image}/image_bookworm_nocloud_${debian_arch}.raw" "${out}"
@@ -318,10 +337,14 @@
 
 generate_output_package() {
 	fdisk -l "${raw_disk_image}"
-	local vm_config="$SCRIPT_DIR/vm_config.json"
 	local root_partition_num=1
 	local efi_partition_num=15
 
+	local vm_config="$SCRIPT_DIR/vm_config.json"
+	if [[ "$uboot" == 1 ]]; then
+		vm_config="$SCRIPT_DIR/vm_config.u-boot.json"
+	fi
+
 	pushd ${workdir} > /dev/null
 
 	echo ${build_id} > build_id
@@ -340,8 +363,6 @@
 	sed -i "s/{root_part_guid}/$(sfdisk --part-uuid $raw_disk_image $root_partition_num)/g" vm_config.json
 	sed -i "s/{efi_part_guid}/$(sfdisk --part-uuid $raw_disk_image $efi_partition_num)/g" vm_config.json
 
-	popd > /dev/null
-
 	contents=(
 		build_id
 		root_part
@@ -349,6 +370,19 @@
 		vm_config.json
 	)
 
+	if [[ "$uboot" != 1 ]]; then
+		rm -f vmlinuz* initrd.img*
+		virt-get-kernel -a "${raw_disk_image}"
+		mv vmlinuz* vmlinuz
+		mv initrd.img* initrd.img
+		contents+=(
+			vmlinuz
+			initrd.img
+		)
+	fi
+
+	popd > /dev/null
+
 	# --sparse option isn't supported in apache-commons-compress
 	tar czv -f ${output} -C ${workdir} "${contents[@]}"
 }
@@ -372,6 +406,7 @@
 mode=debug
 save_workdir=0
 use_generic_kernel=0
+uboot=0
 
 parse_options "$@"
 check_sudo
diff --git a/build/debian/build_in_container.sh b/build/debian/build_in_container.sh
index 739d2dd..82098ed 100755
--- a/build/debian/build_in_container.sh
+++ b/build/debian/build_in_container.sh
@@ -9,6 +9,7 @@
   echo "-g         Use Debian generic kernel [default is our custom kernel]"
   echo "-r         Release mode build"
   echo "-s         Leave a shell open [default: only if the build fails]"
+  echo "-u         Set VM boot mode to u-boot [default is to load kernel directly]"
   echo "-w         Save temp work directory in the container [for debugging]"
 }
 
@@ -17,8 +18,9 @@
 release_flag=
 save_workdir_flag=
 shell_condition="||"
+uboot_flag=
 
-while getopts "a:ghrsw" option; do
+while getopts "a:ghrsuw" option; do
   case ${option} in
     a)
       arch="$OPTARG"
@@ -35,6 +37,9 @@
     s)
       shell_condition=";"
       ;;
+    u)
+      uboot_flag="-u"
+      ;;
     w)
       save_workdir_flag="-w"
       ;;
@@ -58,4 +63,4 @@
   -v "$ANDROID_BUILD_TOP/packages/modules/Virtualization:/root/Virtualization" \
   --workdir /root/Virtualization/build/debian \
   ubuntu:22.04 \
-  bash -c "./build.sh -a $arch $release_flag $kernel_flag $save_workdir_flag $shell_condition bash"
+  bash -c "./build.sh -a $arch $release_flag $kernel_flag $uboot_flag $save_workdir_flag $shell_condition bash"
diff --git a/build/debian/vm_config.json b/build/debian/vm_config.json
index 463583f..e9b3763 100644
--- a/build/debian/vm_config.json
+++ b/build/debian/vm_config.json
@@ -27,6 +27,9 @@
             "sharedPath": "$APP_DATA_DIR/files"
         }
     ],
+    "kernel": "$PAYLOAD_DIR/vmlinuz",
+    "initrd": "$PAYLOAD_DIR/initrd.img",
+    "params": "root=/dev/vda1",
     "protected": false,
     "cpu_topology": "match_host",
     "platform_version": "~1.0",
diff --git a/build/debian/vm_config.u-boot.json b/build/debian/vm_config.u-boot.json
new file mode 100644
index 0000000..463583f
--- /dev/null
+++ b/build/debian/vm_config.u-boot.json
@@ -0,0 +1,42 @@
+{
+    "name": "debian",
+    "disks": [
+        {
+            "partitions": [
+                {
+                    "label": "ROOT",
+                    "path": "$PAYLOAD_DIR/root_part",
+                    "writable": true,
+                    "guid": "{root_part_guid}"
+                },
+                {
+                    "label": "EFI",
+                    "path": "$PAYLOAD_DIR/efi_part",
+                    "writable": false,
+                    "guid": "{efi_part_guid}"
+                }
+            ],
+            "writable": true
+        }
+    ],
+    "sharedPath": [
+        {
+            "sharedPath": "/storage/emulated"
+        },
+        {
+            "sharedPath": "$APP_DATA_DIR/files"
+        }
+    ],
+    "protected": false,
+    "cpu_topology": "match_host",
+    "platform_version": "~1.0",
+    "memory_mib": 4096,
+    "debuggable": true,
+    "console_out": true,
+    "console_input_device": "ttyS0",
+    "network": true,
+    "auto_memory_balloon": true,
+    "gpu": {
+        "backend": "2d"
+    }
+}