diff options
| -rw-r--r-- | Makefile | 24 | ||||
| -rw-r--r-- | multiboot.S | 75 | 
2 files changed, 97 insertions, 2 deletions
| @@ -82,6 +82,11 @@ xv6.img: bootblock kernel fs.img  	dd if=bootblock of=xv6.img conv=notrunc  	dd if=kernel of=xv6.img seek=1 conv=notrunc +xv6memfs.img: bootblock kernelmemfs +	dd if=/dev/zero of=xv6memfs.img count=10000 +	dd if=bootblock of=xv6memfs.img conv=notrunc +	dd if=kernelmemfs of=xv6memfs.img seek=1 conv=notrunc +  bootblock: bootasm.S bootmain.c  	$(CC) $(CFLAGS) -fno-pic -O -nostdinc -I. -c bootmain.c  	$(CC) $(CFLAGS) -fno-pic -nostdinc -I. -c bootasm.S @@ -102,11 +107,23 @@ initcode: initcode.S  	$(OBJCOPY) -S -O binary initcode.out initcode  	$(OBJDUMP) -S initcode.o > initcode.asm -kernel: $(OBJS) bootother initcode -	$(LD) $(LDFLAGS) -Ttext 0x100000 -e main -o kernel $(OBJS) -b binary initcode bootother +kernel: $(OBJS) multiboot.o bootother initcode +	$(LD) $(LDFLAGS) -Ttext 0x100000 -e main -o kernel multiboot.o $(OBJS) -b binary initcode bootother fs.img  	$(OBJDUMP) -S kernel > kernel.asm  	$(OBJDUMP) -t kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernel.sym +# kernelmemfs is a copy of kernel that maintains the +# disk image in memory instead of writing to a disk. +# This is not so useful for testing persistent storage or +# exploring disk buffering implementations, but it is +# great for testing the kernel on real hardware without +# needing a scratch disk. +MEMFSOBJS = $(filter-out ide.o,$(OBJS)) memide.o +kernelmemfs: $(MEMFSOBJS) multiboot.o bootother initcode fs.img +	$(LD) $(LDFLAGS) -Ttext 0x100000 -e main -o kernelmemfs multiboot.o $(MEMFSOBJS) -b binary initcode bootother fs.img +	$(OBJDUMP) -S kernelmemfs > kernelmemfs.asm +	$(OBJDUMP) -t kernelmemfs | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernelmemfs.sym +  tags: $(OBJS) bootother.S _init  	etags *.S *.c @@ -187,6 +204,9 @@ QEMUOPTS = -hdb fs.img xv6.img -smp $(CPUS)  qemu: fs.img xv6.img  	$(QEMU) -serial mon:stdio $(QEMUOPTS) +qemu-memfs: xv6memfs.img +	$(QEMU) xv6memfs.img -smp $(CPUS) +  qemu-nox: fs.img xv6.img  	$(QEMU) -nographic $(QEMUOPTS) diff --git a/multiboot.S b/multiboot.S new file mode 100644 index 0000000..2579b6d --- /dev/null +++ b/multiboot.S @@ -0,0 +1,75 @@ +# 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" + +#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 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, 0x0, 0xffffffff)   # code seg +  SEG_ASM(STA_W, 0x0, 0xffffffff)         # data seg + +gdtdesc: +  .word   (gdtdesc - gdt - 1)             # sizeof(gdt) - 1 +  .long   gdt                             # address gdt + +.comm stack, STACK | 
