Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 135 additions & 0 deletions design/STYLE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Style Guide for Design Files

<!-- Remember to update code example in ## Table of Contents -->
<!-- Table of Contents only links to level 2 headers -->
\[ [Table of Contents](#table-of-contents) \]
\[ [Inline Code](#inline-code) \]
\[ [Note and ToDO](#note-and-todo) \]
\[ [Alerts / Callouts / Admonitions](#alerts--callouts--admonitions) \]

## Table of Contents

The auto-generated bullet point list has very limited control over content and
styling with editors like vscode where the list is automatically updated. A
cleaner solution is a single line linking to the primary sections of the
document, showing only a single level (eg. all level 2 headers).

**Example** this is the ToC for this document. A comment is included to explain
what headers are included for future additions or changes.

```markdown
<!-- Table of Contents only links to level 2 headers -->
\[ [Table of Contents](#table-of-contents) \]
\[ [Inline Code](#inline-code) \]
\[ [Note and ToDO](#note-and-todo) \]
\[ [Alerts / Callouts / Admonitions](#alerts--callouts--admonitions) \]
```

One drawback is the need for manual updates, however these headers are not
frequently updated for well established documents.

## Inline Code

<!-- Why it's good -->
Inline code can be used to display potentially ambiguous characters (eg. lower
and upper case L, letter O and number 0) and to distinguish text from it's
surroundings like hexadecimal numbers (eg. `0x123`). It's use is not mandatory
and typically used as needed rather than by default.

<!-- Why it's bad -->
Inline code, however, reduce the contrast between text and background
making long strings of repeated characters more difficult to read (eg. `0000` vs
0000) or close, similar patterns of characters (eg. `0x0000` near `0x0600` vs
0x0000 near 0x06000). In most case, **bold** can be used to distinguish text
from it's surroundings (eg. **0x00000** near **0x06000**). Avoid using inline
code for tables, near formulas, in headers and in links. Exceptions can be made
when deemed necessary. Put a comment `<!-- -->` near these exceptional use cases
to explain why they are appropriate.

<!-- Examples, using text with bold instead of headers to avoid wasted space -->
**Good Usage** - Inline hexadecimal numbers with area between

> Kernel Size in Protected Mode is smaller than in real mode. Reserved memory in
> protected mode starts at `0x9fc00` while real mode starts at `0xa0000`

**Bad Usage** - Hexadecimal column values in a table, smaller font with lower contrast

> | Start | End | size | description |
> | -------- | --------- | --------- | -------------------------------------- |
> | `0x0000` | `0x4ff` | 1.25 KiB | Bad, small font with low contrast |
> | `0x0500` | `0x00fff` | 1.25 KiB | Bad, small font with low contrast |

Compared to

> | Start | End | size | description |
> | -------- | --------- | --------- | -------------------------------------- |
> | 0x7000 | 0x07bff | 3 KiB | Good, larger font with higher contrast |
> | 0x7c00 | 0x07dff | 512 bytes | Good, larger font with higher contrast |

**Bad Usage** - Mix of numbers with plain text numbers and inline code

>- Page size = 4096 (`0x1000`)
>- Bits per page = Page Size * 8 = 4096 * 8 = 32768 (`0x8000`)
>- Max pages per region = Bits per page = 32768 (`0x8000`) (includes bitmask page)
>- Max region size = Max pages per region * Page size = 32768 * 4096 = 134217728
> (`0x8000000`) = 128 MiB

**Bad Usage** - Numbers in formula without the operators

> Bits per page = Page Size * `8` = `4096` * `8` = `32768` (`0x8000`)

If you're going to quote a formula, include all operators and numbers in a
single quote. Exceptions can be made where impractical.

**Good Usage** - Formula including numbers and operators

> Bits per page = `Page Size * 8` = `4096 * 8` = `32768 (0x8000)`

**Bad Usage** - Quote entire line

> `Bits per page = Page Size * 8 = 4096 * 8 = 32768 (0x8000)`

If a quote spans the entire line, try to use a code block instead. Code blocks
use a larger font with higher contrast between letters and background.

> ```
> Bits per page = Page Size * 8 = 4096 * 8 = 32768 (0x8000)
> ```

## Note and ToDo

An alternative to alerts ia **Note** and **ToDo** (can also be upper case
**NOTE** and **TODO**). These are bold at the start of a paragraph followed by
non-bold text. **Note** is typically used to communicate details that may be
unintuitive or not obvious, but are not important enough to ues an alert.
**ToDo** is typically used as a note or reminder to the writer for future
content and communicates to the reader that a section may be incomplete or
inaccurate.

When used with all caps, **TODO** can also be highlighted by vscode using the
[TODO Highlights](https://marketplace.visualstudio.com/items?itemName=wayou.vscode-todo-highlight)
extension.

## Alerts / Callouts / Admonitions

Alerts can be useful to call attention to some information or visually break up
sections of text. To retain meaning and effectiveness at capturing the readers
attention, alerts should be uses sparingly and with short content.

**Note** In vscode, alerts can have an altered title by following the type `[!...]` with
some text. This fails to render in GitHub so should be avoided.

> [!NOTE]
> Note block

> [!TIP]
> Tip block

> [!IMPORTANT]
> Important block

> [!WARNING]
> Warning block

> [!CAUTION]
> Caution block
26 changes: 16 additions & 10 deletions design/boot_stages.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Boot Stages

<!-- Table of Contents only links to level 2 headers -->
\[ [Stage 0 - BIOS](#stage-0---bios) \]
\[ [Stage 1 - Boot](#stage-1---boot) \]
\[ [Stage 2 - Loader](#stage-2---loader) \]
\[ [Stage 3 - OS](#stage-3---os) \]

This describes the planned stages and steps, it does not represent the current
implementation or progress.

Expand All @@ -9,22 +15,22 @@ The BIOS firmware does a lot more than this, only the steps to launch the kernel
are included.

1. Power On Self Test (POST)
2. Load boot sector (512 Bytes) into memory at `0x7c00`
3. Jump to `0x7c00`
2. Load boot sector (512 Bytes) into memory at 0x7c00
3. Jump to 0x7c00

## Stage 1 - Boot

Execution of the first 512 bytes "boot sector".

1. Store boot drive id from `dl` register
2. Set stack `sp` and base `bp` pointers to `0x6fff`
3. Read memory map to `0x500`
1. Detect and store lower memory size using `int 0x12`
2. Detect upper memory regions using `int 0x15` with `aex = 0xe820`
4. Read stage 2 from boot drive to `0x7e00`
2. Set stack `sp` and base `bp` pointers to 0x6fff
3. Read memory map to 0x500
1. Detect and store lower memory size using interrupt 18 (`int 0x12`)
2. Detect upper memory regions using interrupt 18 (`int 0x15`) with aex = 0xe820
4. Read stage 2 from boot drive to 0x7e00
5. Setup GDT (kernel)
6. Switch to protected mode
7. Jump to loader at `0x7e00`
7. Jump to loader at 0x7e00

## Stage 2 - Loader

Expand All @@ -42,11 +48,11 @@ initialize the kernel then load and launch init program.
5. Initialize GDT
6. Initialize TSS
7. Enable paging
8. Initialize kernel (`kernel_init`)
8. Initialize kernel (**kernel_init**)
1. Clear kernel struct
2. Install ISR and IDT
3. Setup System Calls
4. Initialize `kmalloc`
4. Initialize **kmalloc**
5. (TMP) Setup Event Bus
6. Create Process Manager
7. Initialize Scheduler
Expand Down
2 changes: 2 additions & 0 deletions design/filesystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ The type show what the block type is.

Example to get decode an address

<!-- Using text instead of c because not much gets highlighted -->
```text
block = loc & 0xff
group = (loc >> 8) & 0x3fff
Expand All @@ -34,6 +35,7 @@ type = loc >> 30

Example to encode an address

<!-- Using text instead of c because not much gets highlighted -->
```text
address = block
address |= (group << 8)
Expand Down
70 changes: 39 additions & 31 deletions design/memory.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
# Memory Map

<!-- Table of Contents only links to level 2 headers -->
\[ [Real Mode](#real-mode) \]
\[ [Protected Mode](#protected-mode) \]
\[ [Physical Allocator](#physical-allocator-ramh) \]
\[ [Paging Allocator](#paging-allocator-memoryh) \]

## Real Mode

See https://wiki.osdev.org/Memory_Map_(x86) for reserved BIOS memory.
See [https://wiki.osdev.org/Memory_Map_(x86)](https://wiki.osdev.org/Memory_Map_(x86))
for reserved BIOS memory.

<!-- I'm not using inline code `0x...` for hex values because it makes them harder to read. -->
| start | end | size | description |
| ------ | ------- | --------- | --------------------------- |
| 0x0000 | 0x4ff | 1.25 KiB | Unusable |
Expand All @@ -13,9 +21,9 @@ See https://wiki.osdev.org/Memory_Map_(x86) for reserved BIOS memory.
| 0x7c00 | 0x07dff | 512 bytes | Boot Sector |
| 0x7e00 | 0x9fbff | 607.5 KiB | Kernel (second stage) |

> [!IMPORTANT] Kernel Size in Protected Mode
> Reserved memory in protected mode starts at 0x9fc00 while real mode starts at
> 0xa0000
> [!IMPORTANT]
> Kernel Size in Protected Mode is smaller than in real mode. Reserved memory in
> protected mode starts at 0x9fc00 while real mode starts at 0xa0000

### Boot Parameters

Expand All @@ -33,8 +41,7 @@ x is the value of Memory Entry Count * 24
#### Memory Entry

There is a single memory entry for each region of memory. It is possible to have
out of order and overlapping regions. See [BIOS Function: INT 0x15, EAX =
0xE820](https://wiki.osdev.org/Detecting_Memory_(x86)#BIOS_Function:_INT_0x15.2C_EAX_.3D_0xE820)
out of order and overlapping regions. See [BIOS Function: INT 0x15, EAX = 0xE820](https://wiki.osdev.org/Detecting_Memory_(x86)#BIOS_Function:_INT_0x15.2C_EAX_.3D_0xE820)

| start | size | description |
| ----- | ---- | ------------ |
Expand Down Expand Up @@ -76,28 +83,28 @@ ACPI 3.0 Extended Attributes
| ... | ... | ... | ... |
| 0xb8000 | 0xb8fff | 0x01000 | VGA Memory |

> [!IMPORTANT] Kernel Size in Protected Mode
> Reserved memory in protected mode starts at 0x9fc00 while real mode starts at
> 0xa0000
> [!IMPORTANT]
> Kernel Size in Protected Mode is smaller than in real mode. Reserved memory in
> protected mode starts at 0x9fc00 while real mode starts at 0xa0000

### Virtual Address Space (stage 2)

See https://wiki.osdev.org/Paging for information about page tables and
directory.
See [https://wiki.osdev.org/Paging](https://wiki.osdev.org/Paging) for
information about page tables and directory.

- The first page (0) is always null, accessing any address here will result in a
(page fault?)
- Each page directory and table contain 1024 entries
- 0x1000 will always point to the active page directory
- 0x2000 will always point to the ram region table
- 0xb9000 will always point to the first ram region bitmasks
- **0x1000** will always point to the active page directory
- **0x2000** will always point to the ram region table
- **0xb9000** will always point to the first ram region bitmasks
- There are 512 sequential pages of ram bitmasks ending at 0x2b9fff
- _0x400000 is the first virtual address of the second page table_
- _**0x400000** is the first virtual address of the second page table_
- It is suggested to keep kernel level memory bellow this address to allow
user space application switching out the second+ page table
- This can be used as the entry point address for all user space applications
- This region is ~3.99 GB
- 0xffc00000 will always point to the first page table (kernel table)
- **0xffc00000** will always point to the first page table (kernel table)
- This goes up to 0xffffffff as the last address in all of virtual space
- Each of the 1024 tables from the page directory are stored here sequentially
- The first table includes the null page and kernel memory mapping (see bellow)
Expand Down Expand Up @@ -148,11 +155,12 @@ pages in the region.
| 4 | 2 | page count |
| 8 | 2 | free count |

>[!IMPORTANT] Remember to mask the address
> The low 12 bits of each address are flags because the address is always page
> aligned. Remember to mask these bits when using the address.
> [!IMPORTANT]
> Remember to mask the address. The low 12 bits of each address are flags
> because the address is always page aligned. Remember to mask these bits when
> using the address.

> [!NOTE] Region size
> [!NOTE]
> Each region can be up to 128 MiB (32768 pages)
>- Page size = 4096 (0x1000)
>- Bits per page = Page Size * 8 = 4096 * 8 = 32768 (0x8000)
Expand All @@ -173,14 +181,14 @@ bitmask for the region showing which pages are free. Any bits outside of the
region should be set to 0 (ie. if the region is smaller than 128 MiB, bits for
any pages after the region end should be 0).

> [!IMPORTANT] Bitmask bit 1
> The first bit of the bitmask will always be 0 for the bitmask page itself.
> [!IMPORTANT]
> The first bit (bit 1) of the bitmask will always be 0 for the bitmask page itself.

## Paging Allocator (`memory.h`)

Paging allocator (aka `pmalloc` and `pfree`) is responsible for connecting the
physical memory allocator (ram) and page tables (mmu). This allocator keeps a
linked list of tables, 1022 entries each.
Paging allocator (aka **pmalloc** and **pfree**) is responsible for connecting
the physical memory allocator (ram) and page tables (mmu). This allocator keeps
a linked list of tables, 1022 entries each.

Each entry of the table describes a region of memory with address, flags and
size in bytes (page aligned).
Expand All @@ -198,21 +206,21 @@ There are a total of 511 entries per table.
### Memory Table Entries

The first 12 bits of a table entry are flags. The page number can be converted
to a memory address by shifting it left by 12 bits, or by using the max
(0xfffff000). Because the size is page aligned, the same strategy can be used
for getting the page number or memory address.
to a memory address by shifting it left by 12 bits, or by using the max of
0xfffff000. Because the size is page aligned, the same strategy can be used for
getting the page number or memory address.

| start | size | description |
| ----- | ---- | -------------------------------------- |
| 0 | 12 | flags |
| 12 | 20 | page no (address if flags masked away) |
| 32 | 32 | size in bytes (page aligned) |

> [!IMPORTANT] Size is page aligned
> [!IMPORTANT]
> The size is page aligned such that a page no / address + size points to the
> next valid, page aligned, address.

> [!NOTE] Size has unused bits
> [!NOTE]
> Because the size is page aligned, the first 12 bits should always be 0

#### Flags
Expand All @@ -233,4 +241,4 @@ the present flag set will be treated as the end of all entries.
- Memory tables can be moved and removed. Only a pointer to the first table
should be stored. All other tables are reachable via the linked list.

TODO - everything else here
**TODO** - everything else here
Loading