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.
Interactive hierarchy
Hierarchical map
Expand branches (▸). Each node updates the inspector.
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.