change some comments, maybe more informative
delete most comments from bootother.S (since copy of bootasm.S) ksegment() -> seginit() move more stuff from main() to mainc()
This commit is contained in:
		
							parent
							
								
									124fe7e457
								
							
						
					
					
						commit
						faad047ab2
					
				
					 8 changed files with 70 additions and 66 deletions
				
			
		
							
								
								
									
										11
									
								
								bootasm.S
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								bootasm.S
									
										
									
									
									
								
							|  | @ -13,7 +13,7 @@ | |||
| .code16                       # Assemble for 16-bit mode | ||||
| .globl start
 | ||||
| start: | ||||
|   cli                         # Disable interrupts | ||||
|   cli                         # BIOS enabled interrupts ; disable | ||||
| 
 | ||||
|   # Set up the important data segment registers (DS, ES, SS). | ||||
|   xorw    %ax,%ax             # Segment number zero | ||||
|  | @ -45,7 +45,8 @@ seta20.2: | |||
|   # Switch from real to protected mode, using a bootstrap GDT | ||||
|   # and segment translation that makes virtual addresses  | ||||
|   # identical to physical addresses, so that the  | ||||
|   # effective memory map does not change during the switch. | ||||
|   # effective memory map does not change after subsequent | ||||
|   # loads of segment registers. | ||||
|   lgdt    gdtdesc | ||||
|   movl    %cr0, %eax | ||||
|   orl     $CR0_PE, %eax | ||||
|  | @ -57,7 +58,11 @@ seta20.2: | |||
|   # default to 32 bits after this jump. | ||||
|   ljmp    $(SEG_KCODE<<3), $start32 | ||||
| 
 | ||||
| .code32                       # Assemble for 32-bit mode | ||||
| # tell the assembler to generate 0x66 prefixes for 16-bit | ||||
| # instructions like movw, and to generate 32-bit immediate | ||||
| # addresses. | ||||
| .code32 | ||||
| 
 | ||||
| start32: | ||||
|   # Set up the protected-mode data segment registers | ||||
|   movw    $(SEG_KDATA<<3), %ax    # Our data segment selector | ||||
|  |  | |||
							
								
								
									
										75
									
								
								bootother.S
									
										
									
									
									
								
							
							
						
						
									
										75
									
								
								bootother.S
									
										
									
									
									
								
							|  | @ -9,80 +9,69 @@ | |||
| # 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 puts this code (start) at 0x7000. | ||||
| # It puts the correct %esp in start-4, | ||||
| # and the place to jump to in start-8. | ||||
| # 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, | ||||
| # and the address of the place to jump to (mpmain) in start-8. | ||||
| # | ||||
| # This code is identical to bootasm.S except: | ||||
| #   - it does not need to enable A20 | ||||
| #   - it uses the address at start-4 for the %esp | ||||
| #   - it jumps to the address at start-8 instead of calling bootmain | ||||
| 
 | ||||
| #define SEG_KCODE 1  // kernel code | ||||
| #define SEG_KDATA 2  // kernel data+stack | ||||
| #define SEG_KCODE 1 | ||||
| #define SEG_KDATA 2 | ||||
| 
 | ||||
| #define CR0_PE    1  // protected mode enable bit | ||||
| #define CR0_PE    1 | ||||
| 
 | ||||
| .code16                       # Assemble for 16-bit mode | ||||
| .code16            | ||||
| .globl start
 | ||||
| start: | ||||
|   cli                         # Disable interrupts | ||||
|   cli             | ||||
| 
 | ||||
|   # Set up the important data segment registers (DS, ES, SS). | ||||
|   xorw    %ax,%ax             # Segment number zero | ||||
|   movw    %ax,%ds             # -> Data Segment | ||||
|   movw    %ax,%es             # -> Extra Segment | ||||
|   movw    %ax,%ss             # -> Stack Segment | ||||
|   xorw    %ax,%ax | ||||
|   movw    %ax,%ds | ||||
|   movw    %ax,%es | ||||
|   movw    %ax,%ss | ||||
| 
 | ||||
