Xv6 with picoc & Linkage editor
v1.0
The project delineate mutual cohesion between c library, linkage editor ( linker), interpreter and operating system by porting the same on xv6 kernel
|
00001 // Segments in proc->gdt. 00002 #define NSEGS 7 00003 00004 // Per-CPU state 00005 struct cpu { 00006 uchar id; // Local APIC ID; index into cpus[] below 00007 struct context *scheduler; // swtch() here to enter scheduler 00008 struct taskstate ts; // Used by x86 to find stack for interrupt 00009 struct segdesc gdt[NSEGS]; // x86 global descriptor table 00010 volatile uint started; // Has the CPU started? 00011 int ncli; // Depth of pushcli nesting. 00012 int intena; // Were interrupts enabled before pushcli? 00013 00014 // Cpu-local storage variables; see below 00015 struct cpu *cpu; 00016 struct proc *proc; // The currently-running process. 00017 }; 00018 00019 extern struct cpu cpus[NCPU]; 00020 extern int ncpu; 00021 00022 // Per-CPU variables, holding pointers to the 00023 // current cpu and to the current process. 00024 // The asm suffix tells gcc to use "%gs:0" to refer to cpu 00025 // and "%gs:4" to refer to proc. seginit sets up the 00026 // %gs segment register so that %gs refers to the memory 00027 // holding those two variables in the local cpu's struct cpu. 00028 // This is similar to how thread-local variables are implemented 00029 // in thread libraries such as Linux pthreads. 00030 extern struct cpu *cpu asm("%gs:0"); // &cpus[cpunum()] 00031 extern struct proc *proc asm("%gs:4"); // cpus[cpunum()].proc 00032 00033 //PAGEBREAK: 17 00034 // Saved registers for kernel context switches. 00035 // Don't need to save all the segment registers (%cs, etc), 00036 // because they are constant across kernel contexts. 00037 // Don't need to save %eax, %ecx, %edx, because the 00038 // x86 convention is that the caller has saved them. 00039 // Contexts are stored at the bottom of the stack they 00040 // describe; the stack pointer is the address of the context. 00041 // The layout of the context matches the layout of the stack in swtch.S 00042 // at the "Switch stacks" comment. Switch doesn't save eip explicitly, 00043 // but it is on the stack and allocproc() manipulates it. 00044 struct context { 00045 uint edi; 00046 uint esi; 00047 uint ebx; 00048 uint ebp; 00049 uint eip; 00050 }; 00051 00052 enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE }; 00053 00054 // Per-process state 00055 struct proc { 00056 uint sz; // Size of process memory (bytes) 00057 pde_t* pgdir; // Page table 00058 char *kstack; // Bottom of kernel stack for this process 00059 enum procstate state; // Process state 00060 volatile int pid; // Process ID 00061 struct proc *parent; // Parent process 00062 struct trapframe *tf; // Trap frame for current syscall 00063 struct context *context; // swtch() here to run process 00064 void *chan; // If non-zero, sleeping on chan 00065 int killed; // If non-zero, have been killed 00066 struct file *ofile[NOFILE]; // Open files 00067 struct inode *cwd; // Current directory 00068 char name[16]; // Process name (debugging) 00069 }; 00070 00071 int proc_old_mmap(void *addr, int len, int prot, int flags, int fd, int offset); 00072 00073 00074 // Process memory is laid out contiguously, low addresses first: 00075 // text 00076 // original data and bss 00077 // fixed-size stack 00078 // expandable heap