mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 22:37:49 +00:00
Some wording improvements
This commit is contained in:
@@ -33,7 +33,9 @@ Bit 4 is the _bright bit_, which turns for example blue into light blue. It is u
|
|||||||
[disable blinking]: http://www.ctyme.com/intr/rb-0117.htm
|
[disable blinking]: http://www.ctyme.com/intr/rb-0117.htm
|
||||||
|
|
||||||
## Creating a Rust Module
|
## Creating a Rust Module
|
||||||
Let's create the Rust module `vga_buffer`. Therefor we create a file named `src/vga_buffer.rs` and add a `mod vga_buffer` line to `src/lib.rs`. Now we can create an enum for the colors ([full file](#TODO)):
|
Now that we know how the VGA buffer works, we can create a Rust module to handle printing. To create a new module named `vga_buffer`, we just need to create a file named `src/vga_buffer.rs` and add a `mod vga_buffer` line to `src/lib.rs`.
|
||||||
|
|
||||||
|
First, we represent the different colors using an enum ([full file](#TODO)):
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
@@ -81,23 +83,23 @@ struct Buffer {
|
|||||||
chars: [[ScreenChar; BUFFER_WIDTH]; BUFFER_HEIGHT],
|
chars: [[ScreenChar; BUFFER_WIDTH]; BUFFER_HEIGHT],
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
To ensure that `ScreenChar` is exactly 16-bits, one might be tempted to use the [repr(packed)] attribute. But Rust does not insert any padding around two `u8` values, so it's not needed here. And `repr(packed)` can cause [undefined behavior][repr(packed) issue] and that's always bad.
|
To ensure that `ScreenChar` is exactly 16-bits, one might be tempted to use the [repr(packed)] attribute. But Rust does not insert any padding around two `u8` values, so it's not needed here. And using `repr(packed)` is generally discouraged because it can [cause undefined behavior][repr(packed) issue].
|
||||||
|
|
||||||
[repr(packed)]: https://doc.rust-lang.org/nightly/nomicon/other-reprs.html#repr(packed)
|
[repr(packed)]: https://doc.rust-lang.org/nightly/nomicon/other-reprs.html#reprpacked
|
||||||
[repr(packed) issue]: https://github.com/rust-lang/rust/issues/27060
|
[repr(packed) issue]: https://github.com/rust-lang/rust/issues/27060
|
||||||
|
|
||||||
To actually write to screen, we now create a writer type:
|
To actually write to screen, we now create a writer type:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
pub struct Writer<'a> {
|
pub struct Writer {
|
||||||
column_position: usize,
|
column_position: usize,
|
||||||
color_code: ColorCode,
|
color_code: ColorCode,
|
||||||
buffer: &'a mut Buffer,
|
buffer: Unique<Buffer>,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
The explicit lifetime tells Rust that the writer lives as long as the mutual buffer reference. Thus Rust ensures statically that the writer does not write to invalid memory.
|
The writer will always write to the last line and shift lines up when a line is full (or on `\n`). So just the current column position needs to be stored. The current foreground and background colors are specified by `color_code`. To make it possible to create a `static` Writer later, the `buffer` field stores an `Unique<Buffer>` instead of a plain `*mut Buffer`. [Unique] is a wrapper that implements Send/Sync and is thus usable as a `static` (we want to add static Writer later).
|
||||||
|
|
||||||
The writer will always write to the last line and shift lines up when a line is full (or on `\n`). So the current row is always the last row and just the current column position needs to be stored. The current foreground and background colors are specified by `color_code`.
|
[Unique]: https://doc.rust-lang.org/nightly/core/ptr/struct.Unique.html
|
||||||
|
|
||||||
### Printing Characters
|
### Printing Characters
|
||||||
Now we can use the `Writer` to modify the buffer's characters. First we create a method to write a single ASCII byte:
|
Now we can use the `Writer` to modify the buffer's characters. First we create a method to write a single ASCII byte:
|
||||||
|
|||||||
Reference in New Issue
Block a user