| //PAGEBREAK! | ||||
|   # Switch from real to protected mode, using a bootstrap GDT | ||||
|   # and segment translation that makes virtual addresses  | ||||
|   # identical to physical addresses, so that the  | ||||
|   # effective memory map does not change during the switch. | ||||
|   lgdt    gdtdesc | ||||
|   movl    %cr0, %eax | ||||
|   orl     $CR0_PE, %eax | ||||
|   movl    %eax, %cr0 | ||||
| 
 | ||||
|   # This ljmp is how you load the CS (Code Segment) register. | ||||
|   # SEG_ASM produces segment descriptors with the 32-bit mode | ||||
|   # flag set (the D flag), so addresses and word operands will | ||||
|   # default to 32 bits after this jump. | ||||
|   ljmp    $(SEG_KCODE<<3), $start32 | ||||
| 
 | ||||
| .code32                       # Assemble for 32-bit mode | ||||
| .code32 | ||||
| start32: | ||||
|   # 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 | ||||
|   movw    $(SEG_KDATA<<3), %ax | ||||
|   movw    %ax, %ds | ||||
|   movw    %ax, %es | ||||
|   movw    %ax, %ss | ||||
|   movw    $0, %ax | ||||
|   movw    %ax, %fs | ||||
|   movw    %ax, %gs | ||||
| 
 | ||||
|   # Set up the stack pointer and call into C. | ||||
|   # switch to the stack allocated by bootothers() | ||||
|   movl    start-4, %esp | ||||
| 
 | ||||
|   # call mpmain() | ||||
|   call	*(start-8) | ||||
| 
 | ||||
|   # If the call returns (it shouldn't), trigger a Bochs | ||||
|   # breakpoint if running under Bochs, then loop. | ||||
|   movw    $0x8a00, %ax            # 0x8a00 -> port 0x8a00 | ||||
|   movw    $0x8a00, %ax | ||||
|   movw    %ax, %dx | ||||
|   outw    %ax, %dx | ||||
|   movw    $0x8ae0, %ax            # 0x8ae0 -> port 0x8a00 | ||||
|   movw    $0x8ae0, %ax | ||||
|   outw    %ax, %dx | ||||
| spin: | ||||
|   jmp     spin | ||||
| 
 | ||||
| # Bootstrap GDT | ||||
| .p2align 2                                # force 4 byte alignment | ||||
| .p2align 2
 | ||||
| gdt: | ||||
|   SEG_NULLASM                             # null seg | ||||
|   SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff)   # code seg | ||||
|   SEG_ASM(STA_W, 0x0, 0xffffffff)         # data seg | ||||
|   SEG_NULLASM | ||||
|   SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) | ||||
|   SEG_ASM(STA_W, 0x0, 0xffffffff) | ||||
| 
 | ||||
| gdtdesc: | ||||
|   .word   (gdtdesc - gdt - 1)                            # sizeof(gdt) - 1 | ||||
|   .long   gdt                             # address gdt | ||||
|   .word   (gdtdesc - gdt - 1) | ||||
|   .long   gdt
 | ||||
|  |  | |||
							
								
								
									
										2
									
								
								defs.h
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								defs.h
									
										
									
									
									
								
							|  | @ -152,7 +152,7 @@ void            uartintr(void); | |||
| void            uartputc(int); | ||||
| 
 | ||||
| // vm.c
 | ||||
| void            ksegment(void); | ||||
| void            seginit(void); | ||||
| void            kvmalloc(void); | ||||
| void            vmenable(void); | ||||
| pde_t*          setupkvm(void); | ||||
|  |  | |||
							
								
								
									
										24
									
								
								main.c
									
										
									
									
									
								
							
							
						
						
									
										24
									
								
								main.c
									
										
									
									
									
								
							|  | @ -11,16 +11,14 @@ void jkstack(void)  __attribute__((noreturn)); | |||
| void mainc(void); | ||||
| 
 | ||||
| // Bootstrap processor starts running C code here.
 | ||||
| // Allocate a real stack and switch to it, first
 | ||||
| // doing some setup required for memory allocator to work.
 | ||||
