Skip to content

Commit 3f51f3c

Browse files
committed
Use gutenberg's syntax for internal links
1 parent 7744a08 commit 3f51f3c

File tree

11 files changed

+52
-50
lines changed

11 files changed

+52
-50
lines changed

blog/content/extra/handling-exceptions-with-naked-fns/returning-from-exceptions.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ The breakpoint exception is commonly used in debuggers: When the user sets a bre
3737

3838
For our use case, we don't need to overwrite any instructions (it wouldn't even be possible since we [set the page table flags] to read-only). Instead, we just want to print a message when the breakpoint instruction is executed and then continue the program.
3939

40-
[set the page table flags]: {{% relref "07-remap-the-kernel.md#using-the-correct-flags" %}}
40+
[set the page table flags]: ./posts/07-remap-the-kernel/index.md#using-the-correct-flags
4141

4242
### Catching Breakpoints
4343
Let's start by defining a handler function for the breakpoint exception:
@@ -211,7 +211,7 @@ Instead of the expected _“It did not crash”_ message after the breakpoint ex
211211
### Debugging
212212
Let's debug it using GDB. For that we execute `make debug` in one terminal (which starts QEMU with the `-s -S` flags) and then `make gdb` (which starts and connects GDB) in a second terminal. For more information about GDB debugging, check out our [Set Up GDB] guide.
213213

214-
[Set Up GDB]: {{% relref "set-up-gdb.md" %}}
214+
[Set Up GDB]: ./extra/set-up-gdb.md
215215

216216
First we want to check if our `iretq` was successful. Therefore we set a breakpoint on the `println!("It did not crash line!")` statement in `src/lib.rs`. Let's assume that it's on line 61:
217217

