File 007-Uncompress-kernel-on-RISC-V.patch of Package supermin.36320

Subject: src: Uncompress kernel on RISC-V
From: Richard W.M. Jones rjones@redhat.com Fri Nov 10 10:20:49 2023 +0000
Date: Fri Nov 10 10:28:21 2023 +0000:
Git: 5230e2c3cd07e82bd6431e871e239f7056bf25ad


diff --git a/src/format_ext2_kernel.ml b/src/format_ext2_kernel.ml
index 36514c6..09a3f21 100644
--- a/src/format_ext2_kernel.ml
+++ b/src/format_ext2_kernel.ml
@@ -25,6 +25,20 @@ open Ext2fs
 open Fnmatch
 open Glob
 
+(* Similar but not the same as get_file_type in mode_build.  There
+ * is a case for deriving a common base utility. XXX
+ *)
+type compression_type = GZip | Uncompressed
+let get_compression_type file =
+  let chan = open_in file in
+  let buf = Bytes.create 512 in
+  let len = input chan buf 0 (Bytes.length buf) in
+  close_in chan;
+  let buf = Bytes.to_string buf in
+  if len >= 3 && buf.[0] = '\x1f' && buf.[1] = '\x8b' && buf.[2] = '\x08'
+  then GZip
+  else Uncompressed (* or other unknown compression type *)
+
 let rec build_kernel debug host_cpu copy_kernel kernel =
   (* Locate the kernel.
    * SUPERMIN_* environment variables override everything.  If those
@@ -54,7 +68,19 @@ let rec build_kernel debug host_cpu copy_kernel kernel =
     printf "supermin: kernel: modpath %s\n%!" modpath;
   );
 
-  copy_or_symlink_kernel copy_kernel kernel_file kernel;
+  (* RISC-V relies on the bootloader or firmware to uncompress the
+   * kernel and doesn't have a concept of self-extracting kernels.
+   * On Arm which is similar, qemu -kernel will automatically uncompress
+   * the kernel, but qemu-system-riscv won't do that and the code is a
+   * big mess so I don't fancy fixing it.  So we have to detect that
+   * case here and uncompress the kernel.
+   *)
+  let kernel_compression_type = get_compression_type kernel_file in
+  if string_prefix "riscv" host_cpu && kernel_compression_type <> Uncompressed
+  then
+    copy_and_uncompress_kernel kernel_compression_type kernel_file kernel
+  else
+    copy_or_symlink_kernel copy_kernel kernel_file kernel;
 
   (kernel_version, modpath)
 
@@ -308,6 +334,13 @@ and read_string chan offset len =
   really_input chan buf 0 len;
   Bytes.to_string buf
 
+and copy_and_uncompress_kernel compression_type src dest =
+  let cmd =
+    match compression_type with
+    | GZip -> sprintf "zcat %s > %s" (quote src) (quote dest)
+    | Uncompressed -> sprintf "cp %s %s" (quote src) (quote dest) in
+  run_command cmd
+
 and copy_or_symlink_kernel copy_kernel src dest =
   if not copy_kernel then
     symlink src dest
openSUSE Build Service is sponsored by