从零写OS(十六):ELF 加载器,运行第一个用户程序
这一章做完,我们的系统就有了完整的用户程序执行链路:写一个独立的程序,编译成 ELF,放到磁盘上,Shell 里输入 run hello.elf,内核加载并执行它。 ELF 是什么 ELF(Executable and Linkable Format)是 Linux 可执行文件的格式。你编译出来的每个程序、/bin/ls、/usr/bin/python 都是 ELF 文件。 结构很简单: ELF Header → 魔数、架构、入口地址 Program Headers → 每个段加载到内存哪里、从文件哪里读 .text → 代码 .data → 数据 .bss → 未初始化数据(文件里不占空间,加载时清零) 加载一个 ELF,本质上就是:按 Program Header 的指示,把文件里的数据复制到内存里,然后跳到入口地址。 先写用户程序 用户程序不能调内核函数,只能通过 syscall 和内核通信: BITS 64 section .text global _start _start: mov rax, 1 ; syscall 1 = print lea rdi, [rel msg] ; RIP 相对寻址 syscall mov rax, 2 ; syscall 2 = exit syscall section .data msg: db "Hello from ELF!", 13, 10, 0 链接时指定加载地址 0x400000(避开内核占用的低地址区域): ENTRY(_start) SECTIONS { . = 0x400000; .text : { *(.text) } .data : { *(.data) } } ELF 加载器 加载流程: ...