Not logged inTalkContributionsCreate accountLog in

Architecture & Boot

From nexOS Wiki
Kernel topology, entry points, protected-mode switch, memory map

Contents

[hide]

Kernel topology

nexOS is monolithic: bootloader, kernel, ATA/FAT32 storage, RTL8139 networking, and the entire GUI are linked into a single flat image that runs at privilege level 0. There is no kernel/userspace split and no module loading. “Applications” (Paint, terminal, browser, file manager) are C functions called from main().

                 +------------------------------+
                 |  nexos.img  (32 KiB raw)     |
                 +--------------+----------------+
                 | sector 0     | sectors 1..63  |
                 | boot.asm     | kernel.bin     |
                 | (512 B)      | (objcopy)      |
                 +------+-------+----------------+
                        | BIOS INT 13h, 60 sectors to 0x8000
                        v
                 +--------------+  +---------------------------+
                 |  boot.asm    |  |  kernel (flat, ring 0)    |
                 |  real mode   |  |  _start -> _main -> main()  |
                 |  -> prot.mode |  |  paging + drivers + GUI   |
                 +--------------+  +---------------------------+

Entry-point chain

Three symbols stand between the CPU and the first line of C:

[boot.asm]  init_pm:  call 0x8000          ; KERNEL_OFFSET
       |
       v
[kernel_entry.asm]  _start:
       call _main                          ; extern _main (kernel.c)
       jmp  $                              ; halt if it ever returns
       |
       v
[kernel.c]  void _main(void) { main(); }
       |
       v
[kernel.c]  void main(void)  { ... }       ; page_init, drivers, GUI loop

main() initializes in order: net_init(), vbe_init(), init_font(), boot_splash(), remap_pic(), init_idt(), init_ps2(), pit_init(), then sti and the desktop loop. Paging is enabled early via page_init() (see Memory).

Bootloader (boot.asm)

Assembled with nasm -f bin into sector 0 (154 lines). It does four jobs:

  1. Zero segment registers, set sp = 0x7C00, save dl in BOOT_DRIVE.
  2. Load the kernel — BIOS INT 13h AH=0x02, AL=60 sectors from CHS (0,0,2) to 0x8000. 60 sectors covers the grown kernel (~42 sectors after FAT32+network were added; the old 40-sector read truncated it). On error it writes 0x4F52 to text VRAM 0xB8000 and halts.
  3. Set video mode — VESA 0x4F01/0x4F02 with LFB bit 0x4000, copy result to VBE_OUT @ 0x5000.
  4. Enter protected modelgdt, set CR0.PE, far jump 0x08:init_pm, load data selector, ebp = esp = 0x1000000 (16 MiB, up from the old 0x90000).

VESA mode preference order

The bootloader tries modes best-first, then falls back to VGA mode 13h:

vesa_modes: dw 0x118, 0x11B, 0x115, 0x114, 0x112, 0x111, 0
; 0x118 = 1024x768x24bpp first, then 0x11B, then 800x600 (0x115/0x114),
; then 640x480 (0x112/0x111). QEMU is run with -vga vmware so the
; high modes probe successfully; bare hardware falls back gracefully.

vesa_fail:                     ; fallback VGA 320x200x8bpp
  mov ah,0x00 / mov al,0x13    ; INT 10h mode 13h
  LFB = 0xA0000, 320x200, pitch 320, bpp 8

GDT — flat model

Three-entry GDT, 4 GiB flat space for code and data (base 0, limit 0xFFFFF, 4 KiB granularity):

IndexSelectorBaseLimitAccessFlags
00x00x00x000x0
1 (code)0x080x00xFFFFF10011010b (0x9A)11001111b (0xCF)
2 (data)0x100x00xFFFFF10010010b (0x92)11001111b (0xCF)

Selector 0x08 is also the IDT gate code selector; 0x10 loads DS/SS/ES/FS/GS. Paging builds on top of this flat segmentation (see Memory).

Memory map

0x1000000  +------------------+  protected-mode stack top (16 MiB)
           |  kernel stack    |
0x080000...+------------------+  page tables (aligned 4 KiB) + heap pages
0x00200000 +------------------+  BACKBUFFER_ADDR (off-screen frame)
0x00080000 +------------------+  KERNEL_OFFSET / link . = 0x8000 (.text/.data/.bss)
0x00007C00 +------------------+  bootloader (512 B, org 0x7C00)
0x00000600 +------------------+  MODE_INFO (VBE info buffer)
0x00000500 +------------------+  VBE_OUT (16-byte param block)
           |  IVT / BIOS data |
0x00000000 +------------------+
  0xA0000  VGA 13h fallback LFB | 0xB8000 text VRAM (disk_error)

The 16-byte VBE_OUT block is the only bootloader→kernel IPC. It is read by vbe_init() — see Memory for offsets.