98 lines
4.4 KiB
Markdown
98 lines
4.4 KiB
Markdown
# Summary of Work Done on April 10, 2026
|
||
|
||
## Overview
|
||
|
||
Today, work was done on the `OSDev_18` project to improve the kernel startup sequence and to make sure the kernel still boots correctly and prints output to the screen. The main focus was to add a minimal Global Descriptor Table (GDT) setup for the i386 version of the kernel and verify that it works as expected.
|
||
|
||
The project is set up to use a dev container, so the build and test steps were carried out in that environment. This was necessary because the container already includes the required cross-compilation and debugging tools.
|
||
|
||
## GDT Implementation
|
||
|
||
A minimal GDT was added for 32-bit protected mode. The implementation uses three entries:
|
||
|
||
1. A null descriptor
|
||
2. A kernel code segment descriptor
|
||
3. A kernel data segment descriptor
|
||
|
||
The code and data segments were configured with:
|
||
|
||
- base address `0x00000000`
|
||
- effective 4 GiB address space
|
||
- 4 KiB granularity
|
||
- ring 0 privilege level
|
||
|
||
The GDT setup code builds these descriptors in memory and prepares a GDT descriptor that can be loaded by the CPU.
|
||
|
||
After that, an assembly routine loads the new GDT with `lgdt`, performs a far jump to reload the code segment register, and then reloads the remaining segment registers for data access. This step is important because loading the GDT alone does not automatically update the segment registers already cached by the processor.
|
||
|
||
## Kernel Startup Changes
|
||
|
||
The kernel startup code was updated so that the GDT is initialized before the terminal is set up. After the GDT setup is finished, the terminal initialization still runs and the kernel prints `Hello, World!` to the VGA text buffer.
|
||
|
||
This means the boot flow now works roughly like this:
|
||
|
||
1. The bootloader transfers control to the kernel entry point.
|
||
2. The kernel starts execution in C code.
|
||
3. The GDT is initialized and loaded.
|
||
4. Segment registers are reloaded.
|
||
5. The VGA terminal is initialized.
|
||
6. `Hello, World!` is printed.
|
||
7. The kernel enters an infinite halt loop.
|
||
|
||
## Build System Changes
|
||
|
||
The build configuration was updated so the kernel now includes both the new C source for the GDT logic and the new assembly source for the reload routine. This ensures that the GDT implementation is compiled and linked into the kernel binary together with the rest of the startup code.
|
||
|
||
New build artifacts were generated today, including an updated kernel binary and bootable ISO image.
|
||
|
||
## Documentation Work
|
||
|
||
The project documentation was also improved today. Short explanations were added to describe:
|
||
|
||
- the general kernel boot flow
|
||
- where the GDT setup happens
|
||
- why `lgdt` is not enough on its own
|
||
- why a far jump and segment-register reload are required after loading the GDT
|
||
|
||
This was done to make the code easier to follow and to connect the implementation more clearly to the assignment requirements.
|
||
|
||
## Verification and Testing
|
||
|
||
The GDT implementation was tested in two ways.
|
||
|
||
### 1. Static inspection of the kernel binary
|
||
|
||
The built kernel binary was inspected to confirm that the expected GDT-related symbols were present and that the generated machine code actually contained:
|
||
|
||
- a call to load the GDT
|
||
- a far jump to selector `0x08`
|
||
- reloads of the data segment registers using selector `0x10`
|
||
|
||
This showed that the expected GDT setup sequence had been compiled into the kernel.
|
||
|
||
### 2. Runtime debugging in QEMU with GDB
|
||
|
||
The kernel was then started in QEMU and examined with `gdb-multiarch`. During this session, execution was stopped inside the GDT initialization code and inside the assembly reload routine.
|
||
|
||
The following results were observed:
|
||
|
||
- the GDT descriptor size was `0x17`, which matches three 8-byte entries minus 1
|
||
- the code segment entry was populated with the expected values
|
||
- after the far jump, the `cs` register changed to `0x08`
|
||
- after stepping through the segment reload instructions, `ds`, `es`, `fs`, `gs`, and `ss` all became `0x10`
|
||
|
||
These checks show that the processor did not just compile the code correctly, but also used the new GDT correctly at runtime.
|
||
|
||
## Current State at the End of the Day
|
||
|
||
At the end of today’s work, the `OSDev_18` kernel:
|
||
|
||
- builds inside the dev container
|
||
- includes a minimal i386 GDT implementation
|
||
- loads the GDT during kernel startup
|
||
- reloads the code and data segment registers correctly
|
||
- still initializes the VGA terminal
|
||
- still prints `Hello, World!` after boot
|
||
|
||
Based on the testing that was done today, the GDT implementation appears to be working correctly for this minimal protected-mode kernel setup.
|