我通过教程学习用户模式。在教程中,他们通过以下代码构建内核映像:
nasm -f bin -o boot.bin boot.asm
nasm -f bin -o loader.bin loader.asm
nasm -f elf64 -o kernel.o kernel.asm
nasm -f elf64 -o trapa.o trap.asm
nasm -f elf64 -o liba.o lib.asm
gcc -std=c99 -mcmodel=large -ffreestanding -fno-stack-protector -mno-red-zone -c main.c
gcc -std=c99 -mcmodel=large -ffreestanding -fno-stack-protector -mno-red-zone -c trap.c
gcc -std=c99 -mcmodel=large -ffreestanding -fno-stack-protector -mno-red-zone -c print.c
gcc -std=c99 -mcmodel=large -ffreestanding -fno-stack-protector -mno-red-zone -c debug.c
gcc -std=c99 -mcmodel=large -ffreestanding -fno-stack-protector -mno-red-zone -c memory.c
gcc -std=c99 -mcmodel=large -ffreestanding -fno-stack-protector -mno-red-zone -c process.c
gcc -std=c99 -mcmodel=large -ffreestanding -fno-stack-protector -mno-red-zone -c syscall.c
ld -nostdlib -T link.lds -o kernel kernel.o main.o trapa.o trap.o liba.o print.o debug.o memory.o process.o syscall.o
objcopy -O binary kernel kernel.bin
dd if=boot.bin of=boot.img bs=512 count=1 conv=notrunc
dd if=loader.bin of=boot.img bs=512 count=5 seek=1 conv=notrunc
dd if=kernel.bin of=boot.img bs=512 count=100 seek=6 conv=notrunc
dd if=user.bin of=boot.img bs=512 count=10 seek=106 conv=notrunc
并通过以下代码构建用户空间:
nasm -f elf64 -o start.o start.asm
gcc -std=c99 -mcmodel=large -ffreestanding -fno-stack-protector -mno-red-zone -c main.c
ld -nostdlib -Tlink.lds -o user start.o main.o lib.a
objcopy -O binary user user.bin
他们使用 bochs 和自定义引导加载程序,并通过以下代码加载内核和用户模式:
LoadKernel:
mov si,ReadPacket
mov word[si],0x10
mov word[si+2],100
mov word[si+4],0
mov word[si+6],0x1000
mov dword[si+8],6
mov dword[si+0xc],0
mov dl,[DriveId]
mov ah,0x42
int 0x13
jc ReadError
LoadUser:
mov si,ReadPacket
mov word[si],0x10
mov word[si+2],10
mov word[si+4],0
mov word[si+6],0x2000
mov dword[si+8],106
mov dword[si+0xc],0
mov dl,[DriveId]
mov ah,0x42
int 0x13
jc ReadError
但是我将 grub 用于我的内核。我用 qemu 运行 iso。我也使用gas而不是nasm。
从我的 Makefile 制作 iso(就像在 osdev 教程中一样):
...
$(ISO_FILE): kernel
mkdir -p iso/boot/grub
cp grub.cfg iso/boot/grub/
cp kernel/kernel iso/boot/
$(GRUB_MKRESCUE) -o $(ISO_FILE) iso
如何使用 grub 加载用户空间?或者我需要在内核中编写一些代码来加载用户进程?