Operation map

How Popcorn boots and runs in the v0.5 tree: GRUB Multiboot2 loads the ELF at the link address, start enters long mode and calls kmain, init_boot_screen sequences subsystems and pops, then init_transition_to_console enables the IDT/PIC path and drops into the shell while IRQ0 still feeds the scheduler.

ELF64 @ 0x100000 Multiboot2 IDT 0x20 / 0x21 / 0x80 PIT → scheduler_tick 9 pops registered QEMU ISO boot

Interactive hierarchy

Hierarchical map

Expand branches (▸). Each node updates the inspector.

Popcorn

Loading…

Flow diagrams

Interrupt delivery

flowchart TD
  PIT[PIT IRQ0] --> PIC1[PIC master]
  KB[Keyboard IRQ1] --> PIC1
  PIC1 --> CPU[CPU interrupt]
  CPU --> IDT[IDT dispatch]
  IDT --> T0[timer_handler asm]
  IDT --> K0[keyboard_handler asm]
  IDT --> S0[syscall_handler_asm]
  T0 --> T1[timer_interrupt_handler C]
  T1 --> TH["tick_handler: scheduler_tick"]
  K0 --> K1[keyboard_handler_main C]
  S0 --> SD[syscall_dispatch C]

Lifecycle — host to shell

flowchart TB
  subgraph Host["Host (build and QEMU)"]
    ISO[GRUB ISO] --> QEMU[QEMU -cdrom]
  end
  subgraph Guest["Guest (Popcorn kernel)"]
    QEMU --> ENTRY["start: kernel.asm"]
    ENTRY --> KM[kmain]
    KM --> INIT[init_boot_screen]
    INIT --> MEM[memory_init]
    INIT --> TIM[timer_init]
    INIT --> SCH[scheduler_init]
    INIT --> SYS[syscall_init]
    INIT --> POP[register_pop modules]
    INIT --> GO[init_transition_to_console]
    GO --> MB[multiboot2_parse]
    GO --> IDT[idt_init + PIC]
    GO --> KB[kb_init]
    GO --> TE["timer_enable + tick to scheduler_tick"]
    GO --> SH[Shell prompt loop]
    IRQ0[PIT IRQ0] --> TICK[timer_interrupt_handler]
    TICK --> ST[scheduler_tick]
    IRQ1[KB IRQ1] --> KH[keyboard_handler_main]
    INT80[int 0x80] --> SC[syscall_dispatch]
    SH --> EX[execute_command]
  end
  Host --> Guest

Reference sections

0 · Repository layout
Popcorn/
├── src/
│   ├── link.ld
│   ├── core/
│   ├── pops/
│   ├── includes/
│   └── build.sh / buildmon.py / mac-build*  (host)

Only the linked ELF runs inside QEMU; Python and shell helpers are host tooling.

1 · Boot chain (GRUB → start → kmain)
GRUB (guest)
  └─ multiboot2 /boot/kernel
       └─ loads ELF to link address
            └─ jumps to symbol `start` in core/kernel.asm

start saves the Multiboot2 info pointer, builds identity-mapped tables, enables long mode, sets rsp, calls kmain. ASM exports connect IRQ and syscall gates to C.

4 · init_boot_screen + transition
init_boot_screen
  console_init → header → memory_init → timer_init
  → scheduler_init → syscall_init
  → register_pop_module ×9 → progress → wait Enter
  → init_transition_to_console

init_transition_to_console
  multiboot2_parse → idt_init (PIC, masks, load_idt/sti)
  → kb_init → timer_set_tick_handler(scheduler_tick)
  → timer_enable → prompt + status bar

Pop registration order: spinner, uptime, filesystem, sysinfo, memory, cpu, dolphin, halt, shimjapii.

8 · Syscall surface (representative)
exit, read, write, open, close, seek, getpid,
fork, exec, wait,
malloc, free, mmap, munmap,
gettime, sleep, yield,
getcwd, chdir,
stat, ioctl

syscall_dispatch uses the convention in ctx->rax; IDT vector 0x80 is installed as a user-accessible interrupt gate in idt_init.

13 · Reading map
Concern Primary files
Entry, long mode, ISR stubs core/kernel.asm
Link address, sections link.ld
Boot UI + ordered init core/init.c
Shell + IDT/PIC + keyboard loop core/kernel.c
Timer IRQ core/timer.c + asm stub
Scheduler core/scheduler.c + context_switch.asm
Syscalls core/syscall.c + asm stub
Multiboot core/multiboot2.c, includes/multiboot2.h
Pop registry core/pop_module.c, includes/pop_module.h
Individual pops pops/*.c
14 · Caveats

Educational kernel: syscall gate exists; real isolation depends on memory and task setup—verify in tree.

Shell polls the keyboard while timer IRQ runs scheduler logic; treat shared console state carefully.

execute_all_pops is a batch helper; some commands invoke pops directly.