Skip to content

Commit 76d7d2d

Browse files
update blog
Signed-off-by: Henry Gressmann <[email protected]>
1 parent c771343 commit 76d7d2d

File tree

3 files changed

+71
-9
lines changed

3 files changed

+71
-9
lines changed

content/rust-os/1-hello-riscv/assets/boot1.svg

Lines changed: 46 additions & 0 deletions
Loading

content/rust-os/1-hello-riscv/index.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,9 @@ SBI (Supervisor Binary Interface) is a standard interface for interacting with t
129129

130130
The version shipping with QEMU uses a Jump Address ([_FW_JUMP_](https://github.com/riscv-software-src/opensbi/blob/master/docs/firmware/fw_jump.md)), in this case, `0x80200000`, which is where we'll be putting our kernel. QEMU will load our kernel into memory and jump to `0x80000000`, from where OpenSBI will then jump to `0x80200000`, where our kernel is located.
131131

132-
{{ figure(caption = "RISC-V Boot Flow", position="center", src="./assets/boot.svg") }}
132+
{{ figure(caption = "Traditional Boot Flow", position="center", src="./assets/boot1.svg") }}
133+
134+
{{ figure(caption = "QEMU RISC-V Boot Flow", position="center", src="./assets/boot.svg") }}
133135

134136
This architecture has a lot of benefits: SBI puts an abstraction layer between the kernel and the hardware, which allows us to write a single kernel that can run on any RISC-V CPU, regardless of the extensions it supports, as long as it has an SBI implementation. SBI also provides many functions like printing to and reading from the console, and it loads a flattened device tree (FDT) into memory, which we'll also be using later on to get information about the hardware.
135137

content/rust-os/2-shell/index.md

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,18 @@ transparent = true
33
title = "Creating a Kernel in Rust #2: Shell"
44
description = "Creating a simple shell for our kernel to run commands and help us debug"
55
date = 2023-05-14
6-
draft = true
76

87
[taxonomies]
98
tags = ["rust", "riscv", "kernel"]
109
series = ["rust-os"]
1110
+++
1211

12+
{% quote (class="info")%}
13+
14+
This is a series of posts about my journey creating a kernel in rust. You can find the code for this project [here](https://github.com/explodingcamera/pogos/tree/part-1) and all of the posts in this series [here](/series/os-dev/).
15+
16+
{% end %}
17+
1318
Now that we have a basic kernel that can print to the screen, we can start building out some more functionality.
1419
The first thing I want to do is create a simple shell that will allow us to run some commands and more easily interact with our system.
1520

@@ -33,20 +38,29 @@ First, we'll create a new file `src/linear-allocator.rs` and will create the bas
3338

3439
use core::sync::atomic::{AtomicUsize};
3540

36-
pub struct LinearAllocator<const T: usize> {
41+
pub struct LinearAllocator {
3742
head: AtomicUsize, // the current index of the buffer
3843
// AtomicUsize is a special type that allows us to safely share data
3944
// between threads without using locks
4045

41-
memory: [u8; T], // our in-memory "arena"
46+
start: *mut u8, // raw pointer to the start of the heap
47+
end: *mut u8, // raw pointer to the end of the heap
4248
}
43-
4449
// allow our allocator to be shared between threads
4550
unsafe impl Sync for LinearAllocator {}
4651

4752
impl LinearAllocator {
48-
pub fn init(buffer: &'static mut [u8]) -> Self {
49-
Self { head: AtomicUsize::new(0), memory }
53+
pub const fn empty() -> Self {
54+
Self {
55+
head: AtomicUsize::new(0),
56+
start: core::ptr::null_mut(),
57+
end: core::ptr::null_mut(),
58+
}
59+
}
60+
61+
pub fn init(&mut self, start: usize, size: usize) {
62+
self.start = start as *mut u8;
63+
self.end = unsafe { self.start.add(size) };
5064
}
5165
}
5266
```
@@ -60,8 +74,8 @@ use core::alloc::{GlobalAlloc, Layout};
6074
use core::ptr::NonNull;
6175
use core::sync::atomic::{Ordering};
6276

63-
unsafe impl<const T: usize> GlobalAlloc for LinearAllocator<T> {
64-
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
77+
unsafe impl GlobalAlloc for LinearAllocator {
78+
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
6579
/* The byte multiple that our allocated memory must start at
6680
most hardware architectures perform better when reading/writing
6781
data at aligned addresses (e.g. 4 bytes, 8 bytes, etc.) so we

0 commit comments

Comments
 (0)