eaea18cb9c
Various changes made while offline. + bwrite sector argument is redundant; use b->sector. + reformatting of files for nicer PDF page breaks + distinguish between locked, unlocked inodes in type signatures + change FD_FILE to FD_INODE + move userinit (nee proc0init) to proc.c + move ROOTDEV to param.h + always parenthesize sizeof argument
78 lines
2.5 KiB
C
78 lines
2.5 KiB
C
// Segments in proc->gdt
|
|
#define SEG_KCODE 1 // kernel code
|
|
#define SEG_KDATA 2 // kernel data+stack
|
|
#define SEG_UCODE 3
|
|
#define SEG_UDATA 4
|
|
#define SEG_TSS 5 // this process's task state
|
|
#define NSEGS 6
|
|
|
|
// Saved registers for kernel context switches.
|
|
// Don't need to save all the %fs etc. segment registers,
|
|
// because they are constant across kernel contexts.
|
|
// Save all the regular registers so we don't need to care
|
|
// which are caller save.
|
|
// Don't save %eax, because that's the return register.
|
|
// The layout of jmpbuf is known to setjmp.S.
|
|
struct jmpbuf {
|
|
int ebx;
|
|
int ecx;
|
|
int edx;
|
|
int esi;
|
|
int edi;
|
|
int esp;
|
|
int ebp;
|
|
int eip;
|
|
};
|
|
|
|
enum proc_state { 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 proc_state state; // Process state
|
|
int pid; // Process ID
|
|
int ppid; // Parent pid
|
|
void *chan; // If non-zero, sleeping on chan
|
|
int killed; // If non-zero, have been killed
|
|
struct file *ofile[NOFILE]; // Open files
|
|
struct uinode *cwd; // Current directory
|
|
struct jmpbuf jmpbuf; // Jump here to run process
|
|
struct trapframe *tf; // Trap frame for current interrupt
|
|
char name[16]; // Process name (debugging)
|
|
};
|
|
|
|
// Process memory is laid out contiguously:
|
|
// text
|
|
// original data and bss
|
|
// fixed-size stack
|
|
// expandable heap
|
|
|
|
// If xv6 was only for uniprocessors, this could be
|
|
// struct proc *cp;
|
|
// Instead we have an array curproc, one per
|
|
// processor, and #define cp to the right element
|
|
// in the array. In general such preprocessor
|
|
// subterfuge is to be avoided, but cp is used
|
|
// so often that having the shorthand is worth the ugliness.
|
|
extern struct proc *curproc[NCPU]; // Current (running) process per CPU
|
|
#define cp (curproc[cpu()]) // Current process on this CPU
|
|
|
|
|
|
#define MPSTACK 512
|
|
|
|
// Per-CPU state
|
|
struct cpu {
|
|
uchar apicid; // Local APIC ID
|
|
struct jmpbuf jmpbuf; // Jump here to enter scheduler
|
|
struct taskstate ts; // Used by x86 to find stack for interrupt
|
|
struct segdesc gdt[NSEGS]; // x86 global descriptor table
|
|
char mpstack[MPSTACK]; // Per-CPU startup stack
|
|
volatile int booted; // Has the CPU started?
|
|
int nlock; // Number of locks currently held
|
|
};
|
|
|
|
extern struct cpu cpus[NCPU];
|
|
extern int ncpu;
|