Skip to content

Commit

Permalink
more comments
Browse files Browse the repository at this point in the history
  • Loading branch information
rsc committed Sep 7, 2006
1 parent 7e01946 commit 31085bb
Show file tree
Hide file tree
Showing 13 changed files with 151 additions and 81 deletions.
6 changes: 3 additions & 3 deletions elf.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
//
// format of an ELF executable file
//
// Format of an ELF executable file

#define ELF_MAGIC 0x464C457FU // "\x7FELF" in little endian

// File header
struct elfhdr {
uint magic; // must equal ELF_MAGIC
uchar elf[12];
Expand All @@ -22,6 +21,7 @@ struct elfhdr {
ushort shstrndx;
};

// Program section header
struct proghdr {
uint type;
uint offset;
Expand Down
53 changes: 33 additions & 20 deletions fs.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
// on-disk file system format
// On-disk file system format.
// This header is shared between kernel and user space.

// Block 0 is unused.
// Block 1 is super block.
// Inodes start at block 2.

#define BSIZE 512 // block size

// sector 1 (2nd sector)
struct superblock{
uint size;
uint nblocks;
uint ninodes;
// File system super block
struct superblock {
uint size; // Size of file system (bytes???) xxx
uint nblocks; // Number of blocks
uint ninodes; // Number of inodes.
};

#define NADDRS (NDIRECT+1)
Expand All @@ -15,24 +20,31 @@ struct superblock{
#define NINDIRECT (BSIZE / sizeof(uint))
#define MAXFILE (NDIRECT + NINDIRECT)

// On-disk inode structure
struct dinode {
short type;
short major;
short minor;
short nlink;
uint size;
uint addrs[NADDRS];
short type; // File type
short major; // Major device number (T_DEV only)
short minor; // Minor device number (T_DEV only)
short nlink; // Number of links to inode in file system
uint size; // Size of file (bytes)
uint addrs[NADDRS]; // Data block addresses
};

#define T_DIR 1
#define T_FILE 2
#define T_DEV 3
#define T_DIR 1 // Directory
#define T_FILE 2 // File
#define T_DEV 3 // Special device

// Inodes per block.
#define IPB (BSIZE / sizeof(struct dinode))

// Block containing inode i
#define IBLOCK(i) ((i) / IPB + 2)

// Bitmap bits per block
#define BPB (BSIZE*8)

// sector 0 is unused, sector 1 is superblock, inodes start at sector 2
#define IPB (BSIZE / sizeof(struct dinode))
#define IBLOCK(inum) (inum / IPB + 2) // start of inode
#define BPB (BSIZE*8)
#define BBLOCK(b,ninodes) (b/BPB + (ninodes/IPB) + 3) // start of bitmap
// Block containing bit for block b
#define BBLOCK(b, ninodes) (b/BPB + (ninodes)/IPB + 3)

#define DIRSIZ 14

Expand All @@ -41,4 +53,5 @@ struct dirent {
char name[DIRSIZ];
};

extern uint rootdev; // Device number of root file system

4 changes: 4 additions & 0 deletions kalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ kinit(void)
kfree(start, mem * PAGE);
}

// Free the len bytes of memory pointed at by cp,
// which normally should have been returned by a
// call to kalloc(cp). (The exception is when
// initializing the allocator; see kinit above.)
void
kfree(char *cp, int len)
{
Expand Down
1 change: 1 addition & 0 deletions mkdir.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "stat.h"
#include "user.h"

int
main(int argc, char *argv[])
{
int i;
Expand Down
5 changes: 4 additions & 1 deletion proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ copyproc(struct proc *p)
return np;
}

uint
// Grow current process's memory by n bytes.
// Return old size on success, -1 on failure.
int
growproc(int n)
{
struct proc *cp = curproc[cpu()];
Expand All @@ -154,6 +156,7 @@ growproc(int n)
return cp->sz - n;
}

//PAGEBREAK: 42
// Per-CPU process scheduler.
// Each CPU calls scheduler() after setting itself up.
// Scheduler never returns. It loops, doing:
Expand Down
76 changes: 40 additions & 36 deletions proc.h
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
// segments in proc->gdt
#define SEG_KCODE 1 // kernel code
#define SEG_KDATA 2 // kernel data+stack
// 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 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 {
// saved registers for kernel context switches
// don't need to save all the fs etc. registers because
// they are constant across kernel contexts
// save all the regular registers so we don't care which are caller save
// don't save eax because that's the return register
// layout known to setjmp.S
int ebx;
int ecx;
int edx;
Expand All @@ -25,39 +26,42 @@ struct jmpbuf {

enum proc_state { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };

struct proc{
char *mem; // start of process's memory (a kernel address)
// process memory is laid out contiguously:
// text
// original data and bss
// fixed-size stack
// expandable heap
uint sz; // user memory size
char *kstack; // kernel stack
enum proc_state state;
int pid;
int ppid;
void *chan; // sleep
int killed;
struct file *ofile[NOFILE];
struct inode *cwd;
struct jmpbuf jmpbuf;
struct trapframe *tf; // points into kstack, used to find user regs
// 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 inode *cwd; // Current directory
struct jmpbuf jmpbuf; // Jump here to run process
struct trapframe *tf; // Trap frame for current interrupt
};

// Process memory is laid out contiguously:
// text
// original data and bss
// fixed-size stack
// expandable heap

extern struct proc proc[];
extern struct proc *curproc[NCPU]; // can be NULL if no proc running.
extern struct proc *curproc[NCPU]; // Current (running) process per CPU

#define MPSTACK 512

// Per-CPU state
struct cpu {
uchar apicid; // Local APIC ID
struct jmpbuf jmpbuf;
struct taskstate ts; // only to give cpu address of kernel stack
struct segdesc gdt[NSEGS];
char mpstack[MPSTACK]; // per-cpu start-up stack
volatile int booted;
int nlock; // # of locks currently held
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];
Expand Down
27 changes: 22 additions & 5 deletions setjmp.S
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
# int setjmp(struct jmpbuf *jmp);
# void longjmp(struct jmpbuf *jmp);
#
# Setjmp saves its stack environment in jmp
# for later use by longjmp. It returns 0.
#
# Longjmp restores the environment saved by
# the last call of setjmp. It then causes
# execution to continue as if the call of setjmp
# had just returned 1.
#
# The caller of setjmp must not itself have
# returned in the interim. All accessible data
# have values as of the time longjmp was called.
#
# [Description, but not code, borrowed from Plan 9.]

.globl setjmp
setjmp:
movl 4(%esp), %eax
Expand All @@ -9,10 +26,10 @@ setjmp:
movl %edi, 16(%eax)
movl %esp, 20(%eax)
movl %ebp, 24(%eax)
pushl 0(%esp) /* %eip */
pushl 0(%esp) # %eip
popl 28(%eax)

movl $0, %eax /* return value */
movl $0, %eax # return value
ret

.globl longjmp
Expand All @@ -27,8 +44,8 @@ longjmp:
movl 20(%eax), %esp
movl 24(%eax), %ebp

addl $4, %esp /* pop %eip into thin air */
pushl 28(%eax) /* push new %eip */
addl $4, %esp # pop and discard %eip
pushl 28(%eax) # push new %eip

movl $1, %eax /* return value (appears to come from setjmp!) */
movl $1, %eax # return value (appears to come from setjmp!)
ret
16 changes: 15 additions & 1 deletion spinlock.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Mutual exclusion spin locks.

#include "types.h"
#include "defs.h"
#include "x86.h"
Expand All @@ -16,6 +18,7 @@ initlock(struct spinlock *lock, char *name)
lock->cpu = 0xffffffff;
}

// Record the current call stack in pcs[] by following the %ebp chain.
void
getcallerpcs(void *v, uint pcs[])
{
Expand All @@ -31,6 +34,10 @@ getcallerpcs(void *v, uint pcs[])
pcs[i] = 0;
}

// Acquire the lock.
// Loops (spins) until the lock is acquired.
// (Because contention is handled by spinning, must not
// go to sleep holding any locks.)
void
acquire(struct spinlock *lock)
{
Expand All @@ -44,10 +51,16 @@ acquire(struct spinlock *lock)
while(cmpxchg(0, 1, &lock->locked) == 1)
;
cpuid(0, 0, 0, 0, 0); // memory barrier
getcallerpcs(&lock, lock->pcs);

// Record info about lock acquisition for debugging.
// The +10 is only so that we can tell the difference
// between forgetting to initialize lock->cpu
// and holding a lock on cpu 0.
lock->cpu = cpu() + 10;
getcallerpcs(&lock, lock->pcs);
}

// Release the lock.
void
release(struct spinlock *lock)
{
Expand All @@ -63,6 +76,7 @@ release(struct spinlock *lock)
sti();
}

// Check whether this cpu is holding the lock.
int
holding(struct spinlock *lock)
{
Expand Down
12 changes: 8 additions & 4 deletions spinlock.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// Mutual exclusion lock.
struct spinlock {
char *name;
uint locked;
int cpu;
uint pcs[10];
uint locked; // Is the lock held?

// For debugging:
char *name; // Name of lock.
int cpu; // The number of the cpu holding the lock.
uint pcs[10]; // The call stack (an array of program counters)
// that locked the lock.
};
10 changes: 5 additions & 5 deletions stat.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
struct stat {
int dev;
uint ino;
short type;
short nlink;
uint size;
int dev; // Device number
uint ino; // Inode number on device
short type; // Type of file
short nlink; // Number of links to file
uint size; // Size of file in bytes
};
Loading

0 comments on commit 31085bb

Please sign in to comment.