Update grub to 2.12-rc1 for efi bugfix

This commit is contained in:
Zhang Junyang 2023-10-22 10:57:33 +08:00 committed by Tate, Hongliang Tian
parent 9c52f7aee7
commit 8910af1294
11 changed files with 90 additions and 69 deletions

View File

@ -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

View File

@ -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

2
Cargo.lock generated
View File

@ -599,7 +599,7 @@ dependencies = [
[[package]]
name = "jinux"
version = "0.2.0"
version = "0.2.1"
dependencies = [
"component",
"jinux-frame",

View File

@ -1,6 +1,6 @@
[package]
name = "jinux"
version = "0.2.0"
version = "0.2.1"
edition = "2021"
[[bin]]

View File

@ -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.**

View File

@ -1 +1 @@
0.2.0
0.2.1

View File

@ -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#

65
runner/src/gdb.rs Normal file
View File

@ -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::<Vec<_>>();
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();
}
}

View File

@ -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);

View File

@ -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::<Vec<_>>();
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;
}

View File

@ -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