| int | ||||
| main(void) | ||||
| { | ||||
|   mpinit();        // collect info about this machine
 | ||||
|   lapicinit(mpbcpu()); | ||||
|   ksegment();      // set up segments
 | ||||
|   picinit();       // interrupt controller
 | ||||
|   ioapicinit();    // another interrupt controller
 | ||||
|   consoleinit();   // I/O devices & their interrupts
 | ||||
|   uartinit();      // serial port
 | ||||
|   seginit();       // set up segments
 | ||||
|   kinit();         // initialize memory allocator
 | ||||
|   jkstack();       // call mainc() on a properly-allocated stack 
 | ||||
| } | ||||
|  | @ -37,10 +35,16 @@ jkstack(void) | |||
|   panic("jkstack"); | ||||
| } | ||||
| 
 | ||||
| // Set up hardware and software.
 | ||||
| // Runs only on the boostrap processor.
 | ||||
| void | ||||
| mainc(void) | ||||
| { | ||||
|   cprintf("\ncpu%d: starting xv6\n\n", cpu->id); | ||||
|   picinit();       // interrupt controller
 | ||||
|   ioapicinit();    // another interrupt controller
 | ||||
|   consoleinit();   // I/O devices & their interrupts
 | ||||
|   uartinit();      // serial port
 | ||||
|   kvmalloc();      // initialize the kernel page table
 | ||||
|   pinit();         // process table
 | ||||
|   tvinit();        // trap vectors
 | ||||
|  | @ -64,16 +68,17 @@ static void | |||
| mpmain(void) | ||||
| { | ||||
|   if(cpunum() != mpbcpu()) { | ||||
|     ksegment(); | ||||
|     seginit(); | ||||
|     lapicinit(cpunum()); | ||||
|   } | ||||
|   vmenable();        // turn on paging
 | ||||
|   cprintf("cpu%d: starting\n", cpu->id); | ||||
|   idtinit();       // load idt register
 | ||||
|   xchg(&cpu->booted, 1); | ||||
|   xchg(&cpu->booted, 1); // tell bootothers() we're up
 | ||||
|   scheduler();     // start running processes
 | ||||
| } | ||||
| 
 | ||||
| // Start the non-boot processors.
 | ||||
| static void | ||||
| bootothers(void) | ||||
| { | ||||
|  | @ -91,10 +96,13 @@ bootothers(void) | |||
|     if(c == cpus+cpunum())  // We've started already.
 | ||||
|       continue; | ||||
| 
 | ||||
|     // Fill in %esp, %eip and start code on cpu.
 | ||||
|     // Tell bootother.S what stack to use and the address of mpmain;
 | ||||
|     // it expects to find these two addresses stored just before
 | ||||
|     // its first instruction.
 | ||||
|     stack = kalloc(); | ||||
|     *(void**)(code-4) = stack + KSTACKSIZE; | ||||
|     *(void**)(code-8) = mpmain; | ||||
| 
 | ||||
|     lapicstartap(c->id, (uint)code); | ||||
| 
 | ||||
|     // Wait for cpu to finish mpmain()
 | ||||
|  |  | |||
							
								
								
									
										6
									
								
								proc.c
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								proc.c
									
										
									
									
									
								
							|  | @ -65,7 +65,8 @@ procdump(void) | |||
| 
 | ||||
| //PAGEBREAK: 32
 | ||||
| // Look in the process table for an UNUSED proc.
 | ||||
| // If found, change state to EMBRYO and return it.
 | ||||
| // If found, change state to EMBRYO and initialize
 | ||||
| // state required to run in the kernel.
 | ||||
| // Otherwise return 0.
 | ||||
| static struct proc* | ||||
| allocproc(void) | ||||
|  | @ -97,7 +98,7 @@ found: | |||
|   p->tf = (struct trapframe*)sp; | ||||
|    | ||||
|   // Set up new context to start executing at forkret,
 | ||||
|   // which returns to trapret (see below).
 | ||||
|   // which returns to trapret.
 | ||||
|   sp -= 4; | ||||
|   *(uint*)sp = (uint)trapret; | ||||
| 
 | ||||
|  | @ -105,6 +106,7 @@ found: | |||
|   p->context = (struct context*)sp; | ||||
|   memset(p->context, 0, sizeof *p->context); | ||||
|   p->context->eip = (uint)forkret; | ||||
| 
 | ||||
|   return p; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										14
									
								
								proc.h
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								proc.h
									
										
									
									
									
								
							|  | @ -11,7 +11,7 @@ | |||
| // Per-CPU state
 | ||||
| struct cpu { | ||||
|   uchar id;                    // Local APIC ID; index into cpus[] below
 | ||||
|   struct context *scheduler;   // Switch here to enter scheduler
 | ||||
|   struct context *scheduler;   // swtch() here to enter scheduler
 | ||||
|   struct taskstate ts;         // Used by x86 to find stack for interrupt
 | ||||
|   struct segdesc gdt[NSEGS];   // x86 global descriptor table
 | ||||
|   volatile uint booted;        // Has the CPU started?
 | ||||
|  | @ -20,7 +20,7 @@ struct cpu { | |||
|    | ||||
|   // Cpu-local storage variables; see below
 | ||||
|   struct cpu *cpu; | ||||
|   struct proc *proc; | ||||
|   struct proc *proc;           // The currently-running process.
 | ||||
| }; | ||||
| 
 | ||||
| extern struct cpu cpus[NCPU]; | ||||
|  | @ -29,13 +29,13 @@ extern int ncpu; | |||
| // Per-CPU variables, holding pointers to the
 | ||||
| // current cpu and to the current process.
 | ||||
| // The asm suffix tells gcc to use "%gs:0" to refer to cpu
 | ||||
| // and "%gs:4" to refer to proc.  ksegment sets up the
 | ||||
| // and "%gs:4" to refer to proc.  seginit sets up the
 | ||||
| // %gs segment register so that %gs refers to the memory
 | ||||
| // holding those two variables in the local cpu's struct cpu.
 | ||||
| // This is similar to how thread-local variables are implemented
 | ||||
| // in thread libraries such as Linux pthreads.
 | ||||
| extern struct cpu *cpu asm("%gs:0");       // This cpu.
 | ||||
| extern struct proc *proc asm("%gs:4");     // Current proc on this cpu.
 | ||||
| extern struct cpu *cpu asm("%gs:0");       // &cpus[cpunum()]
 | ||||
| extern struct proc *proc asm("%gs:4");     // cpus[cpunum()].proc
 | ||||
| 
 | ||||
| //PAGEBREAK: 17
 | ||||
| // Saved registers for kernel context switches.
 | ||||
|  | @ -61,13 +61,13 @@ enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE }; | |||
| // Per-process state
 | ||||
| struct proc { | ||||
|   uint sz;                     // Size of process memory (bytes)
 | ||||
|   pde_t* pgdir;                // Linear address of proc's pgdir
 | ||||
|   pde_t* pgdir;                // Page table
 | ||||
|   char *kstack;                // Bottom of kernel stack for this process
 | ||||
|   enum procstate state;        // Process state
 | ||||
|   volatile int pid;            // Process ID
 | ||||
|   struct proc *parent;         // Parent process
 | ||||
|   struct trapframe *tf;        // Trap frame for current syscall
 | ||||
|   struct context *context;     // Switch here to run process
 | ||||
|   struct context *context;     // swtch() here to run process
 | ||||
|   void *chan;                  // If non-zero, sleeping on chan
 | ||||
|   int killed;                  // If non-zero, have been killed
 | ||||
|   struct file *ofile[NOFILE];  // Open files
 | ||||
|  |  | |||
|  | @ -23,7 +23,7 @@ initlock(struct spinlock *lk, char *name) | |||
| void | ||||
| acquire(struct spinlock *lk) | ||||
| { | ||||
|   pushcli(); | ||||
|   pushcli(); // disable interrupts to avoid deadlock.
 | ||||
|   if(holding(lk)) | ||||
|     panic("acquire"); | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										2
									
								
								vm.c
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								vm.c
									
										
									
									
									
								
							|  | @ -13,7 +13,7 @@ static pde_t *kpgdir;  // for use in scheduler() | |||
| // Set up CPU's kernel segment descriptors.
 | ||||
| // Run once at boot time on each CPU.
 | ||||
| void | ||||
| ksegment(void) | ||||
| seginit(void) | ||||
| { | ||||
|   struct cpu *c; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Robert Morris
						Robert Morris