From c60a3551c2dba29006f5d7917308281e47fa5fef Mon Sep 17 00:00:00 2001 From: Frans Kaashoek Date: Mon, 15 Aug 2011 12:02:59 -0400 Subject: Separate more clearly bootloader from xv6 by renaming multiboot.S to entry.S etc. Maybe the string boot shouldn't appear in xv6 code? --- Makefile | 20 +++++++-------- bootother.S | 84 ------------------------------------------------------------ entry.S | 60 +++++++++++++++++++++++++++++++++++++++++++ entryother.S | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.c | 22 ++++++++-------- multiboot.S | 60 ------------------------------------------- 6 files changed, 165 insertions(+), 165 deletions(-) delete mode 100644 bootother.S create mode 100644 entry.S create mode 100644 entryother.S delete mode 100644 multiboot.S diff --git a/Makefile b/Makefile index bd4fb4c..a497992 100644 --- a/Makefile +++ b/Makefile @@ -97,11 +97,11 @@ bootblock: bootasm.S bootmain.c $(OBJCOPY) -S -O binary -j .text bootblock.o bootblock ./sign.pl bootblock -bootother: bootother.S - $(CC) $(CFLAGS) -fno-pic -nostdinc -I. -c bootother.S - $(LD) $(LDFLAGS) -N -e start -Ttext 0x7000 -o bootblockother.o bootother.o - $(OBJCOPY) -S -O binary -j .text bootblockother.o bootother - $(OBJDUMP) -S bootblockother.o > bootother.asm +entryother: entryother.S + $(CC) $(CFLAGS) -fno-pic -nostdinc -I. -c entryother.S + $(LD) $(LDFLAGS) -N -e start -Ttext 0x7000 -o bootblockother.o entryother.o + $(OBJCOPY) -S -O binary -j .text bootblockother.o entryother + $(OBJDUMP) -S bootblockother.o > entryother.asm initcode: initcode.S $(CC) $(CFLAGS) -nostdinc -I. -c initcode.S @@ -109,8 +109,8 @@ initcode: initcode.S $(OBJCOPY) -S -O binary initcode.out initcode $(OBJDUMP) -S initcode.o > initcode.asm -kernel: $(OBJS) multiboot.o data.o bootother initcode - $(LD) $(LDFLAGS) -T kernel.ld -e multiboot_entry -o kernel multiboot.o data.o $(OBJS) -b binary initcode bootother +kernel: $(OBJS) entry.o data.o entryother initcode + $(LD) $(LDFLAGS) -T kernel.ld -e multiboot_entry -o kernel entry.o data.o $(OBJS) -b binary initcode entryother $(OBJDUMP) -S kernel > kernel.asm $(OBJDUMP) -t kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernel.sym @@ -121,12 +121,12 @@ kernel: $(OBJS) multiboot.o data.o bootother initcode # 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 data.o bootother initcode fs.img - $(LD) $(LDFLAGS) -Ttext 0x100000 -e main -o kernelmemfs multiboot.o data.o $(MEMFSOBJS) -b binary initcode bootother fs.img +kernelmemfs: $(MEMFSOBJS) entry.o data.o entryother initcode fs.img + $(LD) $(LDFLAGS) -Ttext 0x100000 -e main -o kernelmemfs entry.o data.o $(MEMFSOBJS) -b binary initcode entryother fs.img $(OBJDUMP) -S kernelmemfs > kernelmemfs.asm $(OBJDUMP) -t kernelmemfs | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernelmemfs.sym -tags: $(OBJS) bootother.S _init +tags: $(OBJS) entryother.S _init etags *.S *.c vectors.S: vectors.pl diff --git a/bootother.S b/bootother.S deleted file mode 100644 index 56edac2..0000000 --- a/bootother.S +++ /dev/null @@ -1,84 +0,0 @@ -#include "asm.h" -#include "memlayout.h" -#include "mmu.h" - -# Each non-boot CPU ("AP") is started up in response to a STARTUP -# IPI from the boot CPU. Section B.4.2 of the Multi-Processor -# Specification says that the AP will start in real mode with CS:IP -# set to XY00:0000, where XY is an 8-bit value sent with the -# STARTUP. Thus this code must start at a 4096-byte boundary. -# -# Because this code sets DS to zero, it must sit -# at an address in the low 2^16 bytes. -# -# Bootothers (in main.c) sends the STARTUPs one at a time. -# It copies this code (start) at 0x7000. -# It puts the address of a newly allocated per-core stack in start-4, -# the address of the place to jump to (mpboot) in start-8, and the physical -# address of bootpgdir in start-12. -# -# -# This code is identical to bootasm.S except: -# - it does not need to enable A20 -# - it uses the address at start-4, start-8, and start-12 - -.code16 -.globl start -start: - cli - - xorw %ax,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%ss - - lgdt gdtdesc - movl %cr0, %eax - orl $CR0_PE, %eax - movl %eax, %cr0 - -//PAGEBREAK! - ljmpl $(SEG_KCODE<<3), $(start32) - -.code32 -start32: - movw $(SEG_KDATA<<3), %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %ss - movw $0, %ax - movw %ax, %fs - movw %ax, %gs - - # Use bootpgdir as our initial page table - movl (start-12), %eax - movl %eax, %cr3 - # Turn on paging. - movl %cr0, %eax - orl $(CR0_PE|CR0_PG|CR0_WP), %eax - movl %eax, %cr0 - - # Switch to the stack allocated by bootothers() - movl (start-4), %esp - # Call mpboot() - call *(start-8) - - movw $0x8a00, %ax - movw %ax, %dx - outw %ax, %dx - movw $0x8ae0, %ax - outw %ax, %dx -spin: - jmp spin - -.p2align 2 -gdt: - SEG_NULLASM - SEG_ASM(STA_X|STA_R, 0, 0xffffffff) - SEG_ASM(STA_W, 0, 0xffffffff) - - -gdtdesc: - .word (gdtdesc - gdt - 1) - .long gdt - diff --git a/entry.S b/entry.S new file mode 100644 index 0000000..cd6a62b --- /dev/null +++ b/entry.S @@ -0,0 +1,60 @@ +# 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" +#include "mmu.h" + +#define STACK 4096 + +# 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. +.globl multiboot_entry +multiboot_entry: + movl $(V2P_WO(bootpgdir)), %eax + movl %eax, %cr3 + # Turn on paging. + movl %cr0, %eax + orl $(CR0_PE|CR0_PG|CR0_WP), %eax + movl %eax, %cr0 + + # now switch to using addresses above KERNBASE + # call addresses are pc-relative so we jump though this hoop: + mov $relocated, %eax + jmp *%eax +relocated: + # Set up the stack pointer and call into C. + movl $(stack + STACK), %esp + call main +spin: + jmp spin + +.comm stack, STACK diff --git a/entryother.S b/entryother.S new file mode 100644 index 0000000..4f8e3ba --- /dev/null +++ b/entryother.S @@ -0,0 +1,84 @@ +#include "asm.h" +#include "memlayout.h" +#include "mmu.h" + +# Each non-boot CPU ("AP") is started up in response to a STARTUP +# IPI from the boot CPU. Section B.4.2 of the Multi-Processor +# Specification says that the AP will start in real mode with CS:IP +# set to XY00:0000, where XY is an 8-bit value sent with the +# STARTUP. Thus this code must start at a 4096-byte boundary. +# +# Because this code sets DS to zero, it must sit +# at an address in the low 2^16 bytes. +# +# Bootothers (in main.c) sends the STARTUPs one at a time. +# It copies this code (start) at 0x7000. +# It puts the address of a newly allocated per-core stack in start-4, +# the address of the place to jump to (mpboot) in start-8, and the physical +# address of bootpgdir in start-12. +# +# +# This code is identical to bootasm.S except: +# - it does not need to enable A20 +# - it uses the address at start-4, start-8, and start-12 + +.code16 +.globl start +start: + cli + + xorw %ax,%ax + movw %ax,%ds + movw %ax,%es + movw %ax,%ss + + lgdt gdtdesc + movl %cr0, %eax + orl $CR0_PE, %eax + movl %eax, %cr0 + +//PAGEBREAK! + ljmpl $(SEG_KCODE<<3), $(start32) + +.code32 +start32: + movw $(SEG_KDATA<<3), %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %ss + movw $0, %ax + movw %ax, %fs + movw %ax, %gs + + # Use bootpgdir as our initial page table + movl (start-12), %eax + movl %eax, %cr3 + # Turn on paging. + movl %cr0, %eax + orl $(CR0_PE|CR0_PG|CR0_WP), %eax + movl %eax, %cr0 + + # Switch to the stack allocated by entryothers() + movl (start-4), %esp + # Call mpboot() + call *(start-8) + + movw $0x8a00, %ax + movw %ax, %dx + outw %ax, %dx + movw $0x8ae0, %ax + outw %ax, %dx +spin: + jmp spin + +.p2align 2 +gdt: + SEG_NULLASM + SEG_ASM(STA_X|STA_R, 0, 0xffffffff) + SEG_ASM(STA_W, 0, 0xffffffff) + + +gdtdesc: + .word (gdtdesc - gdt - 1) + .long gdt + diff --git a/main.c b/main.c index 570ae52..69ceee6 100644 --- a/main.c +++ b/main.c @@ -6,7 +6,7 @@ #include "proc.h" #include "x86.h" -static void bootothers(void); +static void enterothers(void); static void mpmain(void) __attribute__((noreturn)); extern pde_t *kpgdir; @@ -33,14 +33,14 @@ main(void) ideinit(); // disk if(!ismp) timerinit(); // uniprocessor timer - bootothers(); // start other processors (must come before kinit; must use boot_alloc) + enterothers(); // start other processors (must come before kinit; must use boot_alloc) kinit(); // initialize memory allocator userinit(); // first user process (must come after kinit) // Finish setting up this processor in mpmain. mpmain(); } -// Other CPUs jump here from bootother.S. +// Other CPUs jump here from entryother.S. static void mpboot(void) { @@ -56,7 +56,7 @@ mpmain(void) { cprintf("cpu%d: starting\n", cpu->id); idtinit(); // load idt register - xchg(&cpu->booted, 1); // tell bootothers() we're up + xchg(&cpu->booted, 1); // tell enterothers() we're up scheduler(); // start running processes } @@ -64,24 +64,24 @@ pde_t bootpgdir[]; // Start the non-boot processors. static void -bootothers(void) +enterothers(void) { - extern uchar _binary_bootother_start[], _binary_bootother_size[]; + extern uchar _binary_entryother_start[], _binary_entryother_size[]; uchar *code; struct cpu *c; char *stack; // Write bootstrap code to unused memory at 0x7000. - // The linker has placed the image of bootother.S in - // _binary_bootother_start. + // The linker has placed the image of entryother.S in + // _binary_entryother_start. code = p2v(0x7000); - memmove(code, _binary_bootother_start, (uint)_binary_bootother_size); + memmove(code, _binary_entryother_start, (uint)_binary_entryother_size); for(c = cpus; c < cpus+ncpu; c++){ if(c == cpus+cpunum()) // We've started already. continue; - // Tell bootother.S what stack to use, the address of mpboot and pgdir; + // Tell entryother.S what stack to use, the address of mpboot and pgdir; // We cannot use kpgdir yet, because the AP processor is running in low // memory, so we use bootpgdir for the APs too. kalloc can return addresses // above 4Mbyte (the machine may have much more physical memory than 4Mbyte), which @@ -101,7 +101,7 @@ bootothers(void) } } -// Boot page table used in multiboot.S and bootother.S. +// Boot page table used in multiboot.S and entryother.S. // Page directories (and page tables), must start on a page boundary, // hence the "__aligned__" attribute. Also, because of restrictions // related to linking and static initializers, we use "x + PTE_P" diff --git a/multiboot.S b/multiboot.S deleted file mode 100644 index cd6a62b..0000000 --- a/multiboot.S +++ /dev/null @@ -1,60 +0,0 @@ -# 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" -#include "mmu.h" - -#define STACK 4096 - -# 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. -.globl multiboot_entry -multiboot_entry: - movl $(V2P_WO(bootpgdir)), %eax - movl %eax, %cr3 - # Turn on paging. - movl %cr0, %eax - orl $(CR0_PE|CR0_PG|CR0_WP), %eax - movl %eax, %cr0 - - # now switch to using addresses above KERNBASE - # call addresses are pc-relative so we jump though this hoop: - mov $relocated, %eax - jmp *%eax -relocated: - # Set up the stack pointer and call into C. - movl $(stack + STACK), %esp - call main -spin: - jmp spin - -.comm stack, STACK -- cgit v1.2.3