summaryrefslogtreecommitdiff
path: root/multiboot.S
diff options
context:
space:
mode:
Diffstat (limited to 'multiboot.S')
-rw-r--r--multiboot.S75
1 files changed, 75 insertions, 0 deletions
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