asdf
This commit is contained in:
parent
7d12f92a22
commit
953487dc11
11
Cargo.lock
generated
11
Cargo.lock
generated
|
@ -11,6 +11,12 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aligned-vec"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "android-tzdata"
|
name = "android-tzdata"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
@ -134,6 +140,7 @@ checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
|
||||||
name = "efigife"
|
name = "efigife"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aligned-vec",
|
||||||
"embedded-graphics",
|
"embedded-graphics",
|
||||||
"log",
|
"log",
|
||||||
"tinygif",
|
"tinygif",
|
||||||
|
@ -419,9 +426,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "1.0.22"
|
version = "1.0.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
|
checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spin"
|
name = "spin"
|
||||||
|
|
|
@ -6,6 +6,7 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
aligned-vec = { version = "0.5.0", default-features = false }
|
||||||
embedded-graphics.workspace = true
|
embedded-graphics.workspace = true
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
tinygif.workspace = true
|
tinygif.workspace = true
|
||||||
|
|
|
@ -3,26 +3,30 @@
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
use aligned_vec::{AVec, ConstAlign};
|
||||||
|
use alloc::vec::Vec;
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
|
|
||||||
use uefi::prelude::*;
|
use uefi::{prelude::*, CStr16};
|
||||||
|
|
||||||
use uefi::proto::console::gop::GraphicsOutput;
|
use uefi::proto::console::gop::GraphicsOutput;
|
||||||
use uefi::proto::loaded_image::LoadedImage;
|
use uefi::proto::loaded_image::LoadedImage;
|
||||||
use uefi::proto::media::block::{BlockIO, Lba};
|
use uefi::proto::media::block::{BlockIO, Lba};
|
||||||
|
use uefi::proto::media::file::{File, FileSystemVolumeLabel};
|
||||||
|
use uefi::proto::media::fs::SimpleFileSystem;
|
||||||
use uefi::proto::misc::Timestamp;
|
use uefi::proto::misc::Timestamp;
|
||||||
use uefi::table::boot::{OpenProtocolAttributes, OpenProtocolParams};
|
use uefi::table::boot::{OpenProtocolAttributes, OpenProtocolParams};
|
||||||
|
|
||||||
use uefi_graphics2::embedded_graphics::{pixelcolor::Rgb888, prelude::*};
|
use uefi_graphics2::embedded_graphics::{pixelcolor::Rgb888, prelude::*};
|
||||||
use uefi_graphics2::UefiDisplay;
|
use uefi_graphics2::UefiDisplay;
|
||||||
|
|
||||||
const GIF_SIZE: usize = include_bytes!("bad-apple.gif").len();
|
const GIF_SIZE: usize = ((include_bytes!("bad-apple.gif").len() + 511) / 512) * 512;
|
||||||
|
const VOLUME_LABEL: &CStr16 = cstr16!("EFIGIFEDEMO");
|
||||||
|
|
||||||
#[entry]
|
#[entry]
|
||||||
fn main(_image_handle: Handle, mut boot_system_table: SystemTable<Boot>) -> Status {
|
fn main(_image_handle: Handle, mut boot_system_table: SystemTable<Boot>) -> Status {
|
||||||
uefi::helpers::init(&mut boot_system_table).expect("helper init");
|
uefi::helpers::init(&mut boot_system_table).expect("helper init");
|
||||||
|
|
||||||
log::info!("hello!");
|
|
||||||
|
|
||||||
// Disable the watchdog timer
|
// Disable the watchdog timer
|
||||||
boot_system_table
|
boot_system_table
|
||||||
.boot_services()
|
.boot_services()
|
||||||
|
@ -34,11 +38,34 @@ fn main(_image_handle: Handle, mut boot_system_table: SystemTable<Boot>) -> Stat
|
||||||
boot_services.stall(1_000_000);
|
boot_services.stall(1_000_000);
|
||||||
|
|
||||||
let img_handle = boot_services.image_handle();
|
let img_handle = boot_services.image_handle();
|
||||||
let loaded_image = boot_services
|
let loaded_image_dev_path = boot_services
|
||||||
.open_protocol_exclusive::<LoadedImage>(img_handle)
|
.open_protocol_exclusive::<LoadedImageDevicePath>(img_handle)
|
||||||
.expect("loaded image");
|
.expect("loaded image");
|
||||||
|
|
||||||
let device_handle = loaded_image.device().expect("device handle");
|
loaded_image_dev_path.get()
|
||||||
|
|
||||||
|
let mut device_handle = loaded_image.device().expect("device handle");
|
||||||
|
|
||||||
|
/*
|
||||||
|
let handles = boot_services
|
||||||
|
.find_handles::<uefi::proto::media::fs::SimpleFileSystem>()
|
||||||
|
.expect("sfs handle");
|
||||||
|
for handle in handles {
|
||||||
|
let mut sfs = boot_services
|
||||||
|
.open_protocol_exclusive::<SimpleFileSystem>(handle)
|
||||||
|
.expect("sfs proto");
|
||||||
|
let mut root_dir = sfs.open_volume().expect("open volume");
|
||||||
|
let vol_info = root_dir
|
||||||
|
.get_boxed_info::<FileSystemVolumeLabel>()
|
||||||
|
.expect("root dir label");
|
||||||
|
if vol_info.volume_label() == VOLUME_LABEL {
|
||||||
|
assert_eq!(device_handle, handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TODO boot_services.locate_device_path()
|
||||||
|
// FIXME we currently have the fat partition, need the parent disk
|
||||||
|
|
||||||
let block_io = unsafe {
|
let block_io = unsafe {
|
||||||
boot_services.open_protocol::<BlockIO>(
|
boot_services.open_protocol::<BlockIO>(
|
||||||
|
@ -52,11 +79,18 @@ fn main(_image_handle: Handle, mut boot_system_table: SystemTable<Boot>) -> Stat
|
||||||
}
|
}
|
||||||
.expect("block io");
|
.expect("block io");
|
||||||
|
|
||||||
let mut gif_buf = [0u8; GIF_SIZE];
|
let mut gif_buf: AVec<u8, ConstAlign<512>> = AVec::with_capacity(512, GIF_SIZE);
|
||||||
|
// for _ in 0..GIF_SIZE {
|
||||||
|
for _ in 0..512 {
|
||||||
|
gif_buf.push(0u8);
|
||||||
|
}
|
||||||
|
|
||||||
block_io
|
block_io
|
||||||
.read_blocks(block_io.media().media_id(), Lba::from(0u64), &mut gif_buf)
|
.read_blocks(block_io.media().media_id(), Lba::from(0u64), &mut gif_buf)
|
||||||
.expect("read blocks");
|
.expect("read blocks");
|
||||||
|
|
||||||
|
panic!("{:x?}", &gif_buf[..32]);
|
||||||
|
|
||||||
let gif = tinygif::Gif::<Rgb888>::from_slice(&gif_buf).expect("gif from slice");
|
let gif = tinygif::Gif::<Rgb888>::from_slice(&gif_buf).expect("gif from slice");
|
||||||
|
|
||||||
// Get gop
|
// Get gop
|
||||||
|
@ -67,7 +101,6 @@ fn main(_image_handle: Handle, mut boot_system_table: SystemTable<Boot>) -> Stat
|
||||||
.open_protocol_exclusive::<GraphicsOutput>(gop_handle)
|
.open_protocol_exclusive::<GraphicsOutput>(gop_handle)
|
||||||
.expect("graphics output open");
|
.expect("graphics output open");
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
|
||||||
// Create UefiDisplay
|
// Create UefiDisplay
|
||||||
for mode in gop.modes(&boot_services).collect::<Vec<_>>() {
|
for mode in gop.modes(&boot_services).collect::<Vec<_>>() {
|
||||||
let (w, h) = mode.info().resolution();
|
let (w, h) = mode.info().resolution();
|
||||||
|
@ -137,3 +170,166 @@ fn main(_image_handle: Handle, mut boot_system_table: SystemTable<Boot>) -> Stat
|
||||||
|
|
||||||
Status::SUCCESS
|
Status::SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// uefi-rs book example for reference:
|
||||||
|
|
||||||
|
#![no_main]
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
|
use alloc::vec;
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
use uefi::prelude::*;
|
||||||
|
use uefi::proto::console::gop::{BltOp, BltPixel, BltRegion, GraphicsOutput};
|
||||||
|
use uefi::proto::loaded_image::LoadedImage;
|
||||||
|
use uefi::proto::media::block::{BlockIO, Lba};
|
||||||
|
use uefi::table::boot::{OpenProtocolAttributes, OpenProtocolParams};
|
||||||
|
use uefi::Result;
|
||||||
|
|
||||||
|
const GIF_SIZE: usize = include_bytes!("bad-apple.gif").len();
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Point {
|
||||||
|
fn new(x: f32, y: f32) -> Self {
|
||||||
|
Self { x, y }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Buffer {
|
||||||
|
width: usize,
|
||||||
|
height: usize,
|
||||||
|
pixels: Vec<BltPixel>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Buffer {
|
||||||
|
/// Create a new `Buffer`.
|
||||||
|
fn new(width: usize, height: usize) -> Self {
|
||||||
|
Buffer {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
pixels: vec![BltPixel::new(0, 0, 0); width * height],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a single pixel.
|
||||||
|
fn pixel(&mut self, x: usize, y: usize) -> Option<&mut BltPixel> {
|
||||||
|
self.pixels.get_mut(y * self.width + x)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Blit the buffer to the framebuffer.
|
||||||
|
fn blit(&self, gop: &mut GraphicsOutput) -> Result {
|
||||||
|
gop.blt(BltOp::BufferToVideo {
|
||||||
|
buffer: &self.pixels,
|
||||||
|
src: BltRegion::Full,
|
||||||
|
dest: (0, 0),
|
||||||
|
dims: (self.width, self.height),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_sierpinski(bt: &BootServices) -> Result {
|
||||||
|
// Open graphics output protocol.
|
||||||
|
let gop_handle = bt
|
||||||
|
.get_handle_for_protocol::<GraphicsOutput>()
|
||||||
|
.expect("gop handle");
|
||||||
|
let mut gop = bt
|
||||||
|
.open_protocol_exclusive::<GraphicsOutput>(gop_handle)
|
||||||
|
.expect("gop proto");
|
||||||
|
|
||||||
|
// Create a buffer to draw into.
|
||||||
|
let (width, height) = gop.current_mode_info().resolution();
|
||||||
|
let mut buffer = Buffer::new(width, height);
|
||||||
|
|
||||||
|
// Initialize the buffer with a simple gradient background.
|
||||||
|
for y in 0..height {
|
||||||
|
let r = ((y as f32) / ((height - 1) as f32)) * 255.0;
|
||||||
|
for x in 0..width {
|
||||||
|
let g = ((x as f32) / ((width - 1) as f32)) * 255.0;
|
||||||
|
let pixel = buffer.pixel(x, y).expect("gradient pixel");
|
||||||
|
pixel.red = r as u8;
|
||||||
|
pixel.green = g as u8;
|
||||||
|
pixel.blue = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let size = Point::new(width as f32, height as f32);
|
||||||
|
|
||||||
|
// Define the vertices of a big triangle.
|
||||||
|
let border = 20.0;
|
||||||
|
let triangle = [
|
||||||
|
Point::new(size.x / 2.0, border),
|
||||||
|
Point::new(border, size.y - border),
|
||||||
|
Point::new(size.x - border, size.y - border),
|
||||||
|
];
|
||||||
|
|
||||||
|
// `p` is the point to draw. Start at the center of the triangle.
|
||||||
|
let mut p = Point::new(size.x / 2.0, size.y / 2.0);
|
||||||
|
|
||||||
|
// Loop forever, drawing the frame after each new point is changed.
|
||||||
|
loop {
|
||||||
|
// Choose one of the triangle's vertices at random.
|
||||||
|
let v = triangle[1]; // chosen by fair dice roll.
|
||||||
|
|
||||||
|
// Move `p` halfway to the chosen vertex.
|
||||||
|
p.x = (p.x + v.x) * 0.5;
|
||||||
|
p.y = (p.y + v.y) * 0.5;
|
||||||
|
|
||||||
|
// Set `p` to black.
|
||||||
|
let pixel = buffer
|
||||||
|
.pixel(p.x as usize, p.y as usize)
|
||||||
|
.expect("black pixel");
|
||||||
|
pixel.red = 0;
|
||||||
|
pixel.green = 100;
|
||||||
|
pixel.blue = 0;
|
||||||
|
|
||||||
|
// Draw the buffer to the screen.
|
||||||
|
buffer.blit(&mut gop).expect("blit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[entry]
|
||||||
|
fn main(_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
|
||||||
|
uefi::helpers::init(&mut system_table).expect("table init");
|
||||||
|
let boot_services = system_table.boot_services();
|
||||||
|
|
||||||
|
// Disable the watchdog timer
|
||||||
|
boot_services
|
||||||
|
.set_watchdog_timer(0, 0x10000, None)
|
||||||
|
.expect("disable watchdog timer");
|
||||||
|
|
||||||
|
let img_handle = boot_services.image_handle();
|
||||||
|
let loaded_image = boot_services
|
||||||
|
.open_protocol_exclusive::<LoadedImage>(img_handle)
|
||||||
|
.expect("loaded image");
|
||||||
|
|
||||||
|
let device_handle = loaded_image.device().expect("device handle");
|
||||||
|
|
||||||
|
let block_io = unsafe {
|
||||||
|
boot_services.open_protocol::<BlockIO>(
|
||||||
|
OpenProtocolParams {
|
||||||
|
handle: device_handle,
|
||||||
|
agent: img_handle,
|
||||||
|
controller: None,
|
||||||
|
},
|
||||||
|
OpenProtocolAttributes::GetProtocol,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.expect("block io");
|
||||||
|
|
||||||
|
let mut gif_buf = Vec::new();
|
||||||
|
gif_buf.resize(GIF_SIZE, 0u8);
|
||||||
|
block_io
|
||||||
|
.read_blocks(block_io.media().media_id(), Lba::from(0u64), &mut gif_buf)
|
||||||
|
.expect("read blocks");
|
||||||
|
|
||||||
|
draw_sierpinski(boot_services).expect("sierpinski");
|
||||||
|
Status::SUCCESS
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -11,6 +11,9 @@ use fatfs::{
|
||||||
};
|
};
|
||||||
use mbrs::{Mbr, PartInfo, PartType};
|
use mbrs::{Mbr, PartInfo, PartType};
|
||||||
|
|
||||||
|
const RELEASE: bool = false;
|
||||||
|
const VOLUME_LABEL: [u8; 11] = *b"EFIGIFEDEMO";
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
enum Cpu {
|
enum Cpu {
|
||||||
X86_64,
|
X86_64,
|
||||||
|
@ -33,9 +36,10 @@ fn main() {
|
||||||
let cpu = match args
|
let cpu = match args
|
||||||
.pop_front()
|
.pop_front()
|
||||||
.unwrap_or(std::env::consts::ARCH.to_string())
|
.unwrap_or(std::env::consts::ARCH.to_string())
|
||||||
|
.to_lowercase()
|
||||||
.as_str()
|
.as_str()
|
||||||
{
|
{
|
||||||
"aarch64" | "arm64" => Cpu::AArch64,
|
"aarch64" | "arm64" | "aa64" => Cpu::AArch64,
|
||||||
"x86_64" | "x64" => Cpu::X86_64,
|
"x86_64" | "x64" => Cpu::X86_64,
|
||||||
x => unimplemented!("target cpu {:?}", x),
|
x => unimplemented!("target cpu {:?}", x),
|
||||||
};
|
};
|
||||||
|
@ -101,28 +105,26 @@ impl<T: Read + Write + Seek> FatWrite for MyStdIoWrapper<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_build(cpu: Cpu, _args: VecDeque<String>) {
|
fn do_build(cpu: Cpu, _args: VecDeque<String>) {
|
||||||
let build = "debug";
|
let mut cmd = Command::new(env!("CARGO"));
|
||||||
let build_success = Command::new(env!("CARGO"))
|
cmd.stdin(Stdio::inherit())
|
||||||
|
.stdout(Stdio::inherit())
|
||||||
|
.stderr(Stdio::inherit())
|
||||||
.arg("build")
|
.arg("build")
|
||||||
.arg("--bin")
|
.arg("--bin")
|
||||||
.arg("efigife")
|
.arg("efigife")
|
||||||
//.arg("--release")
|
|
||||||
.arg("--target")
|
.arg("--target")
|
||||||
.arg(format!("{}-unknown-uefi", cpu))
|
.arg(format!("{}-unknown-uefi", cpu));
|
||||||
.stdin(Stdio::inherit())
|
if RELEASE {
|
||||||
.stdout(Stdio::inherit())
|
cmd.arg("--release");
|
||||||
.stderr(Stdio::inherit())
|
}
|
||||||
.output()
|
let build_success = cmd.output().unwrap().status.success();
|
||||||
.unwrap()
|
|
||||||
.status
|
|
||||||
.success();
|
|
||||||
assert!(build_success);
|
assert!(build_success);
|
||||||
|
|
||||||
let efi_bin_path = format!(
|
let efi_bin_path = format!(
|
||||||
"{}/../target/{}-unknown-uefi/{}/efigife.efi",
|
"{}/../target/{}-unknown-uefi/{}/efigife.efi",
|
||||||
env!("CARGO_MANIFEST_DIR"),
|
env!("CARGO_MANIFEST_DIR"),
|
||||||
cpu,
|
cpu,
|
||||||
build
|
if RELEASE { "release" } else { "debug" }
|
||||||
);
|
);
|
||||||
let mut efi_bin_buf = Vec::new();
|
let mut efi_bin_buf = Vec::new();
|
||||||
let mut efi_bin_file = File::open(efi_bin_path).unwrap();
|
let mut efi_bin_file = File::open(efi_bin_path).unwrap();
|
||||||
|
@ -135,7 +137,9 @@ fn do_build(cpu: Cpu, _args: VecDeque<String>) {
|
||||||
let mut fat_disk = MyStdIoWrapper(Cursor::new(&mut fat_disk_buf));
|
let mut fat_disk = MyStdIoWrapper(Cursor::new(&mut fat_disk_buf));
|
||||||
fatfs::format_volume(
|
fatfs::format_volume(
|
||||||
&mut fat_disk,
|
&mut fat_disk,
|
||||||
FormatVolumeOptions::new().fat_type(fatfs::FatType::Fat12),
|
FormatVolumeOptions::new()
|
||||||
|
.fat_type(fatfs::FatType::Fat12)
|
||||||
|
.volume_label(VOLUME_LABEL),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let fat_fs = FileSystem::new(fat_disk, FsOptions::new()).unwrap();
|
let fat_fs = FileSystem::new(fat_disk, FsOptions::new()).unwrap();
|
||||||
|
@ -206,9 +210,13 @@ fn do_run(cpu: Cpu, args: VecDeque<String>) {
|
||||||
} else {
|
} else {
|
||||||
cmd.arg("-M").arg("virt,pflash0=code,gic-version=3");
|
cmd.arg("-M").arg("virt,pflash0=code,gic-version=3");
|
||||||
}
|
}
|
||||||
cmd.arg("-drive").arg(
|
cmd.arg("-drive")
|
||||||
"if=none,id=code,format=raw,file=/usr/share/qemu/edk2-aarch64-code.fd,readonly=on",
|
.arg("if=none,id=code,format=raw,file=/usr/share/qemu/edk2-aarch64-code.fd,readonly=on")
|
||||||
);
|
.arg("-device")
|
||||||
|
.arg("qemu-xhci")
|
||||||
|
.arg("-usb")
|
||||||
|
.arg("-device")
|
||||||
|
.arg("usb-kbd");
|
||||||
}
|
}
|
||||||
Cpu::X86_64 => {
|
Cpu::X86_64 => {
|
||||||
if kvm {
|
if kvm {
|
||||||
|
@ -222,9 +230,7 @@ fn do_run(cpu: Cpu, args: VecDeque<String>) {
|
||||||
cmd.arg("-global")
|
cmd.arg("-global")
|
||||||
.arg("ICH9-LPC.disable_s3=1")
|
.arg("ICH9-LPC.disable_s3=1")
|
||||||
.arg("-drive")
|
.arg("-drive")
|
||||||
.arg(
|
.arg("if=pflash,format=raw,unit=0,file=/usr/share/edk2-ovmf/OVMF_CODE.fd,readonly=on");
|
||||||
"if=pflash,format=raw,unit=0,file=/usr/share/edk2-ovmf/OVMF_CODE.fd,readonly=on",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmd.arg("-m")
|
cmd.arg("-m")
|
||||||
|
|
Loading…
Reference in a new issue