1 // Segments in proc->gdt. 2 // Also known to bootasm.S and trapasm.S 3 #define SEG_KCODE 1 // kernel code 4 #define SEG_KDATA 2 // kernel data+stack 5 #define SEG_KCPU 3 // kernel per-cpu data 6 #define SEG_UCODE 4 7 #define SEG_UDATA 5 8 #define SEG_TSS 6 // this process's task state 9 #define NSEGS 7 10 11 // Saved registers for kernel context switches. 12 // Don't need to save all the segment registers (%cs, etc), 13 // because they are constant across kernel contexts. 14 // Don't need to save %eax, %ecx, %edx, because the 15 // x86 convention is that the caller has saved them. 16 // Contexts are stored at the bottom of the stack they 17 // describe; the stack pointer is the address of the context. 18 // The layout of the context must match the code in swtch.S. 19 struct context { 20 uint edi; 21 uint esi; 22 uint ebx; 23 uint ebp; 24 uint eip; 25 }; 26 27 enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE }; 28 29 // Per-process state 30 struct proc { 31 char *mem; // Start of process memory (kernel address) 32 uint sz; // Size of process memory (bytes) 33 char *kstack; // Bottom of kernel stack for this process 34 enum procstate state; // Process state 35 volatile int pid; // Process ID 36 struct proc *parent; // Parent process 37 struct trapframe *tf; // Trap frame for current syscall 38 struct context *context; // Switch here to run process 39 void *chan; // If non-zero, sleeping on chan 40 int killed; // If non-zero, have been killed 41 struct file *ofile[NOFILE]; // Open files 42 struct inode *cwd; // Current directory 43 char name[16]; // Process name (debugging) 44 }; 45 46 // Process memory is laid out contiguously, low addresses first: 47 // text 48 // original data and bss 49 // fixed-size stack 50 // expandable heap 51 52 // Per-CPU state 53 struct cpu { 54 uchar id; // Local APIC ID; index into cpus[] below 55 struct context *scheduler; // Switch here to enter scheduler 56 struct taskstate ts; // Used by x86 to find stack for interrupt 57 struct segdesc gdt[NSEGS]; // x86 global descriptor table 58 volatile uint booted; // Has the CPU started? 59 int ncli; // Depth of pushcli nesting. 60 int intena; // Were interrupts enabled before pushcli? 61 62 // Cpu-local storage variables; see below 63 struct cpu *cpu; 64 struct proc *proc; 65 }; 66 67 extern struct cpu cpus[NCPU]; 68 extern int ncpu; 69 70 // Per-CPU variables, holding pointers to the 71 // current cpu and to the current process. 72 // The asm suffix tells gcc to use "%gs:0" to refer to cpu 73 // and "%gs:4" to refer to proc. ksegment sets up the 74 // %gs segment register so that %gs refers to the memory 75 // holding those two variables in the local cpu's struct cpu. 76 // This is similar to how thread-local variables are implemented 77 // in thread libraries such as Linux pthreads. 78 extern struct cpu *cpu asm("%gs:0"); // This cpu. 79 extern struct proc *proc asm("%gs:4"); // Current proc on this cpu. 80