mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-21 16:37:48 +00:00
Compare commits
8 Commits
f557d1c698
...
edition-3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd3550ea87 | ||
|
|
ecb60ec326 | ||
|
|
8a1267477a | ||
|
|
ce01059620 | ||
|
|
4d0c3ac188 | ||
|
|
d565cd125b | ||
|
|
ca86085360 | ||
|
|
5f3d38884c |
@@ -75,7 +75,7 @@ This structure has the following general format:
|
|||||||
| 446 | partition entry 1 | 16 |
|
| 446 | partition entry 1 | 16 |
|
||||||
| 462 | partition entry 2 | 16 |
|
| 462 | partition entry 2 | 16 |
|
||||||
| 478 | partition entry 3 | 16 |
|
| 478 | partition entry 3 | 16 |
|
||||||
| 444 | partition entry 4 | 16 |
|
| 494 | partition entry 4 | 16 |
|
||||||
| 510 | boot signature | 2 |
|
| 510 | boot signature | 2 |
|
||||||
|
|
||||||
The bootstrap code is commonly called the _bootloader_ and responsible for loading and starting the operating system kernel.
|
The bootstrap code is commonly called the _bootloader_ and responsible for loading and starting the operating system kernel.
|
||||||
@@ -706,7 +706,7 @@ We then use the the `create_uefi_image` and `create_bios_image` methods to creat
|
|||||||
[requires build scripts]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script
|
[requires build scripts]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script
|
||||||
[`join`]: https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.join
|
[`join`]: https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.join
|
||||||
|
|
||||||
We can now use use a simple `cargo build` to cross-compile our kernel, build the bootloader, and combine them to create a bootable disk image:
|
We can now use a simple `cargo build` to cross-compile our kernel, build the bootloader, and combine them to create a bootable disk image:
|
||||||
|
|
||||||
```
|
```
|
||||||
❯ cargo build
|
❯ cargo build
|
||||||
@@ -1011,27 +1011,35 @@ Now we can create our `qemu-uefi` executable at `src/bin/qemu-uefi.rs`:
|
|||||||
|
|
||||||
```rust ,hl_lines=3-15
|
```rust ,hl_lines=3-15
|
||||||
// src/bin/qemu-uefi.rs
|
// src/bin/qemu-uefi.rs
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
env,
|
env, process::{self, Command}
|
||||||
process::{self, Command},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use ovmf_prebuilt::{Arch, FileType, Prebuilt, Source};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
let prebuilt =
|
||||||
|
Prebuilt::fetch(Source::LATEST, "target/ovmf").unwrap();
|
||||||
|
let ovmf_code = prebuilt.get_file(Arch::X64, FileType::Code);
|
||||||
|
let ovmf_vars = prebuilt.get_file(Arch::X64, FileType::Vars);
|
||||||
let mut qemu = Command::new("qemu-system-x86_64");
|
let mut qemu = Command::new("qemu-system-x86_64");
|
||||||
qemu.arg("-drive");
|
qemu.args([
|
||||||
qemu.arg(format!("format=raw,file={}", env!("UEFI_IMAGE")));
|
"-drive",
|
||||||
qemu.arg("-bios").arg(ovmf_prebuilt::ovmf_pure_efi());
|
&format!("format=raw,if=pflash,readonly=on,file={}", ovmf_code.display()),
|
||||||
|
"-drive",
|
||||||
|
&format!("format=raw,if=pflash,file={}", ovmf_vars.display()),
|
||||||
|
"-drive",
|
||||||
|
&format!("format=raw,file={}", env!("UEFI_IMAGE")),
|
||||||
|
]);
|
||||||
let exit_status = qemu.status().unwrap();
|
let exit_status = qemu.status().unwrap();
|
||||||
process::exit(exit_status.code().unwrap_or(-1));
|
process::exit(exit_status.code().unwrap_or(-1));
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
It's very similar to our `qemu-bios` executable.
|
It's very similar to our `qemu-bios` executable.
|
||||||
The only two differences are that it passes an additional `-bios` argument and that it uses the `UEFI_IMAGE` instead of the `BIOS_IMAGE`.
|
The only two differences are that it passes two additional `-drive if=pflash,..` arguments to load UEFI firmware (`OVMF_CODE.fd`) and writable NVRAM (`OVMF_VARS.fd`), and that it uses the `UEFI_IMAGE` instead of the `BIOS_IMAGE`.
|
||||||
Using a quick `cargo run --bin qemu-uefi`, we can confirm that it works as intended.
|
Using a quick `cargo run --bin qemu-uefi`, we can confirm that it works as intended.
|
||||||
|
|
||||||
|
|
||||||
### Screen Output
|
### Screen Output
|
||||||
|
|
||||||
While we see some screen output from the bootloader, our kernel still does nothing.
|
While we see some screen output from the bootloader, our kernel still does nothing.
|
||||||
|
|||||||
@@ -149,8 +149,6 @@ In the new module, we create basic structs for representing pixel positions and
|
|||||||
```rust ,hl_lines=3-16
|
```rust ,hl_lines=3-16
|
||||||
// in new kernel/src/framebuffer.rs file
|
// in new kernel/src/framebuffer.rs file
|
||||||
|
|
||||||
use bootloader_api::info::FrameBuffer;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct Position {
|
pub struct Position {
|
||||||
pub x: usize,
|
pub x: usize,
|
||||||
@@ -180,7 +178,7 @@ Next, we create a function for setting a specific pixel in the framebuffer to a
|
|||||||
```rust ,hl_lines=3 5-39
|
```rust ,hl_lines=3 5-39
|
||||||
// in new kernel/src/framebuffer.rs file
|
// in new kernel/src/framebuffer.rs file
|
||||||
|
|
||||||
use bootloader_api::info::PixelFormat;
|
use bootloader_api::info::{FrameBuffer, PixelFormat};
|
||||||
|
|
||||||
pub fn set_pixel_in(framebuffer: &mut FrameBuffer, position: Position, color: Color) {
|
pub fn set_pixel_in(framebuffer: &mut FrameBuffer, position: Position, color: Color) {
|
||||||
let info = framebuffer.info();
|
let info = framebuffer.info();
|
||||||
@@ -474,7 +472,7 @@ fn kernel_main(boot_info: &'static mut bootloader_api::BootInfo) -> ! {
|
|||||||
let frame_buffer_struct = frame_buffer_option.unwrap();
|
let frame_buffer_struct = frame_buffer_option.unwrap();
|
||||||
|
|
||||||
// extract the framebuffer info and, to satisfy the borrow checker, clone it
|
// extract the framebuffer info and, to satisfy the borrow checker, clone it
|
||||||
let frame_buffer_info = frame_buffer.info().clone();
|
let frame_buffer_info = frame_buffer_struct.info().clone();
|
||||||
|
|
||||||
// get the framebuffer's mutable raw byte slice
|
// get the framebuffer's mutable raw byte slice
|
||||||
let raw_frame_buffer = frame_buffer_struct.buffer_mut();
|
let raw_frame_buffer = frame_buffer_struct.buffer_mut();
|
||||||
|
|||||||
Reference in New Issue
Block a user