From 8910af12949c2e8ecc2112b84e2ef71de2ec8353 Mon Sep 17 00:00:00 2001 From: Zhang Junyang Date: Sun, 22 Oct 2023 10:57:33 +0800 Subject: [PATCH] Update grub to 2.12-rc1 for efi bugfix --- .github/workflows/cargo_check.yml | 4 +- .github/workflows/syscall_test.yml | 4 +- Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 4 +- VERSION | 2 +- runner/grub/grub.cfg.template | 2 +- runner/src/gdb.rs | 65 +++++++++++++++++++++++++++++ runner/src/machine/qemu_grub_efi.rs | 5 ++- runner/src/main.rs | 56 +------------------------ tools/docker/Dockerfile.ubuntu22.04 | 13 ++++-- 11 files changed, 90 insertions(+), 69 deletions(-) create mode 100644 runner/src/gdb.rs diff --git a/.github/workflows/cargo_check.yml b/.github/workflows/cargo_check.yml index 28aa12da..e25de41a 100644 --- a/.github/workflows/cargo_check.yml +++ b/.github/workflows/cargo_check.yml @@ -11,9 +11,9 @@ jobs: test: runs-on: ubuntu-latest timeout-minutes: 10 - container: jinuxdev/jinux:0.2.0 + container: jinuxdev/jinux:0.2.1 steps: - - run: echo "Running in jinuxdev/jinux:0.2.0" + - run: echo "Running in jinuxdev/jinux:0.2.1" - uses: actions/checkout@v3 diff --git a/.github/workflows/syscall_test.yml b/.github/workflows/syscall_test.yml index d1a7a118..2ef049d9 100644 --- a/.github/workflows/syscall_test.yml +++ b/.github/workflows/syscall_test.yml @@ -11,9 +11,9 @@ jobs: test: runs-on: ubuntu-latest timeout-minutes: 15 - container: jinuxdev/jinux:0.2.0 + container: jinuxdev/jinux:0.2.1 steps: - - run: echo "Running in jinuxdev/jinux:0.2.0" + - run: echo "Running in jinuxdev/jinux:0.2.1" - uses: actions/checkout@v3 diff --git a/Cargo.lock b/Cargo.lock index fa396883..359676ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -599,7 +599,7 @@ dependencies = [ [[package]] name = "jinux" -version = "0.2.0" +version = "0.2.1" dependencies = [ "component", "jinux-frame", diff --git a/Cargo.toml b/Cargo.toml index 75ed9401..d14c54fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "jinux" -version = "0.2.0" +version = "0.2.1" edition = "2021" [[bin]] diff --git a/README.md b/README.md index a3bbc069..fb3cd3e1 100644 --- a/README.md +++ b/README.md @@ -34,12 +34,12 @@ git clone [repository url] 2. After downloading the source code, run the following command to pull the development image. ```bash -docker pull jinuxdev/jinux:0.2.0 +docker pull jinuxdev/jinux:0.2.1 ``` 3. Start the development container. ```bash -docker run -it --privileged --network=host --device=/dev/kvm -v `pwd`:/root/jinux jinuxdev/jinux:0.2.0 +docker run -it --privileged --network=host --device=/dev/kvm -v `pwd`:/root/jinux jinuxdev/jinux:0.2.1 ``` **All build and test commands should be run inside the development container.** diff --git a/VERSION b/VERSION index 0ea3a944..0c62199f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.0 +0.2.1 diff --git a/runner/grub/grub.cfg.template b/runner/grub/grub.cfg.template index 77250369..fec85025 100644 --- a/runner/grub/grub.cfg.template +++ b/runner/grub/grub.cfg.template @@ -2,7 +2,7 @@ # AUTOMATICALLY GENERATED FILE, DO NOT EDIT IF YOU KNOW WHAT YOU ARE DOING -# set debug=linux,efi,relocator +# set debug=linux,efi set timeout_style=#GRUB_TIMEOUT_STYLE# set timeout=#GRUB_TIMEOUT# diff --git a/runner/src/gdb.rs b/runner/src/gdb.rs new file mode 100644 index 00000000..a976b1ca --- /dev/null +++ b/runner/src/gdb.rs @@ -0,0 +1,65 @@ +//! Providing the utility to run the GDB scripts for the runner. + +use crate::qemu_grub_efi; +use std::{fs::OpenOptions, io::Write, path::PathBuf, process::Command}; + +/// Run a GDB client. +/// +/// If argument `gdb_grub` is set true, it will run GRUB's gdb script. +/// +/// When debugging grub, the OVMF firmware will load the grub kernel at an +/// address unknown at the moment. You should use the debug message from our +/// custom built OVMF firmware and read the entrypoint address +/// (often `0x0007E685000`). Then use the following GDB command to load symbols: +/// `dynamic_load_symbols ${ENTRY_ADDRESS}`. +/// During each run, the address is unlikely to change. But the address will +/// depend on the versions of grub or OVMF. +/// +/// Also, do `set breakpoint pending on` when you want to break on GRUB modules. +pub fn run_gdb_client(path: &PathBuf, gdb_grub: bool) { + let path = std::fs::canonicalize(path).unwrap(); + let mut gdb_cmd = Command::new("gdb"); + // Set the architecture, otherwise GDB will complain about. + gdb_cmd.arg("-ex").arg("set arch i386:x86-64:intel"); + let grub_script = "/tmp/jinux-gdb-grub-script"; + if gdb_grub { + let grub_dir = PathBuf::from(qemu_grub_efi::GRUB_PREFIX) + .join("lib") + .join("grub") + .join(qemu_grub_efi::GRUB_VERSION); + // Load symbols from GRUB using the provided grub gdb script. + // Read the contents from `gdb_grub` and + // replace the lines containing "target remote :1234". + gdb_cmd.current_dir(&grub_dir); + let grub_script_content = std::fs::read_to_string(grub_dir.join("gdb_grub")).unwrap(); + let lines = grub_script_content.lines().collect::>(); + let mut f = OpenOptions::new() + .write(true) + .create(true) + .open(grub_script) + .unwrap(); + for line in lines { + if line.contains("target remote :1234") { + // Connect to the GDB server. + writeln!(f, "target remote /tmp/jinux-gdb-socket").unwrap(); + } else { + writeln!(f, "{}", line).unwrap(); + } + } + gdb_cmd.arg("-x").arg(grub_script); + } else { + // Load symbols from the kernel image. + gdb_cmd.arg("-ex").arg(format!("file {}", path.display())); + // Connect to the GDB server. + gdb_cmd + .arg("-ex") + .arg("target remote /tmp/jinux-gdb-socket"); + } + // Connect to the GDB server and run. + println!("running:{:#?}", gdb_cmd); + gdb_cmd.status().unwrap(); + if gdb_grub { + // Clean the temporary script file then return. + std::fs::remove_file(grub_script).unwrap(); + } +} diff --git a/runner/src/machine/qemu_grub_efi.rs b/runner/src/machine/qemu_grub_efi.rs index 8ea53a27..0894b3be 100644 --- a/runner/src/machine/qemu_grub_efi.rs +++ b/runner/src/machine/qemu_grub_efi.rs @@ -56,7 +56,7 @@ pub const IOMMU_DEVICE_ARGS: &[&str] = &[ "ioh3420,id=pcie.0,chassis=1", ]; -pub const GRUB_LIB_PREFIX: &str = "/usr/lib/grub"; +pub const GRUB_PREFIX: &str = "/usr/local/grub"; pub const GRUB_VERSION: &str = "x86_64-efi"; pub fn create_bootdev_image( @@ -109,7 +109,8 @@ pub fn create_bootdev_image( // Make the boot device CDROM image. let iso_path = target_dir.join(target_name.to_string() + ".iso"); - let mut cmd = std::process::Command::new("grub-mkrescue"); + let grub_mkrescue_bin = PathBuf::from(GRUB_PREFIX).join("bin").join("grub-mkrescue"); + let mut cmd = std::process::Command::new(grub_mkrescue_bin.as_os_str()); cmd.arg("--output").arg(&iso_path).arg(iso_root.as_os_str()); if !cmd.status().unwrap().success() { panic!("Failed to run `{:?}`.", cmd); diff --git a/runner/src/main.rs b/runner/src/main.rs index 928d0de6..be90e6ec 100644 --- a/runner/src/main.rs +++ b/runner/src/main.rs @@ -10,11 +10,11 @@ //! machine type. //! +pub mod gdb; pub mod machine; use std::{ fs::OpenOptions, - io::Write, path::{Path, PathBuf}, process::Command, }; @@ -117,58 +117,6 @@ pub const GDB_ARGS: &[&str] = &[ "-S", ]; -fn run_gdb_client(path: &PathBuf, gdb_grub: bool) { - let path = std::fs::canonicalize(path).unwrap(); - let mut gdb_cmd = Command::new("gdb"); - // Set the architecture, otherwise GDB will complain about. - gdb_cmd.arg("-ex").arg("set arch i386:x86-64:intel"); - let grub_script = "/tmp/jinux-gdb-grub-script"; - if gdb_grub { - let grub_dir = - PathBuf::from(qemu_grub_efi::GRUB_LIB_PREFIX).join(qemu_grub_efi::GRUB_VERSION); - // Load symbols from GRUB using the provided grub gdb script. - // Read the contents from `gdb_grub` and - // replace the lines containing "target remote :1234". - gdb_cmd.current_dir(&grub_dir); - let grub_script_content = std::fs::read_to_string(grub_dir.join("gdb_grub")).unwrap(); - let lines = grub_script_content.lines().collect::>(); - let mut f = OpenOptions::new() - .write(true) - .create(true) - .open(grub_script) - .unwrap(); - for line in lines { - if line.contains("file kernel.exec") { - writeln!(f, "{}", line).unwrap(); - // A horrible hack on GRUB EFI debugging. - // https://stackoverflow.com/questions/43872078/debug-grub2-efi-image-running-on-qemu - // Please use our custom built debug OVMF image to confirm the entrypoint address. - writeln!(f, "add-symbol-file kernel.exec 0x0007E69F000").unwrap(); - } else if line.contains("target remote :1234") { - // Connect to the GDB server. - writeln!(f, "target remote /tmp/jinux-gdb-socket").unwrap(); - } else { - writeln!(f, "{}", line).unwrap(); - } - } - gdb_cmd.arg("-x").arg(grub_script); - } else { - // Load symbols from the kernel image. - gdb_cmd.arg("-ex").arg(format!("file {}", path.display())); - // Connect to the GDB server. - gdb_cmd - .arg("-ex") - .arg("target remote /tmp/jinux-gdb-socket"); - } - // Connect to the GDB server and run. - println!("running:{:#?}", gdb_cmd); - gdb_cmd.status().unwrap(); - if gdb_grub { - // Clean the temporary script file then return. - std::fs::remove_file(grub_script).unwrap(); - } -} - fn main() { let args = Args::parse(); @@ -177,7 +125,7 @@ fn main() { // You should comment out the next line if you want to debug grub instead // of the kernel because this argument is not exposed by runner CLI. let gdb_grub = gdb_grub && false; - run_gdb_client(&args.path, gdb_grub); + gdb::run_gdb_client(&args.path, gdb_grub); return; } diff --git a/tools/docker/Dockerfile.ubuntu22.04 b/tools/docker/Dockerfile.ubuntu22.04 index ba6e376d..6a3b40ec 100644 --- a/tools/docker/Dockerfile.ubuntu22.04 +++ b/tools/docker/Dockerfile.ubuntu22.04 @@ -95,8 +95,14 @@ RUN source ./edksetup.sh \ FROM build-base as build-grub RUN apt update && apt-get install -y --no-install-recommends \ + autoconf \ + automake \ + autopoint \ bison \ - flex + flex \ + gawk \ + gettext \ + pkg-config RUN apt clean && rm -rf /var/lib/apt/lists/* FROM build-grub as grub @@ -107,12 +113,13 @@ FROM build-grub as grub # in the GRUB release. The Ubuntu release notoriously modifies the GRUB source code and enforce # EFI handover boot, which is deprecated. So we have to build GRUB from source. WORKDIR /root -RUN wget -O grub.tar.xz https://ftp.gnu.org/gnu/grub/grub-2.06.tar.xz \ +RUN wget -O grub.tar.xz https://git.savannah.gnu.org/cgit/grub.git/snapshot/grub-grub-2.12-rc1.tar.gz \ && mkdir /root/grub \ && tar xf grub.tar.xz --strip-components=1 -C /root/grub \ && rm grub.tar.xz WORKDIR /root/grub -RUN ./configure --target=x86_64 --with-platform=efi --prefix=/usr/local/grub \ +RUN ./bootstrap \ + && ./configure --target=x86_64 --with-platform=efi --prefix=/usr/local/grub \ && make -j \ && make install WORKDIR /root