@@ -299,7 +299,7 @@ Unfortunately, Rust does not support such a calling convention. It was [proposed
299299

300300
[interrupt calling conventions]: https://github.com/rust-lang/rfcs/pull/1275
301301
[Naked functions]: https://github.com/rust-lang/rfcs/blob/master/text/1201-naked-fns.md
302-
[naked fn post]: {{% relref "better-exception-messages.md#naked-functions" %}}
302+
[naked fn post]: ./extra/handling-exceptions-with-naked-fns/better-exception-messages.md#naked-functions
303303

304304
### A naked wrapper function
305305

@@ -567,7 +567,7 @@ It doesn't compile anymore. The error tells us that the Rust compiler no longer
567567
The [core library] is implicitly linked to all `no_std` crates and contains things such as `Result`, `Option`, and iterators. We've used that library without problems since [the very beginning], so why is it no longer available?
568568

569569
[core library]: https://doc.rust-lang.org/nightly/core/index.html
570-
[the very beginning]: {{% relref "03-set-up-rust.md" %}}
570+
[the very beginning]: ./posts/03-set-up-rust/index.md
571571

572572
The problem is that the core library is distributed together with the Rust compiler as a _precompiled_ library. So it is only valid for the host triple, which is `x86_64-unknown-linux-gnu` in our case. If we want to compile code for other targets, we need to recompile `core` for these targets first.
573573

blog/content/posts/01-multiboot-kernel/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ Idx Name Size VMA LMA File off Algn
188188
CONTENTS, ALLOC, LOAD, READONLY, CODE
189189
```
190190
_Note_: The `ld` and `objdump` commands are platform specific. If you're _not_ working on x86_64 architecture, you will need to [cross compile binutils]. Then use `x86_64‑elf‑ld` and `x86_64‑elf‑objdump` instead of `ld` and `objdump`.
191-
[cross compile binutils]: {{% relref "cross-compile-binutils.md" %}}
191+
[cross compile binutils]: ./extra/cross-compile-binutils.md
192192

193193
## Creating the ISO
194194
The last step is to create a bootable ISO image with GRUB. We need to create the following directory structure and copy the `kernel.bin` to the right place:
@@ -318,7 +318,7 @@ Now we can invoke `make` and all updated assembly files are compiled and linked.
318318

319319
In the [next post] we will create a page table and do some CPU configuration to switch to the 64-bit [long mode].
320320

321-
[next post]: {{% relref "02-entering-longmode.md" %}}
321+
[next post]: ./posts/02-entering-longmode/index.md
322322
[long mode]: https://en.wikipedia.org/wiki/Long_mode
323323

324324
## Footnotes

blog/content/posts/02-entering-longmode/index.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ aliases = [
1212

1313
In the [previous post] we created a minimal multiboot kernel. It just prints `OK` and hangs. The goal is to extend it and call 64-bit [Rust] code. But the CPU is currently in [protected mode] and allows only 32-bit instructions and up to 4GiB memory. So we need to set up _Paging_ and switch to the 64-bit [long mode] first.
1414

15-
[previous post]: {{% relref "01-multiboot-kernel.md" %}}
15+
[previous post]: ./posts/01-multiboot-kernel/index.md
1616
[Rust]: http://www.rust-lang.org/
1717
[protected mode]: https://en.wikipedia.org/wiki/Protected_mode
1818
[long mode]: https://en.wikipedia.org/wiki/Long_mode
@@ -40,7 +40,7 @@ error:
4040
At address `0xb8000` begins the so-called [VGA text buffer]. It's an array of screen characters that are displayed by the graphics card. A [future post] will cover the VGA buffer in detail and create a Rust interface to it. But for now, manual bit-fiddling is the easiest option.
4141

4242
[VGA text buffer]: https://en.wikipedia.org/wiki/VGA-compatible_text_mode
43-
[future post]: {{% relref "04-printing-to-screen.md" %}}
43+
[future post]: ./posts/04-printing-to-screen/index.md
4444

4545
A screen character consists of a 8 bit color code and a 8 bit [ASCII] character. We used the color code `4f` for all characters, which means white text on red background. `0x52` is an ASCII `R`, `0x45` is an `E`, `0x3a` is a `:`, and `0x20` is a space. The second space is overwritten by the given ASCII byte. Finally the CPU is stopped with the `hlt` instruction.
4646

@@ -494,8 +494,8 @@ _Congratulations_! You have successfully wrestled through this CPU configuration
494494
#### One Last Thing
495495
Above, we reloaded the code segment register `cs` with the new GDT offset. However, the data segment registers `ss`, `ds`, `es`, `fs`, and `gs` still contain the data segment offsets of the old GDT. This isn't necessarily bad, since they're ignored by almost all instructions in 64-bit mode. However, there are a few instructions that expect a valid data segment descriptor _or the null descriptor_ in those registers. An example is the the [iretq] instruction that we'll need in the [_Returning from Exceptions_] post.
496496

497-
[iretq]: {{% relref "returning-from-exceptions.md#the-iretq-instruction" %}}
498-
[_Returning from Exceptions_]: {{% relref "returning-from-exceptions.md" %}}
497+
[iretq]: ./extra/handling-exceptions-with-naked-fns/returning-from-exceptions.md#the-iretq-instruct/indexion
498+
[_Returning from Exceptions_]: ./extra/handling-exceptions-with-naked-fns/returning-from-exceptions.md
499499

500500
To avoid future problems, we reload all data segment registers with null:
501501

@@ -517,7 +517,7 @@ long_mode_start:
517517
It's time to finally leave assembly behind and switch to [Rust]. Rust is a systems language without garbage collections that guarantees memory safety. Through a real type system and many abstractions it feels like a high-level language but can still be low-level enough for OS development. The [next post] describes the Rust setup.
518518

519519
[Rust]: https://www.rust-lang.org/
520-
[next post]: {{% relref "03-set-up-rust.md" %}}
520+
[next post]: ./posts/03-set-up-rust/index.md
521521

522522
## Footnotes
523523
[^hardware_lookup]: In the x86 architecture, the page tables are _hardware walked_, so the CPU will look at the table on its own when it needs a translation. Other architectures, for example MIPS, just throw an exception and let the OS translate the virtual address.

blog/content/posts/03-set-up-rust/index.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ aliases = [
1313

1414
In the previous posts we created a [minimal Multiboot kernel][multiboot post] and [switched to Long Mode][long mode post]. Now we can finally switch to [Rust] code. Rust is a high-level language without runtime. It allows us to not link the standard library and write bare metal code. Unfortunately the setup is not quite hassle-free yet.
1515

16-
[multiboot post]: {{% relref "01-multiboot-kernel.md" %}}
17-
[long mode post]: {{% relref "02-entering-longmode.md" %}}
16+
[multiboot post]: ./posts/01-multiboot-kernel/index.md
17+
[long mode post]: ./posts/02-entering-longmode/index.md
1818
[Rust]: https://www.rust-lang.org/
1919

2020
<!-- more --><aside id="toc"></aside>
@@ -90,7 +90,7 @@ Let's define some properties of our target system:
9090
- **No SSE**: Our target might not have [SSE] support. Even if it does, we probably don't want to use SSE instructions in our kernel, because it makes interrupt handling much slower. We will explain this in detail in the [“Handling Exceptions”] post.
9191
- **No hardware floats**: The `x86_64` architecture uses SSE instructions for floating point operations, which we don't want to use (see the previous point). So we also need to avoid hardware floating point operations in our kernel. Instead, we will use _soft floats_, which are basically software functions that emulate floating point operations using normal integers.
9292

93-
[“Handling Exceptions”]: {{% relref "09-handling-exceptions.md" %}}
93+
[“Handling Exceptions”]: ./posts/09-handling-exceptions/index.md
9494

9595
### Target Specifications
9696
Rust allows us to define [custom targets] through a JSON configuration file. A minimal target specification equal to `x86_64-unknown-linux-gnu` (the default 64-bit Linux target) looks like this:
@@ -480,10 +480,10 @@ Some notes:
480480
### Stack Overflows
481481
Since we still use the small 64 byte [stack from the last post], we must be careful not to [overflow] it. Normally, Rust tries to avoid stack overflows through _guard pages_: The page below the stack isn't mapped and such a stack overflow triggers a page fault (instead of silently overwriting random memory). But we can't unmap the page below our stack right now since we currently use only a single big page. Fortunately the stack is located just above the page tables. So some important page table entry would probably get overwritten on stack overflow and then a page fault occurs, too.
482482

483-
[stack from the last post]: {{% relref "02-entering-longmode.md#creating-a-stack" %}}
483+
[stack from the last post]: ./posts/02-entering-longmode/index.md#creating-a-stack
484484
[overflow]: https://en.wikipedia.org/wiki/Stack_overflow
485485

486486
## What's next?
487487
Until now we write magic bits to some memory location when we want to print something to screen. In the [next post] we create a abstraction for the VGA text buffer that allows us to print strings in different colors and provides a simple interface.
488488

489-
[next post]: {{% relref "04-printing-to-screen.md" %}}
489+
[next post]: ./posts/04-printing-to-screen/index.md

blog/content/posts/04-printing-to-screen/index.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ aliases = [
1212

1313
In the [previous post] we switched from assembly to [Rust], a systems programming language that provides great safety. But so far we are using unsafe features like [raw pointers] whenever we want to print to screen. In this post we will create a Rust module that provides a safe and easy-to-use interface for the VGA text buffer. It will support Rust's [formatting macros], too.
1414

15-
[previous post]: {{% relref "03-set-up-rust.md" %}}
15+
[previous post]: ./posts/03-set-up-rust/index.md
1616
[Rust]: https://www.rust-lang.org/
1717
[raw pointers]: https://doc.rust-lang.org/book/raw-pointers.html
1818
[formatting macros]: https://doc.rust-lang.org/std/fmt/#related-macros
@@ -642,7 +642,7 @@ In the next posts we will map the kernel pages correctly so that accessing `0x0`
642642

643643
The [next post] describes the Multiboot information structure and creates a frame allocator using the information about memory areas.
644644

645-
[next post]: {{% relref "05-allocating-frames.md" %}}
645+
[next post]: ./posts/05-allocating-frames/index.md
646646

647647
## Other Rust OS Projects
648648
Now that you know the very basics of OS development in Rust, you should also check out the following projects:
@@ -651,7 +651,7 @@ Now that you know the very basics of OS development in Rust, you should also che
651651
_Note_: You need to [cross compile binutils] to build it (or you create some symbolic links[^fn-symlink] if you're on x86_64).
652652
[Rust Bare-Bones Kernel]: https://github.com/thepowersgang/rust-barebones-kernel
653653
[higher half]: http://wiki.osdev.org/Higher_Half_Kernel
654-
[cross compile binutils]: {{% relref "cross-compile-binutils.md" %}}
654+
[cross compile binutils]: ./posts/cross-compile-binutils/index.md
655655

656656
- [RustOS]: More advanced kernel that supports allocation, keyboard inputs, and threads. It also has a scheduler and a basic network driver.
657657
[RustOS]: https://github.com/RustOS-Fork-Holding-Ground/RustOS

blog/content/posts/05-allocating-frames/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -427,10 +427,10 @@ Now we have a working frame allocator. It is a bit rudimentary and cannot free f
427427
## What's next?
428428
The [next post] will be about paging again. We will use the frame allocator to create a safe module that allows us to switch page tables and map pages. Then we will use this module and the information from the Elf-sections tag to remap the kernel correctly.
429429

430-
[next post]: {{% relref "06-page-tables.md" %}}
430+
[next post]: ./posts/06-page-tables/index.md
431431

432432
## Recommended Posts
433433
Eric Kidd started the [Bare Metal Rust] series last week. Like this post, it builds upon the code from [Printing to Screen], but tries to support keyboard input instead of wrestling through memory management details.
434434

435435
[Bare Metal Rust]: http://www.randomhacks.net/bare-metal-rust/
436-
[Printing to Screen]: {{% relref "04-printing-to-screen.md" %}}
436+
[Printing to Screen]: ./posts/04-printing-to-screen/index.md

blog/content/posts/06-page-tables/index.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub struct Page {
5050
```
5151
We import the `PAGE_SIZE` and define a constant for the number of entries per table. To make future function signatures more expressive, we can use the type aliases `PhysicalAddress` and `VirtualAddress`. The `Page` struct is similar to the `Frame` struct in the [previous post], but represents a virtual page instead of a physical frame.
5252

53-
[previous post]: {{% relref "05-allocating-frames.md#a-memory-module" %}}
53+
[previous post]: ./posts/05-allocating-frames/index.md#a-memory-module
5454

5555
### Page Table Entries
5656
To model page table entries, we create a new `entry` submodule:
@@ -650,7 +650,7 @@ pub struct ActivePageTable {
650650
```
651651
We can't store the `Table<Level4>` directly because it needs to be at a special memory location (like the [VGA text buffer]). We could use a raw pointer or `&mut` instead of [Unique], but Unique indicates ownership better.
652652

653-
[VGA text buffer]: {{% relref "04-printing-to-screen.md#the-text-buffer" %}}
653+
[VGA text buffer]: ./posts/04-printing-to-screen/index.md#the-text-buffer
654654
[Unique]: https://doc.rust-lang.org/nightly/core/ptr/struct.Unique.html
655655

656656
Because the `ActivePageTable` owns the unique recursive mapped P4 table, there must be only one `ActivePageTable` instance. Thus we make the constructor function unsafe:
@@ -879,7 +879,7 @@ This post has become pretty long. So let's summarize what we've done:
879879
## What's next?
880880
In the [next post] we will extend this module and add a function to modify inactive page tables. Through that function, we will create a new page table hierarchy that maps the kernel correctly using 4KiB pages. Then we will switch to the new table to get a safer kernel environment.
881881

882-
[next post]: {{% relref "07-remap-the-kernel.md" %}}
882+
[next post]: ./posts/07-remap-the-kernel/index.md
883883

884884
Afterwards, we will use this paging module to build a heap allocator. This will allow us to use allocation and collection types such as `Box` and `Vec`.
885885

0 commit comments

Comments
 (0)