Compare commits
No commits in common. "7d12f92a2276d2736d62dfdd26c7d19b9c172123" and "5b9f765be086cdfab36b50b089650e34725acab8" have entirely different histories.
7d12f92a22
...
5b9f765be0
45
Cargo.lock
generated
45
Cargo.lock
generated
|
@ -26,18 +26,6 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary-int"
|
||||
version = "1.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c84fc003e338a6f69fbd4f7fe9f92b535ff13e9af8997f3b14b6ddff8b1df46d"
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545"
|
||||
|
||||
[[package]]
|
||||
name = "atomic-polyfill"
|
||||
version = "1.0.3"
|
||||
|
@ -135,7 +123,6 @@ name = "efigife"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"embedded-graphics",
|
||||
"log",
|
||||
"tinygif",
|
||||
"uefi",
|
||||
"uefi-graphics2",
|
||||
|
@ -297,17 +284,6 @@ version = "0.4.21"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
|
||||
[[package]]
|
||||
name = "mbrs"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d080a720bb58430e0039347784859f9be41bf8578307b8156be4e02ca3b316e"
|
||||
dependencies = [
|
||||
"arbitrary-int",
|
||||
"arrayref",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.2"
|
||||
|
@ -469,26 +445,6 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinygif"
|
||||
version = "0.0.4"
|
||||
|
@ -740,5 +696,4 @@ name = "xtask"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"fatfs",
|
||||
"mbrs",
|
||||
]
|
||||
|
|
|
@ -12,8 +12,6 @@ resolver = "2"
|
|||
[workspace.dependencies]
|
||||
fatfs = { path = "rust-fatfs", default-features = false, features = ["alloc", "chrono"] }
|
||||
embedded-graphics = "0.8.1"
|
||||
log = "0.4.21"
|
||||
mbrs = "0.3.1"
|
||||
tinygif = { version = "0.0.4", features = ["8k"] }
|
||||
uefi = { version = "0.28.0", features = ["global_allocator", "panic_handler", "alloc"] }
|
||||
uefi-graphics2 = "0.1.3"
|
||||
|
|
|
@ -7,7 +7,6 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
embedded-graphics.workspace = true
|
||||
log.workspace = true
|
||||
tinygif.workspace = true
|
||||
uefi.workspace = true
|
||||
uefi-graphics2.workspace = true
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use core::time::Duration;
|
||||
|
||||
use uefi::prelude::*;
|
||||
|
@ -19,26 +17,22 @@ const GIF_SIZE: usize = include_bytes!("bad-apple.gif").len();
|
|||
|
||||
#[entry]
|
||||
fn main(_image_handle: Handle, mut boot_system_table: SystemTable<Boot>) -> Status {
|
||||
uefi::helpers::init(&mut boot_system_table).expect("helper init");
|
||||
|
||||
log::info!("hello!");
|
||||
uefi::helpers::init(&mut boot_system_table).unwrap();
|
||||
|
||||
// Disable the watchdog timer
|
||||
boot_system_table
|
||||
.boot_services()
|
||||
.set_watchdog_timer(0, 0x10000, None)
|
||||
.expect("disable watchdog timer");
|
||||
.unwrap();
|
||||
|
||||
let boot_services = boot_system_table.boot_services();
|
||||
|
||||
boot_services.stall(1_000_000);
|
||||
|
||||
let img_handle = boot_services.image_handle();
|
||||
let loaded_image = boot_services
|
||||
.open_protocol_exclusive::<LoadedImage>(img_handle)
|
||||
.expect("loaded image");
|
||||
.unwrap();
|
||||
|
||||
let device_handle = loaded_image.device().expect("device handle");
|
||||
let device_handle = loaded_image.device().unwrap();
|
||||
|
||||
let block_io = unsafe {
|
||||
boot_services.open_protocol::<BlockIO>(
|
||||
|
@ -50,56 +44,39 @@ fn main(_image_handle: Handle, mut boot_system_table: SystemTable<Boot>) -> Stat
|
|||
OpenProtocolAttributes::GetProtocol,
|
||||
)
|
||||
}
|
||||
.expect("block io");
|
||||
.unwrap();
|
||||
|
||||
let mut gif_buf = [0u8; GIF_SIZE];
|
||||
block_io
|
||||
.read_blocks(block_io.media().media_id(), Lba::from(0u64), &mut gif_buf)
|
||||
.expect("read blocks");
|
||||
.unwrap();
|
||||
|
||||
let gif = tinygif::Gif::<Rgb888>::from_slice(&gif_buf).expect("gif from slice");
|
||||
let gif = tinygif::Gif::<Rgb888>::from_slice(&gif_buf).unwrap();
|
||||
|
||||
// Get gop
|
||||
let gop_handle = boot_services
|
||||
.get_handle_for_protocol::<GraphicsOutput>()
|
||||
.expect("graphics output handle");
|
||||
.unwrap();
|
||||
let mut gop = boot_services
|
||||
.open_protocol_exclusive::<GraphicsOutput>(gop_handle)
|
||||
.expect("graphics output open");
|
||||
.unwrap();
|
||||
|
||||
use alloc::vec::Vec;
|
||||
// Create UefiDisplay
|
||||
for mode in gop.modes(&boot_services).collect::<Vec<_>>() {
|
||||
let (w, h) = mode.info().resolution();
|
||||
if w >= gif.width() as usize && h >= gif.height() as usize {
|
||||
match mode.info().pixel_format() {
|
||||
uefi::proto::console::gop::PixelFormat::Rgb
|
||||
| uefi::proto::console::gop::PixelFormat::Bgr => {
|
||||
if gop.set_mode(&mode).is_ok() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
uefi::proto::console::gop::PixelFormat::Bitmask
|
||||
| uefi::proto::console::gop::PixelFormat::BltOnly => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mode = gop.current_mode_info();
|
||||
let (res_w, res_h) = mode.resolution();
|
||||
let mut display = UefiDisplay::new(gop.frame_buffer(), mode);
|
||||
|
||||
// Tint the entire screen cyan
|
||||
display.fill_entire(Rgb888::BLACK).expect("fill black");
|
||||
display.fill_entire(Rgb888::BLACK).unwrap();
|
||||
|
||||
let timer_handle = boot_services
|
||||
.get_handle_for_protocol::<Timestamp>()
|
||||
.expect("timestamp handle");
|
||||
.unwrap();
|
||||
let timer = boot_services
|
||||
.open_protocol_exclusive::<Timestamp>(timer_handle)
|
||||
.expect("timestamp open");
|
||||
.unwrap();
|
||||
|
||||
let timer_hz = timer.get_properties().expect("timer props").frequency as f64;
|
||||
let timer_hz = timer.get_properties().unwrap().frequency as f64;
|
||||
|
||||
let start_timestamp = timer.get_timestamp();
|
||||
let mut gif_elapsed = Duration::new(0, 0);
|
||||
|
@ -113,9 +90,7 @@ fn main(_image_handle: Handle, mut boot_system_table: SystemTable<Boot>) -> Stat
|
|||
(res_h as i32 / gif.height() as i32) / 2,
|
||||
);
|
||||
for frame in gif.frames() {
|
||||
frame
|
||||
.draw(&mut display.translated(translation))
|
||||
.expect("frame draw");
|
||||
frame.draw(&mut display.translated(translation)).unwrap();
|
||||
gif_elapsed += Duration::from_millis(frame.delay_centis as u64 * 10);
|
||||
|
||||
// skip flush to catch up
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 5.9 KiB |
|
@ -7,4 +7,3 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
fatfs.workspace = true
|
||||
mbrs.workspace = true
|
||||
|
|
|
@ -9,43 +9,16 @@ use fatfs::{
|
|||
FileSystem, FormatVolumeOptions, FsOptions, IoBase, IoError, Read as FatRead, Seek as FatSeek,
|
||||
Write as FatWrite,
|
||||
};
|
||||
use mbrs::{Mbr, PartInfo, PartType};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum Cpu {
|
||||
X86_64,
|
||||
AArch64,
|
||||
}
|
||||
impl std::fmt::Display for Cpu {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(match self {
|
||||
Cpu::X86_64 => "x86_64",
|
||||
Cpu::AArch64 => "aarch64",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args: VecDeque<_> = std::env::args().skip(1).collect();
|
||||
|
||||
match args.pop_front() {
|
||||
Some(cmd) => {
|
||||
let cpu = match args
|
||||
.pop_front()
|
||||
.unwrap_or(std::env::consts::ARCH.to_string())
|
||||
.as_str()
|
||||
{
|
||||
"aarch64" | "arm64" => Cpu::AArch64,
|
||||
"x86_64" | "x64" => Cpu::X86_64,
|
||||
x => unimplemented!("target cpu {:?}", x),
|
||||
};
|
||||
|
||||
match cmd.as_str() {
|
||||
"build" => do_build(cpu, args),
|
||||
"run" => do_run(cpu, args),
|
||||
Some(cmd) => match cmd.as_str() {
|
||||
"build" => do_build(args),
|
||||
"run" => do_run(args),
|
||||
x => eprintln!("unknown command {:?}", x),
|
||||
}
|
||||
}
|
||||
},
|
||||
None => eprintln!("usage: cargo xtask [build|run] [x86_64|aarch64]"),
|
||||
}
|
||||
}
|
||||
|
@ -100,15 +73,14 @@ impl<T: Read + Write + Seek> FatWrite for MyStdIoWrapper<T> {
|
|||
}
|
||||
}
|
||||
|
||||
fn do_build(cpu: Cpu, _args: VecDeque<String>) {
|
||||
let build = "debug";
|
||||
let build_success = Command::new(env!("CARGO"))
|
||||
fn do_build(args: VecDeque<String>) {
|
||||
let build_success = Command::new("cargo")
|
||||
.arg("build")
|
||||
.arg("--bin")
|
||||
.arg("efigife")
|
||||
//.arg("--release")
|
||||
.arg("--release")
|
||||
.arg("--target")
|
||||
.arg(format!("{}-unknown-uefi", cpu))
|
||||
.arg("aarch64-unknown-uefi") // TODO: target according to arg
|
||||
.stdin(Stdio::inherit())
|
||||
.stdout(Stdio::inherit())
|
||||
.stderr(Stdio::inherit())
|
||||
|
@ -118,12 +90,11 @@ fn do_build(cpu: Cpu, _args: VecDeque<String>) {
|
|||
.success();
|
||||
assert!(build_success);
|
||||
|
||||
let efi_bin_path = format!(
|
||||
"{}/../target/{}-unknown-uefi/{}/efigife.efi",
|
||||
let efi_bin_path = concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
cpu,
|
||||
build
|
||||
"/../target/aarch64-unknown-uefi/release/efigife.efi"
|
||||
);
|
||||
eprintln!("{}", efi_bin_path);
|
||||
let mut efi_bin_buf = Vec::new();
|
||||
let mut efi_bin_file = File::open(efi_bin_path).unwrap();
|
||||
let efi_bin_size = efi_bin_file.read_to_end(&mut efi_bin_buf);
|
||||
|
@ -139,11 +110,7 @@ fn do_build(cpu: Cpu, _args: VecDeque<String>) {
|
|||
)
|
||||
.unwrap();
|
||||
let fat_fs = FileSystem::new(fat_disk, FsOptions::new()).unwrap();
|
||||
let boot_efi_name = match cpu {
|
||||
Cpu::AArch64 => "BOOTAA64.EFI",
|
||||
Cpu::X86_64 => "BOOTX64.EFI",
|
||||
};
|
||||
|
||||
let boot_efi_name = "BOOTAA64.EFI"; // TODO: parameterize on arg
|
||||
let mut boot_efi = fat_fs
|
||||
.root_dir()
|
||||
.create_dir("EFI")
|
||||
|
@ -163,82 +130,49 @@ fn do_build(cpu: Cpu, _args: VecDeque<String>) {
|
|||
let mut buf = Vec::new();
|
||||
let src_gif_size = src_gif_file.read_to_end(&mut buf).unwrap();
|
||||
drop(src_gif_file);
|
||||
|
||||
let fat_start_sector = (src_gif_size + 511) / 512;
|
||||
let fat_sector_count = (fat_disk_buf.len() + 511) / 512;
|
||||
buf.extend(std::iter::repeat(0).take(fat_start_sector * 512 - buf.len()));
|
||||
buf.extend(fat_disk_buf);
|
||||
|
||||
let mut mbr = Mbr::default();
|
||||
mbr.partition_table.entries[0] = Some(
|
||||
PartInfo::try_from_lba(
|
||||
true,
|
||||
fat_start_sector as u32,
|
||||
fat_sector_count as u32,
|
||||
PartType::Efi,
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
let fake_mbr_buf = <[u8; 512]>::try_from(&mbr).unwrap();
|
||||
buf[0x1be..0x200].copy_from_slice(&fake_mbr_buf[0x1be..0x200]);
|
||||
|
||||
let out_img_path = format!(
|
||||
"{}/../target/bad-apple.{}-efi.raw.gif",
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
cpu
|
||||
"aarch64"
|
||||
);
|
||||
let mut out_img_file = File::create(out_img_path).unwrap();
|
||||
out_img_file.write_all(&buf).unwrap();
|
||||
}
|
||||
|
||||
fn do_run(cpu: Cpu, args: VecDeque<String>) {
|
||||
do_build(cpu, args.clone());
|
||||
fn do_run(args: VecDeque<String>) {
|
||||
do_build(args.clone());
|
||||
|
||||
let mut cmd = Command::new(format!("qemu-system-{}", cpu));
|
||||
let kvm = cpu.to_string() == std::env::consts::ARCH;
|
||||
match cpu {
|
||||
Cpu::AArch64 => {
|
||||
if kvm {
|
||||
cmd.arg("-M")
|
||||
let mut cmd = match args[0].as_str() {
|
||||
"aarch64" | "arm64" => {
|
||||
let mut cmd = Command::new("qemu-system-aarch64");
|
||||
cmd.arg("-drive")
|
||||
.arg("if=none,id=code,format=raw,file=/usr/share/qemu/edk2-aarch64-code.fd,readonly=on")
|
||||
.arg("-M")
|
||||
.arg("virt,pflash0=code,accel=kvm,gic-version=3")
|
||||
.arg("-cpu")
|
||||
.arg("host");
|
||||
} else {
|
||||
cmd.arg("-M").arg("virt,pflash0=code,gic-version=3");
|
||||
}
|
||||
cmd.arg("-drive").arg(
|
||||
"if=none,id=code,format=raw,file=/usr/share/qemu/edk2-aarch64-code.fd,readonly=on",
|
||||
);
|
||||
}
|
||||
Cpu::X86_64 => {
|
||||
if kvm {
|
||||
cmd.arg("-M")
|
||||
.arg("q35,smm=on,accel=kvm")
|
||||
.arg("-cpu")
|
||||
.arg("host");
|
||||
} else {
|
||||
cmd.arg("-M").arg("q35,smm=on");
|
||||
}
|
||||
cmd.arg("-global")
|
||||
.arg("ICH9-LPC.disable_s3=1")
|
||||
.arg("-drive")
|
||||
.arg(
|
||||
"if=pflash,format=raw,unit=0,file=/usr/share/edk2-ovmf/OVMF_CODE.fd,readonly=on",
|
||||
);
|
||||
}
|
||||
}
|
||||
cmd.arg("-m")
|
||||
.arg("host")
|
||||
.arg("-m")
|
||||
.arg("512")
|
||||
.arg("-device")
|
||||
.arg("virtio-gpu-pci")
|
||||
.args(&args);
|
||||
.arg("virtio-gpu-pci");
|
||||
cmd
|
||||
}
|
||||
"x86_64" | "x64" => {
|
||||
//let mut cmd = Command::new("qemu-system-x86_64");
|
||||
todo!();
|
||||
}
|
||||
x => unimplemented!("target cpu {:?}", x),
|
||||
};
|
||||
let out_img_path = format!(
|
||||
"{}/../target/bad-apple.{}-efi.raw.gif",
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
cpu
|
||||
"aarch64"
|
||||
);
|
||||
cmd.arg("-drive")
|
||||
.arg(format!("format=raw,file={}", out_img_path))
|
||||
cmd.arg(out_img_path)
|
||||
.stdin(Stdio::inherit())
|
||||
.stdout(Stdio::inherit())
|
||||
.stderr(Stdio::inherit())
|
||||
|
|
Loading…
Reference in a new issue