// Segments in proc->gdt. // Also known to bootasm.S and trapasm.S #define SEG_KCODE 1 // kernel code #define SEG_KDATA 2 // kernel data+stack #define SEG_KCPU 3 // kernel per-cpu data #define SEG_UCODE 4 #define SEG_UDATA 5 #define SEG_TSS 6 // this process's task state #define NSEGS 7 // Saved registers for kernel context switches. // Don't need to save all the segment registers (%cs, etc), // because they are constant across kernel contexts. // Don't need to save %eax, %ecx, %edx, because the // x86 convention is that the caller has saved them. // Contexts are stored at the bottom of the stack they // describe; the stack pointer is the address of the context. // The layout of the context must match the code in swtch.S. struct context { uint edi; uint esi; uint ebx; uint ebp; uint eip; }; enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE }; // Per-process state struct proc { char *mem; // Start of process memory (kernel address) uint sz; // Size of process memory (bytes) 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 void *chan; // If non-zero, sleeping on chan int killed; // If non-zero, have been killed struct file *ofile[NOFILE]; // Open files struct inode *cwd; // Current directory char name[16]; // Process name (debugging) }; // Process memory is laid out contiguously, low addresses first: // text // original data and bss // fixed-size stack // expandable heap // Per-CPU state struct cpu { uchar apicid; // Local APIC ID struct context *context; // Switch 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? int ncli; // Depth of pushcli nesting. int intena; // Were interrupts enabled before pushcli? void *tls[2]; }; extern struct cpu cpus[NCPU]; extern int ncpu; // Per-CPU variables, holding pointers to the // current cpu and to the current process. // The __thread prefix tells gcc to refer to them in the segment // pointed at by gs; the name __thread derives from the use // of the same mechanism to provide per-thread storage in // multithreaded user programs. extern __thread struct cpu *c; // This cpu. extern __thread struct proc *cp; // Current process on this cpu.