interlude
This commit is contained in:
parent
83d1ce9b98
commit
f1570c06b1
|
|
@ -345,4 +345,57 @@ If we now run =cargo run=, cargo will build our kernel and automatically start q
|
|||
Unfortunately, since our kernel currently does nothing, this is hard to discern.
|
||||
Therefore, our next goal will be to get some output from our kernel, which we will do by making use of limine’s framebuffer.
|
||||
|
||||
* Interlude: Welcome to kernel-land
|
||||
If you have an aggressive LSP client, or you ran the =cargo clippy= command on our current crate, you may have noticed a warning telling you that an empty loop wastes CPU cycles.
|
||||
This is true, and is in fact the very reason why we use it!
|
||||
However, now that we have arrived in kernel-land, we can actually do a little better: the =hlt= instruction which, according to the Intel manual, stops execution of a logical processor until further notice.
|
||||
Further notice here may be an interrupt, which means we will want to run the =hlt= instruction in a loop.
|
||||
=hlt= is one of a handful of privileged instructions that when attempted to be executed in user-space will cause a general protection fault and terminate the program.
|
||||
|
||||
We start by creating a =lib.rs= file in the =src= directory, which will contain our kernel library code.
|
||||
Just line in our =main.rs=, we will need to tell the compiler that we want to opt out of the standard library:
|
||||
#+begin_src rust
|
||||
#![no_std]
|
||||
#+end_src
|
||||
|
||||
Since the =hlt= instruction is specific to the x86 architecture and not available in the =core::arch::x86_64= module of the core library, we will need to write our own wrapper around some inline assembly to execute the instruction.
|
||||
We create a new =x86_64= module in our new library to house this and future x86-64 specific code:
|
||||
|
||||
#+begin_src rust
|
||||
#![no_std]
|
||||
|
||||
pbu mod x86_64;
|
||||
#+end_src
|
||||
|
||||
#+begin_src rust
|
||||
#![cfg(target_arch = "x86_64")]
|
||||
|
||||
#[inline]
|
||||
pub fn hlt() {
|
||||
unsafe {
|
||||
core::arch::asm!("hlt", options(nomem, nostack, preserves_flags));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn halt_loop() -> ! {
|
||||
loop {
|
||||
hlt();
|
||||
}
|
||||
}
|
||||
#+end_src
|
||||
For a detailed explanation of the =asm!= macro, see the [[https://doc.rust-lang.org/nightly/reference/inline-assembly.html][Rust reference]].
|
||||
|
||||
In our =main.rs=, we can now replace the infinite loop with a call to our new =halt_loop= function:
|
||||
#+begin_src rust
|
||||
#[panic_handler]
|
||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
kernel::x86_64::halt_loop()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
fn _start() -> ! {
|
||||
kernel::x86_64::halt_loop()
|
||||
}
|
||||
#+end_src
|
||||
|
||||
* Getting the Framebuffer
|
||||
|
|
|
|||
1
kernel/.dir-locals.el
Normal file
1
kernel/.dir-locals.el
Normal file
|
|
@ -0,0 +1 @@
|
|||
((nil . ((eglot-workspace-configuration . (:rust-analyzer (:cargo (:extraEnv ((CARGO_UNSTABLE_JSON_TARGET_SPEC . "true")))))))))
|
||||
|
|
@ -3,4 +3,14 @@ name = "kernel"
|
|||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[[bin]]
|
||||
name = "kernel"
|
||||
path = "src/main.rs"
|
||||
test = false
|
||||
bench = false
|
||||
|
||||
[lib]
|
||||
test = false
|
||||
bench = false
|
||||
|
||||
[dependencies]
|
||||
|
|
|
|||
15
kernel/src/lib.rs
Normal file
15
kernel/src/lib.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#![no_std]
|
||||
|
||||
pub mod x86_64;
|
||||
|
||||
/// # Safety
|
||||
pub unsafe fn volatile_copy<T: Sized>(src: *const T, dst: *mut T, count: usize) {
|
||||
unsafe {
|
||||
for i in 0..count {
|
||||
let src_ptr = src.add(i);
|
||||
let dst_ptr = dst.add(i);
|
||||
let val = src_ptr.read_volatile();
|
||||
dst_ptr.write_volatile(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,10 +3,10 @@
|
|||
|
||||
#[panic_handler]
|
||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
loop {}
|
||||
kernel::x86_64::halt_loop()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
fn _start() -> ! {
|
||||
loop {}
|
||||
kernel::x86_64::halt_loop()
|
||||
}
|
||||
|
|
|
|||
14
kernel/src/x86_64.rs
Normal file
14
kernel/src/x86_64.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#![cfg(target_arch = "x86_64")]
|
||||
|
||||
#[inline]
|
||||
pub fn hlt() {
|
||||
unsafe {
|
||||
core::arch::asm!("hlt", options(nomem, nostack, preserves_flags));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn halt_loop() -> ! {
|
||||
loop {
|
||||
hlt();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue