. $ head *
. ==> asm.h <==
. //
. // assembler macros to create x86 segments
. //
.
. #define SEG_NULLASM \
. .word 0, 0; \
. .byte 0, 0, 0, 0
.
. // The 0xC0 means the limit is in 4096-byte units
. // and (for executable segments) 32-bit mode.
.
. ==> bio.c <==
. // Buffer cache.
. //
. // The buffer cache is a linked list of buf structures holding
. // cached copies of disk block contents. Caching disk blocks
. // in memory reduces the number of disk reads and also provides
. // a synchronization point for disk blocks used by multiple processes.
. //
. // Interface:
. // * To get a buffer for a particular disk block, call bread.
. // * After changing buffer data, call bwrite to write it to disk.
.
. ==> bootasm.S <==
. #include "asm.h"
. #include "memlayout.h"
. #include "mmu.h"
.
. # Start the first CPU: switch to 32-bit protected mode, jump into C.
. # The BIOS loads this code from the first sector of the hard disk into
. # memory at physical address 0x7c00 and starts executing in real mode
. # with %cs=0 %ip=7c00.
.
. .code16 # Assemble for 16-bit mode
.
. ==> bootmain.c <==
. // Boot loader.
. //
. // Part of the boot sector, along with bootasm.S, which calls bootmain().
. // bootasm.S has put the processor into protected 32-bit mode.
. // bootmain() loads an ELF kernel image from the disk starting at
. // sector 1 and then jumps to the kernel entry routine.
.
. #include "types.h"
. #include "elf.h"
. #include "x86.h"
.
. ==> buf.h <==
. struct buf {
. int flags;
. uint dev;
. uint sector;
. struct buf *prev; // LRU cache list
. struct buf *next;
. struct buf *qnext; // disk queue
. uchar data[512];
. };
. #define B_BUSY 0x1 // buffer is locked by some process
.
. ==> BUGS <==
. formatting:
. need to fix PAGEBREAK mechanism
.
. sh:
. can't always runcmd in child -- breaks cd.
. maybe should hard-code PATH=/ ?
.
.
. ==> cat.c <==
. #include "types.h"
. #include "stat.h"
. #include "user.h"
.
. char buf[512];
.
. void
. cat(int fd)
. {
. int n;
.
. ==> console.c <==
. // Console input and output.
. // Input is from the keyboard or serial port.
. // Output is written to the screen and serial port.
.
. #include "types.h"
. #include "defs.h"
. #include "param.h"
. #include "traps.h"
. #include "spinlock.h"
. #include "fs.h"
.
. ==> cuth <==
. #!/usr/bin/perl
.
. $| = 1;
.
. sub writefile($@){
. my ($file, @lines) = @_;
.
. sleep(1);
. open(F, ">$file") || die "open >$file: $!";
. print F @lines;
.
. ==> defs.h <==
. struct buf;
. struct context;
. struct file;
. struct inode;
. struct pipe;
. struct proc;
. struct spinlock;
. struct stat;
. struct superblock;
.
.
. ==> dot-bochsrc <==
. # You may now use double quotes around pathnames, in case
. # your pathname includes spaces.
.
. #=======================================================================
. # CONFIG_INTERFACE
. #
. # The configuration interface is a series of menus or dialog boxes that
. # allows you to change all the settings that control Bochs's behavior.
. # There are two choices of configuration interface: a text mode version
. # called "textconfig" and a graphical version called "wx". The text
.
. ==> echo.c <==
. #include "types.h"
. #include "stat.h"
. #include "user.h"
.
. int
. main(int argc, char *argv[])
. {
. int i;
.
. for(i = 1; i < argc; i++)
.
. ==> elf.h <==
. // 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];
. ushort type;
. ushort machine;
.
. ==> entry.S <==
. # Multiboot header, for multiboot boot loaders like GNU Grub.
. #
http://www.gnu.org/software/grub/manual/multiboot/multiboot.html
. #
. # Using GRUB 2, you can boot xv6 from a file stored in a
. #
Linux file system by copying kernel or kernelmemfs to /boot
. # and then adding this menu entry:
. #
. # menuentry "xv6" {
. # insmod ext2
. # set root='(hd0,msdos1)'
.
. ==> entryother.S <==
. #include "asm.h"
. #include "memlayout.h"
. #include "mmu.h"
.
. # Each non-boot CPU ("AP") is started up in response to a STARTUP
. # IPI from the boot CPU. Section B.4.2 of the Multi-Processor
. # Specification says that the AP will start in real mode with CS:IP
. # set to XY00:0000, where XY is an 8-bit value sent with the
. # STARTUP. Thus this code must start at a 4096-byte boundary.
. #
.
. ==> exec.c <==
. #include "types.h"
. #include "param.h"
. #include "memlayout.h"
. #include "mmu.h"
. #include "proc.h"
. #include "defs.h"
. #include "x86.h"
. #include "elf.h"
.
. int
.
. ==> fcntl.h <==
. #define O_RDONLY 0x000
. #define O_WRONLY 0x001
. #define O_RDWR 0x002
. #define O_CREATE 0x200
.
. ==> file.c <==
. //
. // File descriptors
. //
.
. #include "types.h"
. #include "defs.h"
. #include "param.h"
. #include "fs.h"
. #include "file.h"
. #include "spinlock.h"
.
. ==> file.h <==
. struct file {
. enum { FD_NONE, FD_PIPE, FD_INODE } type;
. int ref; // reference count
. char readable;
. char writable;
. struct pipe *pipe;
. struct inode *ip;
. uint off;
. };
.
.
. ==> forktest.c <==
. // Test that fork fails gracefully.
. // Tiny executable so that the limit can be filling the proc table.
.
. #include "types.h"
. #include "stat.h"
. #include "user.h"
.
. #define N 1000
.
. void
.
. ==> fs.c <==
. // File system implementation. Five layers:
. // + Blocks: allocator for raw disk blocks.
. // + Log: crash recovery for multi-step updates.
. // + Files: inode allocator, reading, writing, metadata.
. // + Directories: inode with special contents (list of other inodes!)
. // + Names: paths like /usr/rtm/xv6/fs.c for convenient naming.
. //
. // This file contains the low-level file system manipulation
. // routines. The (higher-level) system call implementations
. // are in sysfile.c.
.
. ==> fs.h <==
. // On-disk file system format.
. // Both the kernel and user programs use this header file.
.
. // Block 0 is unused.
. // Block 1 is super block.
. // Blocks 2 through sb.ninodes/IPB hold inodes.
. // Then free bitmap blocks holding sb.size bits.
. // Then sb.nblocks data blocks.
. // Then sb.nlog log blocks.
.
.
. ==> gdbutil <==
. # -*- gdb-script -*-
.
. # Utility functions to pretty-print x86 segment/interrupt descriptors.
. # To load this file, run "source gdbutil" in gdb.
. # printdesc and printdescs are the main entry points.
.
. # IA32 2007, Volume 3A, Table 3-2
. set $STS_T16A = 0x1
. set $STS_LDT = 0x2
. set $STS_T16B = 0x3
.
. ==> grep.c <==
. // Simple grep. Only supports ^ . * $ operators.
.
. #include "types.h"
. #include "stat.h"
. #include "user.h"
.
. char buf[1024];
. int match(char*, char*);
.
. void
.
. ==> ide.c <==
. // Simple PIO-based (non-DMA) IDE driver code.
.
. #include "types.h"
. #include "defs.h"
. #include "param.h"
. #include "memlayout.h"
. #include "mmu.h"
. #include "proc.h"
. #include "x86.h"
. #include "traps.h"
.
. ==> init.c <==
. // init: The initial user-level program
.
. #include "types.h"
. #include "stat.h"
. #include "user.h"
. #include "fcntl.h"
.
. char *argv[] = { "sh", 0 };
.
. int
.
. ==> initcode.S <==
. # Initial process execs /init.
.
. #include "syscall.h"
. #include "traps.h"
.
.
. # exec(init, argv)
. .globl start
. start:
. pushl $argv
.
. ==> ioapic.c <==
. // The I/O APIC manages hardware interrupts for an SMP system.
. //
http://www.intel.com/design/chipsets/datashts/29056601.pdf
. // See also picirq.c.
.
. #include "types.h"
. #include "defs.h"
. #include "traps.h"
.
. #define IOAPIC 0xFEC00000 // Default physical address of IO APIC
.
.
. ==> kalloc.c <==
. // Physical memory allocator, intended to allocate
. // memory for user processes, kernel stacks, page table pages,
. // and pipe buffers. Allocates 4096-byte pages.
.
. #include "types.h"
. #include "defs.h"
. #include "param.h"
. #include "memlayout.h"
. #include "mmu.h"
. #include "spinlock.h"
.
. ==> kbd.c <==
. #include "types.h"
. #include "x86.h"
. #include "defs.h"
. #include "kbd.h"
.
. int
. kbdgetc(void)
. {
. static uint shift;
. static uchar *charcode[4] = {
.
. ==> kbd.h <==
. // PC keyboard interface constants
.
. #define KBSTATP 0x64 // kbd controller status port(I)
. #define KBS_DIB 0x01 // kbd data in buffer
. #define KBDATAP 0x60 // kbd data port(I)
.
. #define NO 0
.
. #define SHIFT (1<<0)
. #define CTL (1<<1)
.
. ==> kernel.ld <==
. /* Simple linker script for the JOS kernel.
. See the GNU ld 'info' manual ("info ld") to learn the syntax. */
.
. OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
. OUTPUT_ARCH(i386)
. ENTRY(_start)
.
. SECTIONS
. {
. /* Link the kernel at this address: "." means the current address */
.
. ==> kill.c <==
. #include "types.h"
. #include "stat.h"
. #include "user.h"
.
. int
. main(int argc, char **argv)
. {
. int i;
.
. if(argc < 1){
.
. ==> lapic.c <==
. // The local APIC manages internal (non-I/O) interrupts.
. // See Chapter 8 & Appendix C of Intel processor manual volume 3.
.
. #include "types.h"
. #include "defs.h"
. #include "memlayout.h"
. #include "traps.h"
. #include "mmu.h"
. #include "x86.h"
.
.
. ==> LICENSE <==
. The xv6 software is:
.
. Copyright (c) 2006-2009 Frans Kaashoek, Robert Morris, Russ Cox,
. Massachusetts Institute of Technology
.
. Permission is hereby granted, free of charge, to any person obtaining
. a copy of this software and associated documentation files (the
. Software), to deal in the Software without restriction, including
. without limitation the rights to use, copy, modify, merge, publish,
. distribute, sublicense, and/or sell copies of the Software, and to
.
. ==> ln.c <==
. #include "types.h"
. #include "stat.h"
. #include "user.h"
.
. int
. main(int argc, char *argv[])
. {
. if(argc != 3){
. printf(2, "Usage: ln old new\n");
. exit();
.
. ==> log.c <==
. #include "types.h"
. #include "defs.h"
. #include "param.h"
. #include "spinlock.h"
. #include "fs.h"
. #include "buf.h"
.
. // Simple logging. Each system call that might write the file system
. // should be surrounded with begin_trans() and commit_trans() calls.
. //
.
. ==> ls.c <==
. #include "types.h"
. #include "stat.h"
. #include "user.h"
. #include "fs.h"
.
. char*
. fmtname(char *path)
. {
. static char buf[DIRSIZ+1];
. char *p;
.
. ==> main.c <==
. #include "types.h"
. #include "defs.h"
. #include "param.h"
. #include "memlayout.h"
. #include "mmu.h"
. #include "proc.h"
. #include "x86.h"
.
. static void startothers(void);
. static void mpmain(void) __attribute__;
.
. ==> Makefile <==
. OBJS = \
. bio.o\
. console.o\
. exec.o\
. file.o\
. fs.o\
. ide.o\
. ioapic.o\
. kalloc.o\
. kbd.o\
.
. ==> memide.c <==
. // Fake IDE disk; stores blocks in memory.
. // Useful for running kernel without scratch disk.
.
. #include "types.h"
. #include "defs.h"
. #include "param.h"
. #include "mmu.h"
. #include "proc.h"
. #include "x86.h"
. #include "traps.h"
.
. ==> memlayout.h <==
. // Memory layout
.
. #define EXTMEM 0x100000 // Start of extended memory
. #define PHYSTOP 0xE000000 // Top physical memory
. #define DEVSPACE 0xFE000000 // Other devices are at high addresses
.
. // Key addresses for address space layout (see kmap in vm.c for layout)
. #define KERNBASE 0x80000000 // First kernel virtual address
. #define KERNLINK (KERNBASE+EXTMEM) // Address where kernel is linked
.
.
. ==> mkdir.c <==
. #include "types.h"
. #include "stat.h"
. #include "user.h"
.
. int
. main(int argc, char *argv[])
. {
. int i;
.
. if(argc < 2){
.
. ==> mkfs.c <==
. #include <stdio.h>
. #include <unistd.h>
. #include <stdlib.h>
. #include <string.h>
. #include <fcntl.h>
. #include <assert.h>
.
. #define stat xv6_stat // avoid clash with host struct stat
. #include "types.h"
. #include "fs.h"
.
. ==> mmu.h <==
. // This file contains definitions for the
. // x86 memory management unit (MMU).
.
. // Eflags register
. #define FL_CF 0x00000001 // Carry Flag
. #define FL_PF 0x00000004 // Parity Flag
. #define FL_AF 0x00000010 // Auxiliary carry Flag
. #define FL_ZF 0x00000040 // Zero Flag
. #define FL_SF 0x00000080 // Sign Flag
. #define FL_TF 0x00000100 // Trap Flag
.
. ==> mp.c <==
. // Multiprocessor support
. // Search memory for MP description structures.
. //
http://developer.intel.com/design/pentium/datashts/24201606.pdf
.
. #include "types.h"
. #include "defs.h"
. #include "param.h"
. #include "memlayout.h"
. #include "mp.h"
. #include "x86.h"
.
. ==> mp.h <==
. // See MultiProcessor Specification Version 1.[14]
.
. struct mp { // floating pointer
. uchar signature[4]; // "_MP_"
. void *physaddr; // phys addr of MP config table
. uchar length; // 1
. uchar specrev; // [14]
. uchar checksum; // all bytes must add up to 0
. uchar type; // MP system config type
. uchar imcrp;
.
. ==> Notes <==
. bochs 2.2.6:
. ./configure --enable-smp --enable-disasm --enable-debugger --enable-all-optimizations --enable-4meg-pages --enable-global-pages --enable-pae --disable-reset-on-triple-fault
. bochs CVS after 2.2.6:
. ./configure --enable-smp --enable-disasm --enable-debugger --enable-all-optimizations --enable-4meg-pages --enable-global-pages --enable-pae
.
. bootmain.c doesn't work right if the ELF sections aren't
. sector-aligned. so you can't use ld -N. and the sections may also need
. to be non-zero length, only really matters for tiny "kernels".
.
. kernel loaded at 1 megabyte. stack same place that bootasm.S left it.
.
. ==> param.h <==
. #define NPROC 64 // maximum number of processes
. #define KSTACKSIZE 4096 // size of per-process kernel stack
. #define NCPU 8 // maximum number of CPUs
. #define NOFILE 16 // open files per process
. #define NFILE 100 // open files per system
. #define NBUF 10 // size of disk block cache
. #define NINODE 50 // maximum number of active i-nodes
. #define NDEV 10 // maximum major device number
. #define ROOTDEV 1 // device number of file system root disk
. #define MAXARG 32 // max exec arguments
.
. ==> picirq.c <==
. // Intel 8259A programmable interrupt controllers.
.
. #include "types.h"
. #include "x86.h"
. #include "traps.h"
.
. // I/O Addresses of the two programmable interrupt controllers
. #define IO_PIC1 0x20 // Master (IRQs 0-7)
. #define IO_PIC2 0xA0 // Slave (IRQs 8-15)
.
.
. ==> pipe.c <==
. #include "types.h"
. #include "defs.h"
. #include "param.h"
. #include "mmu.h"
. #include "proc.h"
. #include "fs.h"
. #include "file.h"
. #include "spinlock.h"
.
. #define PIPESIZE 512
.
. ==> pr.pl <==
. #!/usr/bin/perl
.
. use POSIX qw(strftime);
.
. if($ARGV[0] eq "-h"){
. shift @ARGV;
. $h = $ARGV[0];
. shift @ARGV;
. }else{
. $h = $ARGV[0];
.
. ==> printf.c <==
. #include "types.h"
. #include "stat.h"
. #include "user.h"
.
. static void
. putc(int fd, char c)
. {
. write(fd, &c, 1);
. }
.
.
. ==> printpcs <==
. #!/bin/sh
.
. # Decode the symbols from a panic EIP list
.
. # Find a working addr2line
. for p in i386-jos-elf-addr2line addr2line; do
. if which $p 2>&1 >/dev/null && \
. $p -h 2>&1 | grep -q '\belf32-i386\b'; then
. break
. fi
.
. ==> proc.c <==
. #include "types.h"
. #include "defs.h"
. #include "param.h"
. #include "memlayout.h"
. #include "mmu.h"
. #include "x86.h"
. #include "proc.h"
. #include "spinlock.h"
.
. struct {
.
. ==> proc.h <==
. // Segments in proc->gdt.
. #define NSEGS 7
.
. // Per-CPU state
. struct cpu {
. uchar id; // Local APIC ID; index into cpus[] below
. struct context *scheduler; // swtch() 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 started; // Has the CPU started?
.
. ==> README <==
. xv6 is a re-implementation of Dennis Ritchie's and Ken Thompson's Unix
. Version 6 (v6). xv6 loosely follows the structure and style of v6,
. but is implemented for a modern x86-based multiprocessor using ANSI C.
.
. ACKNOWLEDGMENTS
.
. xv6 is inspired by John Lions's Commentary on UNIX 6th Edition (Peer
. to Peer Communications; ISBN: 1-57398-013-7; 1st edition (June 14,
. 2000)). See also
http://pdos.csail.mit.edu/6.828/2012/v6.html, which
. provides pointers to on-line resources for v6.
.
. ==> rm.c <==
. #include "types.h"
. #include "stat.h"
. #include "user.h"
.
. int
. main(int argc, char *argv[])
. {
. int i;
.
. if(argc < 2){
.
. ==> runoff <==
. #!/bin/sh
.
. echo This script takes a minute to run. Be patient. 1>&2
.
. LC_CTYPE=C export LC_CTYPE
.
. # pad stdin to multiple of 120 lines
. pad()
. {
. awk '{print} END{for(; NR%120!=0; NR++) print ""}'
.
. ==> runoff.list <==
. # basic headers
. types.h
. param.h
. memlayout.h
. defs.h
. x86.h
. asm.h
. mmu.h
. elf.h
.
.
. ==> runoff.spec <==
. # Is sheet 01 (after the TOC) a left sheet or a right sheet?
. sheet1: right
.
. # "left" and "right" specify which page of a two-page spread a file
. # must start on. "left" means that a file must start on the first of
. # the two pages. "right" means it must start on the second of the two
. # pages. The file may start in either column.
. #
. # "even" and "odd" specify which column a file must start on. "even"
. # means it must start in the left of the two columns (00). "odd" means it
.
. ==> runoff1 <==
. #!/usr/bin/perl
.
. $n = 0;
. $v = 0;
. if($ARGV[0] eq "-v") {
. $v = 1;
. shift @ARGV;
. }
. if($ARGV[0] eq "-n") {
. $n = $ARGV[1];
.
. ==> sh.c <==
. // Shell.
.
. #include "types.h"
. #include "user.h"
. #include "fcntl.h"
.
. // Parsed command representation
. #define EXEC 1
. #define REDIR 2
. #define PIPE 3
.
. ==> show1 <==
. #!/bin/sh
.
. runoff1 "$@" | pr.pl -h "xv6/$@" | mpage -m50t50b -o -bLetter -T -t -2 -FLucidaSans-Typewriter83 -L60 >x.ps; gv --swap x.ps
.
. ==> sign.pl <==
. #!/usr/bin/perl
.
. open(SIG, $ARGV[0]) || die "open $ARGV[0]: $!";
.
. $n = sysread(SIG, $buf, 1000);
.
. if($n > 510){
. print STDERR "boot block too large: $n bytes (max 510)\n";
. exit 1;
. }
.
. ==> sleep1.p <==
. /*
. This file defines a Promela model for xv6's
. acquire, release, sleep, and wakeup, along with
. a model of a simple producer/consumer queue.
.
. To run:
. spinp sleep1.p
.
. (You may need to install Spin, available at
http://spinroot.com/.)
.
.
. ==> spinlock.c <==
. // Mutual exclusion spin locks.
.
. #include "types.h"
. #include "defs.h"
. #include "param.h"
. #include "x86.h"
. #include "memlayout.h"
. #include "mmu.h"
. #include "proc.h"
. #include "spinlock.h"
.
. ==> spinlock.h <==
. // Mutual exclusion lock.
. struct spinlock {
. uint locked; // Is the lock held?
.
. // For debugging:
. char *name; // Name of lock.
. struct cpu *cpu; // The cpu holding the lock.
. uint pcs[10]; // The call stack (an array of program counters)
. // that locked the lock.
. };
.
. ==> spinp <==
. #!/bin/sh
.
. if [ $# != 1 ] || [ ! -f "$1" ]; then
. echo 'usage: spinp file.p' 1>&2
. exit 1
. fi
.
. rm -f $1.trail
. spin -a $1 || exit 1
. cc -DSAFETY -DREACH -DMEMLIM=500 -o pan pan.c
.
. ==> stat.h <==
. #define T_DIR 1 // Directory
. #define T_FILE 2 // File
. #define T_DEV 3 // Device
.
. struct stat {
. short type; // Type of file
. int dev; // File system's disk device
. uint ino; // Inode number
. short nlink; // Number of links to file
. uint size; // Size of file in bytes
.
. ==> stressfs.c <==
. // Demonstrate that moving the "acquire" in iderw after the loop that
. // appends to the idequeue results in a race.
.
. // For this to work, you should also add a spin within iderw's
. // idequeue traversal loop. Adding the following demonstrated a panic
. // after about 5 runs of stressfs in QEMU on a 2.1GHz CPU:
. // for (i = 0; i < 40000; i++)
. // asm volatile("");
.
. #include "types.h"
.
. ==> string.c <==
. #include "types.h"
. #include "x86.h"
.
. void*
. memset(void *dst, int c, uint n)
. {
. if ((int)dst%4 == 0 && n%4 == 0){
. c &= 0xFF;
. stosl(dst, (c<<24)|(c<<16)|(c<<8)|c, n/4);
. } else
.
. ==> swtch.S <==
. # Context switch
. #
. # void swtch(struct context **old, struct context *new);
. #
. # Save current register context in old
. # and then load register context from new.
.
. .globl swtch
. swtch:
. movl 4(%esp), %eax
.
. ==> symlink.patch <==
. diff -r f8a4e40ab1d6 fs.c
. --- a/fs.c Thu Aug 30 14:32:06 2007 -0400
. +++ b/fs.c Thu Aug 30 14:29:02 2007 -0400
. @@ -577,12 +577,18 @@ skipelem(char *path, char *name)
. // If parent != 0, return the inode for the parent and copy the final
. // path element into name, which must have room for DIRSIZ bytes.
. static struct inode*
. #NAME?
. #NAME?
. {
.
. ==> syscall.c <==
. #include "types.h"
. #include "defs.h"
. #include "param.h"
. #include "memlayout.h"
. #include "mmu.h"
. #include "proc.h"
. #include "x86.h"
. #include "syscall.h"
.
. // User code makes a system call with INT T_SYSCALL.
.
. ==> syscall.h <==
. // System call numbers
. #define SYS_fork 1
. #define SYS_exit 2
. #define SYS_wait 3
. #define SYS_pipe 4
. #define SYS_read 5
. #define SYS_kill 6
. #define SYS_exec 7
. #define SYS_fstat 8
. #define SYS_chdir 9
.
. ==> sysfile.c <==
. //
. // File-system system calls.
. // Mostly argument checking, since we don't trust
. // user code, and calls into file.c and fs.c.
. //
.
. #include "types.h"
. #include "defs.h"
. #include "param.h"
. #include "stat.h"
.
. ==> sysproc.c <==
. #include "types.h"
. #include "x86.h"
. #include "defs.h"
. #include "param.h"
. #include "memlayout.h"
. #include "mmu.h"
. #include "proc.h"
.
. int
. sys_fork(void)
.
. ==> timer.c <==
. // Intel 8253/8254/82C54 Programmable Interval Timer (PIT).
. // Only used on uniprocessors;
. // SMP machines use the local APIC timer.
.
. #include "types.h"
. #include "defs.h"
. #include "traps.h"
. #include "x86.h"
.
. #define IO_TIMER1 0x040 // 8253 Timer #1
.
. ==> toc.ftr <==
.
.
. The source listing is preceded by a cross-reference that lists every defined
. constant, struct, global variable, and function in xv6. Each entry gives,
. on the same line as the name, the line number (or, in a few cases, numbers)
. where the name is defined. Successive lines in an entry list the line
. numbers where the name is used. For example, this entry:
.
. swtch 2658
. 0374 2428 2466 2657 2658
.
. ==> toc.hdr <==
. The numbers to the left of the file names in the table are sheet numbers.
. The source code has been printed in a double column format with fifty
. lines per column, giving one hundred lines per sheet (or page).
. Thus there is a convenient relationship between line numbers and sheet numbers.
.
.
.
. ==> trap.c <==
. #include "types.h"
. #include "defs.h"
. #include "param.h"
. #include "memlayout.h"
. #include "mmu.h"
. #include "proc.h"
. #include "x86.h"
. #include "traps.h"
. #include "spinlock.h"
.
.
. ==> trapasm.S <==
. #include "mmu.h"
.
. # vectors.S sends all traps here.
. .globl alltraps
. alltraps:
. # Build trap frame.
. pushl %ds
. pushl %es
. pushl %fs
. pushl %gs
.
. ==> traps.h <==
. // x86 trap and interrupt constants.
.
. // Processor-defined:
. #define T_DIVIDE 0 // divide error
. #define T_DEBUG 1 // debug exception
. #define T_NMI 2 // non-maskable interrupt
. #define T_BRKPT 3 // breakpoint
. #define T_OFLOW 4 // overflow
. #define T_BOUND 5 // bounds check
. #define T_ILLOP 6 // illegal opcode
.
. ==> TRICKS <==
. This file lists subtle things that might not be commented
. as well as they should be in the source code and that
. might be worth pointing out in a longer explanation or in class.
.
. ---
.
. [2009/07/12: No longer relevant; forkret1 changed
. and this is now cleaner.]
.
. forkret1 in trapasm.S is called with a tf argument.
.
. ==> types.h <==
. typedef unsigned int uint;
. typedef unsigned short ushort;
. typedef unsigned char uchar;
. typedef uint pde_t;
.
. ==> uart.c <==
. // Intel 8250 serial port (UART).
.
. #include "types.h"
. #include "defs.h"
. #include "param.h"
. #include "traps.h"
. #include "spinlock.h"
. #include "fs.h"
. #include "file.h"
. #include "mmu.h"
.
. ==> ulib.c <==
. #include "types.h"
. #include "stat.h"
. #include "fcntl.h"
. #include "user.h"
. #include "x86.h"
.
. char*
. strcpy(char *s, char *t)
. {
. char *os;
.
. ==> umalloc.c <==
. #include "types.h"
. #include "stat.h"
. #include "user.h"
. #include "param.h"
.
. // Memory allocator by Kernighan and Ritchie,
. // The C programming Language, 2nd ed. Section 8.7.
.
. typedef long Align;
.
.
. ==> user.h <==
. struct stat;
.
. // system calls
. int fork(void);
. int exit(void) __attribute__;
. int wait(void);
. int pipe(int*);
. int write(int, void*, int);
. int read(int, void*, int);
. int close(int);
.
. ==> usertests.c <==
. #include "param.h"
. #include "types.h"
. #include "stat.h"
. #include "user.h"
. #include "fs.h"
. #include "fcntl.h"
. #include "syscall.h"
. #include "traps.h"
. #include "memlayout.h"
.
.
. ==> usys.S <==
. #include "syscall.h"
. #include "traps.h"
.
. #define SYSCALL(name) \
. .globl name; \
. name: \
. movl $SYS_ ## name, %eax; \
. int $T_SYSCALL; \
. ret
.
.
. ==> vectors.pl <==
. #!/usr/bin/perl -w
.
. # Generate vectors.S, the trap/interrupt entry points.
. # There has to be one entry point per interrupt number
. # since otherwise there's no way for trap() to discover
. # the interrupt number.
.
. print "# generated by vectors.pl - do not edit\n";
. print "# handlers\n";
. print ".globl alltraps\n";
.
. ==> vm.c <==
. #include "param.h"
. #include "types.h"
. #include "defs.h"
. #include "x86.h"
. #include "memlayout.h"
. #include "mmu.h"
. #include "proc.h"
. #include "elf.h"
.
. extern char data[]; // defined by kernel.ld
.
. ==> wc.c <==
. #include "types.h"
. #include "stat.h"
. #include "user.h"
.
. char buf[512];
.
. void
. wc(int fd, char *name)
. {
. int i, n;
.
. ==> x86.h <==
. // Routines to let C code use special x86 instructions.
.
. static inline uchar
. inb(ushort port)
. {
. uchar data;
.
. asm volatile("in %1,%0" : "=a" (data) : "d" (port));
. return data;
. }
.
. ==> zombie.c <==
. // Create a zombie process that
. // must be reparented at exit.
.
. #include "types.h"
. #include "stat.h"
. #include "user.h"
.
. int
. main(void)
. {