# Multiboot header, for multiboot boot loaders like GNU Grub. # http://www.gnu.org/software/grub/manual/multiboot/multiboot.html # # Using GRUB 2, you can boot xv6 from a file stored in a # Linux file system by copying kernel or kernelmemfs to /boot # and then adding this menu entry: # # menuentry "xv6" { # insmod ext2 # set root='(hd0,msdos1)' # set kernel='/boot/kernel' # echo "Loading ${kernel}..." # multiboot ${kernel} ${kernel} # boot # } #include "asm.h" #include "memlayout.h" #define RELOC(x) ((x) - KERNBASE) // same as V2P, but without casts #define STACK 4096 #define SEG_KCODE 1 // kernel code #define SEG_KDATA 2 // kernel data+stack # Multiboot header. Data to direct multiboot loader. .p2align 2 .text .globl multiboot_header multiboot_header: #define magic 0x1badb002 #define flags (1<<16 | 1<<0) .long magic .long flags .long (-magic-flags) .long multiboot_header # beginning of image .long multiboot_header .long edata .long end .long multiboot_entry # Multiboot entry point. Machine is mostly set up. # Configure the GDT to match the environment that our usual # boot loader - bootasm.S - sets up. .globl multiboot_entry multiboot_entry: lgdt RELOC(gdtdesc) ljmp $(SEG_KCODE<<3), $mbstart32 mbstart32: # Set up the protected-mode data segment registers movw $(SEG_KDATA<<3), %ax # Our data segment selector movw %ax, %ds # -> DS: Data Segment movw %ax, %es # -> ES: Extra Segment movw %ax, %ss # -> SS: Stack Segment movw $0, %ax # Zero segments not ready for use movw %ax, %fs # -> FS movw %ax, %gs # -> GS # Set up the stack pointer and call into C. movl $(stack + STACK), %esp call main spin: jmp spin # Bootstrap GDT .p2align 2 # force 4 byte alignment gdt: SEG_NULLASM # null seg SEG_ASM(STA_X|STA_R, -KERNBASE, 0xffffffff) # code seg SEG_ASM(STA_W, -KERNBASE, 0xffffffff) # data seg gdtdesc: .word (gdtdesc - gdt - 1) # sizeof(gdt) - 1 .long RELOC(gdt) # address gdt .comm stack, STACK