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
10 changes: 10 additions & 0 deletions 02_Architecture/04_GDT.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,16 @@ A simple example is outline just below, for a simple 64-bit long mode setup we'd
- Selector 0x18: user code (64-bit, ring 3)
- Selector 0x20: user data (64-bit)

For future reference, we should define macros for these selectors. So let's assume we have the following:

```c
#define NULL_SELECTOR 0x00
#define KERNEL_CS 0x08
#define KERNEL_DS 0x10
#define USER_CS 0x18
#define USER_DS 0x20
```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we use them in the gdt code below? (gdt_entries[0] with i.e. gdt_entries[NULL] etc? )

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gdt_entries is an array of uint64_ts, that'd break unless it was shifted. IMO it's simpler to leave the below code as is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right!

Copy link
Contributor Author

@sudw1n sudw1n Jul 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, that's why I mentioned (in our conversation on Discord) that the author didn't use macros as it wasn't required/relevant there.


To create a GDT populated with these entries we'd do something like the following:

```c
Expand Down
2 changes: 1 addition & 1 deletion 05_Scheduling/02_Scheduler.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ For the purpose of our example the scheduler will only have three states for now

* READY: The process is in the queue and waiting to be scheduled.
* RUNNING: The process is currently running on the cpu.
* DEAD: The process has finished running and should not be scheduled. It's resources can also be cleaned up.
* DEAD: The process has finished running and should not be scheduled. Its resources can also be cleaned up.

We'll modify our selection algorithm to take these new states into account:

Expand Down
8 changes: 4 additions & 4 deletions 05_Scheduling/03_Processes_And_Threads.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ process_t* create_process(char* name, void(*function)(void*), void* arg) {
strncpy(process->name, name, NAME_MAX_LEN);
process->pid = next_free_pid++;
process->process_status = READY;
process->context.iret_ss = KERNEL_SS;
process->context.iret_ss = KERNEL_DS; // from the GDT chapter
process->context.iret_rsp = alloc_stack();
process->context.iret_flags = 0x202;
process->context.iret_cs = KERNEL_CS;
process->context.iret_cs = KERNEL_CS; // from the GDT chapter
process->context.iret_rip = (uint64_t)function;
process->context.rdi = (uint64_t)arg;
process->context.rbp = 0;
Expand Down Expand Up @@ -237,10 +237,10 @@ thread_t* add_thread(process_t* proc, char* name, void(*function)(void*), void*
thread->tid = next_thread_id++;
thread->status = READY;
thread->next = NULL:
thread->context.iret_ss = KERNEL_SS;
thread->context.iret_ss = KERNEL_DS; // from the GDT chapter
thread->context.iret_rsp = alloc_stack();
thread->context.iret_flags = 0x202;
thread->context.iret_cs = KERNEL_CS;
thread->context.iret_cs = KERNEL_CS; // from the GDT chapter
thread->context.iret_rip = (uint64_t)function;
thread->context.rdi = (uint64_t)arg;
thread->context.rbp = 0;
Expand Down