










[package] name = "bootable_graphics" version = "0.1.0" edition = "2021" [dependencies] uefi = "0.31" [profile.dev] panic = "abort" [profile.release] panic = "abort" opt-level = "s" lto = true
#![no_std]
#![no_main]
use uefi::prelude::*;
use uefi::proto::console::gop::{BltPixel, GraphicsOutput};
use uefi::table::boot::{OpenProtocolAttributes, OpenProtocolParams};
use uefi::table::runtime::ResetType;
use core::fmt::Write;
#[panic_handler]
fn panic_handler(_info: &core::panic::PanicInfo) -> ! {
loop {}
}
#[entry]
fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
// ---- 将图形操作放在独立块中,结束后 gop 被释放 ----
let (width, height) = {
let gop_handle = system_table
.boot_services()
.get_handle_for_protocol::<GraphicsOutput>()
.expect("此固件不支持图形输出协议 (GOP)");
let mut gop = unsafe {
system_table
.boot_services()
.open_protocol::<GraphicsOutput>(
OpenProtocolParams {
handle: gop_handle,
agent: image_handle,
controller: None,
},
OpenProtocolAttributes::GetProtocol,
)
.expect("无法打开图形输出协议")
};
let mode = gop.current_mode_info();
let (w, h) = mode.resolution();
let stride = mode.stride();
let mut fb = gop.frame_buffer();
// 蓝色背景
let blue = BltPixel::new(0, 0, 255);
unsafe {
for y in 0..h {
for x in 0..w {
let offset = y * stride + x * 4;
if offset + 4 <= fb.size() {
fb.write_value(offset, &blue);
}
}
}
}
// 中央红色矩形
let rect_x = w / 4;
let rect_y = h / 4;
let rect_w = w / 2;
let rect_h = h / 2;
let red = BltPixel::new(255, 0, 0);
unsafe {
for y in rect_y..(rect_y + rect_h).min(h) {
for x in rect_x..(rect_x + rect_w).min(w) {
let offset = y * stride + x * 4;
if offset + 4 <= fb.size() {
fb.write_value(offset, &red);
}
}
}
}
// gop 在这里离开作用域,对 system_table 的借用结束
(w, h)
};
// ---- 文本输出(此时 system_table 已无借用) ----
let stdout = system_table.stdout();
stdout.reset(false).unwrap();
stdout.clear().unwrap();
write!(stdout, "=== Bare Metal Graphics ===\n").unwrap();
write!(stdout, "Resolution: {}x{}\n", width, height).unwrap();
write!(stdout, "Press any key to reboot...\n").unwrap();
// ---- 等待按键 ----
let stdin = system_table.stdin();
while stdin.read_key().is_err() {}
// ---- 冷重启 ----
system_table.runtime_services().reset(
ResetType::COLD,
Status::SUCCESS,
None,
);
}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。