mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 22:37:49 +00:00
Fix links that pointed to a redirection page (#447)
This commit is contained in:
committed by
Philipp Oppermann
parent
3365a4f9ff
commit
3e570a8cfb
@@ -312,7 +312,7 @@ struct Buffer {
|
|||||||
```
|
```
|
||||||
Instead of a `ScreenChar`, we're now using a `Volatile<ScreenChar>`. (The `Volatile` type is [generic] and can wrap (almost) any type). This ensures that we can't accidentally write to it through a “normal” write. Instead, we have to use the `write` method now.
|
Instead of a `ScreenChar`, we're now using a `Volatile<ScreenChar>`. (The `Volatile` type is [generic] and can wrap (almost) any type). This ensures that we can't accidentally write to it through a “normal” write. Instead, we have to use the `write` method now.
|
||||||
|
|
||||||
[generic]: https://doc.rust-lang.org/book/generics.html
|
[generic]: https://doc.rust-lang.org/book/second-edition/ch10-00-generics.html
|
||||||
|
|
||||||
This means that we have to update our `Writer::write_byte` method:
|
This means that we have to update our `Writer::write_byte` method:
|
||||||
|
|
||||||
@@ -442,7 +442,7 @@ But we can't use it to print anything! You can try it yourself in the `print_som
|
|||||||
|
|
||||||
To resolve it, we could use a [mutable static]. But then every read and write to it would be unsafe since it could easily introduce data races and other bad things. Using `static mut` is highly discouraged, there are even proposals to [remove it][remove static mut].
|
To resolve it, we could use a [mutable static]. But then every read and write to it would be unsafe since it could easily introduce data races and other bad things. Using `static mut` is highly discouraged, there are even proposals to [remove it][remove static mut].
|
||||||
|
|
||||||
[mutable static]: https://doc.rust-lang.org/book/const-and-static.html#mutability
|
[mutable static]: https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html#accessing-or-modifying-a-mutable-static-variable
|
||||||
[remove static mut]: https://internals.rust-lang.org/t/pre-rfc-remove-static-mut/1437
|
[remove static mut]: https://internals.rust-lang.org/t/pre-rfc-remove-static-mut/1437
|
||||||
|
|
||||||
But what are the alternatives? We could try to use a cell type like [RefCell] or even [UnsafeCell] to provide [interior mutability]. But these types aren't [Sync] \(with good reason), so we can't use them in statics.
|
But what are the alternatives? We could try to use a cell type like [RefCell] or even [UnsafeCell] to provide [interior mutability]. But these types aren't [Sync] \(with good reason), so we can't use them in statics.
|
||||||
@@ -505,7 +505,7 @@ Note that we need to import the `Write` trait if we want to use its functions.
|
|||||||
## A println macro
|
## A println macro
|
||||||
Rust's [macro syntax] is a bit strange, so we won't try to write a macro from scratch. Instead we look at the source of the [`println!` macro] in the standard library:
|
Rust's [macro syntax] is a bit strange, so we won't try to write a macro from scratch. Instead we look at the source of the [`println!` macro] in the standard library:
|
||||||
|
|
||||||
[macro syntax]: https://doc.rust-lang.org/nightly/book/macros.html
|
[macro syntax]: https://doc.rust-lang.org/nightly/book/second-edition/appendix-04-macros.html
|
||||||
[`println!` macro]: https://doc.rust-lang.org/nightly/std/macro.println!.html
|
[`println!` macro]: https://doc.rust-lang.org/nightly/std/macro.println!.html
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
|||||||
@@ -316,7 +316,7 @@ pub fn init() {
|
|||||||
There are two problems with this. First, statics are immutable, so we can't modify the breakpoint entry from our `init` function. Second, the `Idt::new` function is not a [`const` function], so it can't be used to initialize a `static`. We could solve this problem by using a [`static mut`] of type `Option<Idt>`:
|
There are two problems with this. First, statics are immutable, so we can't modify the breakpoint entry from our `init` function. Second, the `Idt::new` function is not a [`const` function], so it can't be used to initialize a `static`. We could solve this problem by using a [`static mut`] of type `Option<Idt>`:
|
||||||
|
|
||||||
[`const` function]: https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md
|
[`const` function]: https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md
|
||||||
[`static mut`]: https://doc.rust-lang.org/book/const-and-static.html#mutability
|
[`static mut`]: https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html#accessing-or-modifying-a-mutable-static-variable
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
static mut IDT: Option<Idt> = None;
|
static mut IDT: Option<Idt> = None;
|
||||||
@@ -333,7 +333,7 @@ pub fn init() {
|
|||||||
|
|
||||||
This variant compiles without errors but it's far from idiomatic. `static mut`s are very prone to data races, so we need an [`unsafe` block] on each access. Also, we need to explicitly `unwrap` the `IDT` on each use, since might be `None`.
|
This variant compiles without errors but it's far from idiomatic. `static mut`s are very prone to data races, so we need an [`unsafe` block] on each access. Also, we need to explicitly `unwrap` the `IDT` on each use, since might be `None`.
|
||||||
|
|
||||||
[`unsafe` block]: https://doc.rust-lang.org/book/unsafe.html#unsafe-superpowers
|
[`unsafe` block]: https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html#unsafe-superpowers
|
||||||
|
|
||||||
#### Lazy Statics to the Rescue
|
#### Lazy Statics to the Rescue
|
||||||
The one-time initialization of statics with non-const functions is a common problem in Rust. Fortunately, there already exists a good solution in a crate named [lazy_static]. This crate provides a `lazy_static!` macro that defines a lazily initialized `static`. Instead of computing its value at compile time, the `static` laziliy initializes itself when it's accessed the first time. Thus, the initialization happens at runtime so that arbitrarily complex initialization code is possible.
|
The one-time initialization of statics with non-const functions is a common problem in Rust. Fortunately, there already exists a good solution in a crate named [lazy_static]. This crate provides a `lazy_static!` macro that defines a lazily initialized `static`. Instead of computing its value at compile time, the `static` laziliy initializes itself when it's accessed the first time. Thus, the initialization happens at runtime so that arbitrarily complex initialization code is possible.
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ struct Buffer {
|
|||||||
```
|
```
|
||||||
Instead of a `ScreenChar`, we're now using a `Volatile<ScreenChar>`. (The `Volatile` type is [generic] and can wrap (almost) any type). This ensures that we can't accidentally write to it through a “normal” write. Instead, we have to use the `write` method now.
|
Instead of a `ScreenChar`, we're now using a `Volatile<ScreenChar>`. (The `Volatile` type is [generic] and can wrap (almost) any type). This ensures that we can't accidentally write to it through a “normal” write. Instead, we have to use the `write` method now.
|
||||||
|
|
||||||
[generic]: https://doc.rust-lang.org/book/generics.html
|
[generic]: https://doc.rust-lang.org/book/second-edition/ch10-00-generics.html
|
||||||
|
|
||||||
This means that we have to update our `Writer::write_byte` method:
|
This means that we have to update our `Writer::write_byte` method:
|
||||||
|
|
||||||
@@ -543,7 +543,7 @@ Note that we only have a single unsafe block in our code, which is needed to cre
|
|||||||
### A println Macro
|
### A println Macro
|
||||||
Now that we have a global writer, we can add a `println` macro that can be used from anywhere in the codebase. Rust's [macro syntax] is a bit strange, so we won't try to write a macro from scratch. Instead we look at the source of the [`println!` macro] in the standard library:
|
Now that we have a global writer, we can add a `println` macro that can be used from anywhere in the codebase. Rust's [macro syntax] is a bit strange, so we won't try to write a macro from scratch. Instead we look at the source of the [`println!` macro] in the standard library:
|
||||||
|
|
||||||
[macro syntax]: https://doc.rust-lang.org/nightly/book/macros.html
|
[macro syntax]: https://doc.rust-lang.org/nightly/book/second-edition/appendix-04-macros.html
|
||||||
[`println!` macro]: https://doc.rust-lang.org/nightly/std/macro.println!.html
|
[`println!` macro]: https://doc.rust-lang.org/nightly/std/macro.println!.html
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
|||||||
@@ -317,7 +317,7 @@ pub fn init_idt() {
|
|||||||
|
|
||||||
However, there is a problem: Statics are immutable, so we can't modify the breakpoint entry from our `init` function. We could solve this problem by using a [`static mut`]:
|
However, there is a problem: Statics are immutable, so we can't modify the breakpoint entry from our `init` function. We could solve this problem by using a [`static mut`]:
|
||||||
|
|
||||||
[`static mut`]: https://doc.rust-lang.org/book/const-and-static.html#mutability
|
[`static mut`]: https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html#accessing-or-modifying-a-mutable-static-variable
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
static mut IDT: Option<Idt> = Idt::new();
|
static mut IDT: Option<Idt> = Idt::new();
|
||||||
@@ -332,7 +332,7 @@ pub fn init_idt() {
|
|||||||
|
|
||||||
This variant compiles without errors but it's far from idiomatic. `static mut`s are very prone to data races, so we need an [`unsafe` block] on each access.
|
This variant compiles without errors but it's far from idiomatic. `static mut`s are very prone to data races, so we need an [`unsafe` block] on each access.
|
||||||
|
|
||||||
[`unsafe` block]: https://doc.rust-lang.org/book/unsafe.html#unsafe-superpowers
|
[`unsafe` block]: https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html#unsafe-superpowers
|
||||||
|
|
||||||
#### Lazy Statics to the Rescue
|
#### Lazy Statics to the Rescue
|
||||||
Fortunately the `lazy_static` macro exists. Instead of evaluating a `static` at compile time, the macro performs the initialization when the `static` is referenced the first time. Thus, we can do almost everything in the initialization block and are even able to read runtime values.
|
Fortunately the `lazy_static` macro exists. Instead of evaluating a `static` at compile time, the macro performs the initialization when the `static` is referenced the first time. Thus, we can do almost everything in the initialization block and are even able to read runtime values.
|
||||||
|
|||||||
Reference in New Issue
Block a user