Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Austin Clements
committed
Sep 6, 2011
0 parents
commit 52e7e6a
Showing
43 changed files
with
5,524 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
set $lastcs = -1 | ||
|
||
define hook-stop | ||
# There doesn't seem to be a good way to detect if we're in 16- or | ||
# 32-bit mode, but we always run with CS == 8 in 32-bit mode. | ||
if $cs == 8 || $cs == 27 | ||
if $lastcs != 8 && $lastcs != 27 | ||
set architecture i386 | ||
end | ||
x/i $pc | ||
else | ||
if $lastcs == -1 || $lastcs == 8 || $lastcs == 27 | ||
set architecture i8086 | ||
end | ||
# Translate the segment:offset into a physical address | ||
printf "[%4x:%4x] ", $cs, $eip | ||
x/i $cs*16+$eip | ||
end | ||
set $lastcs = $cs | ||
end | ||
|
||
echo + target remote localhost:1234\n | ||
target remote localhost:1234 | ||
|
||
# If this fails, it's probably because your GDB doesn't support ELF. | ||
# Look at the tools page at | ||
# http://pdos.csail.mit.edu/6.828/2009/tools.html | ||
# for instructions on building GDB with ELF support. | ||
echo + symbol-file obj/kern/kernel\n | ||
symbol-file obj/kern/kernel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
JOS CODING STANDARDS | ||
|
||
It's easier on everyone if all authors working on a shared | ||
code base are consistent in the way they write their programs. | ||
We have the following conventions in our code: | ||
|
||
* No space after the name of a function in a call | ||
For example, printf("hello") not printf ("hello"). | ||
|
||
* One space after keywords "if", "for", "while", "switch". | ||
For example, if (x) not if(x). | ||
|
||
* Space before braces. | ||
For example, if (x) { not if (x){. | ||
|
||
* Function names are all lower-case separated by underscores. | ||
|
||
* Beginning-of-line indentation via tabs, not spaces. | ||
|
||
* Preprocessor macros are always UPPERCASE. | ||
There are a few grandfathered exceptions: assert, panic, | ||
static_assert, offsetof. | ||
|
||
* Pointer types have spaces: (uint16_t *) not (uint16_t*). | ||
|
||
* Multi-word names are lower_case_with_underscores. | ||
|
||
* Comments in imported code are usually C /* ... */ comments. | ||
Comments in new code are C++ style //. | ||
|
||
* In a function definition, the function name starts a new line. | ||
Then you can grep -n '^foo' */*.c to find the definition of foo. | ||
|
||
* Functions that take no arguments are declared f(void) not f(). | ||
|
||
The included .dir-locals.el file will automatically set up the basic | ||
indentation style in Emacs. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
# | ||
# This makefile system follows the structuring conventions | ||
# recommended by Peter Miller in his excellent paper: | ||
# | ||
# Recursive Make Considered Harmful | ||
# http://aegis.sourceforge.net/auug97.pdf | ||
# | ||
OBJDIR := obj | ||
|
||
-include conf/lab.mk | ||
|
||
-include conf/env.mk | ||
|
||
ifndef LABSETUP | ||
LABSETUP := ./ | ||
endif | ||
|
||
TOP = . | ||
|
||
# Cross-compiler jos toolchain | ||
# | ||
# This Makefile will automatically use the cross-compiler toolchain | ||
# installed as 'i386-jos-elf-*', if one exists. If the host tools ('gcc', | ||
# 'objdump', and so forth) compile for a 32-bit x86 ELF target, that will | ||
# be detected as well. If you have the right compiler toolchain installed | ||
# using a different name, set GCCPREFIX explicitly in conf/env.mk | ||
|
||
# try to infer the correct GCCPREFIX | ||
ifndef GCCPREFIX | ||
GCCPREFIX := $(shell if i386-jos-elf-objdump -i 2>&1 | grep '^elf32-i386$$' >/dev/null 2>&1; \ | ||
then echo 'i386-jos-elf-'; \ | ||
elif objdump -i 2>&1 | grep 'elf32-i386' >/dev/null 2>&1; \ | ||
then echo ''; \ | ||
else echo "***" 1>&2; \ | ||
echo "*** Error: Couldn't find an i386-*-elf version of GCC/binutils." 1>&2; \ | ||
echo "*** Is the directory with i386-jos-elf-gcc in your PATH?" 1>&2; \ | ||
echo "*** If your i386-*-elf toolchain is installed with a command" 1>&2; \ | ||
echo "*** prefix other than 'i386-jos-elf-', set your GCCPREFIX" 1>&2; \ | ||
echo "*** environment variable to that prefix and run 'make' again." 1>&2; \ | ||
echo "*** To turn off this error, run 'gmake GCCPREFIX= ...'." 1>&2; \ | ||
echo "***" 1>&2; exit 1; fi) | ||
endif | ||
|
||
# try to infer the correct QEMU | ||
ifndef QEMU | ||
QEMU := $(shell if which qemu > /dev/null; \ | ||
then echo qemu; exit; \ | ||
else \ | ||
qemu=/Applications/Q.app/Contents/MacOS/i386-softmmu.app/Contents/MacOS/i386-softmmu; \ | ||
if test -x $$qemu; then echo $$qemu; exit; fi; fi; \ | ||
echo "***" 1>&2; \ | ||
echo "*** Error: Couldn't find a working QEMU executable." 1>&2; \ | ||
echo "*** Is the directory containing the qemu binary in your PATH" 1>&2; \ | ||
echo "*** or have you tried setting the QEMU variable in conf/env.mk?" 1>&2; \ | ||
echo "***" 1>&2; exit 1) | ||
endif | ||
|
||
# try to generate a unique GDB port | ||
GDBPORT := $(shell expr `id -u` % 5000 + 25000) | ||
# QEMU's gdb stub command line changed in 0.11 | ||
QEMUGDB = $(shell if $(QEMU) -nographic -help | grep -q '^-gdb'; \ | ||
then echo "-gdb tcp::$(GDBPORT)"; \ | ||
else echo "-s -p $(GDBPORT)"; fi) | ||
|
||
CC := $(GCCPREFIX)gcc -pipe | ||
AS := $(GCCPREFIX)as | ||
AR := $(GCCPREFIX)ar | ||
LD := $(GCCPREFIX)ld | ||
OBJCOPY := $(GCCPREFIX)objcopy | ||
OBJDUMP := $(GCCPREFIX)objdump | ||
NM := $(GCCPREFIX)nm | ||
|
||
# Native commands | ||
NCC := gcc $(CC_VER) -pipe | ||
TAR := gtar | ||
PERL := perl | ||
|
||
# Compiler flags | ||
# -fno-builtin is required to avoid refs to undefined functions in the kernel. | ||
# Only optimize to -O1 to discourage inlining, which complicates backtraces. | ||
CFLAGS := $(CFLAGS) $(DEFS) $(LABDEFS) -O1 -fno-builtin -I$(TOP) -MD | ||
CFLAGS += -fno-omit-frame-pointer | ||
CFLAGS += -Wall -Wno-format -Wno-unused -Werror -gstabs -m32 | ||
|
||
# Add -fno-stack-protector if the option exists. | ||
CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector) | ||
|
||
# Common linker flags | ||
LDFLAGS := -m elf_i386 | ||
|
||
# Linker flags for JOS user programs | ||
ULDFLAGS := -T user/user.ld | ||
|
||
GCC_LIB := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) | ||
|
||
# Lists that the */Makefrag makefile fragments will add to | ||
OBJDIRS := | ||
|
||
# Make sure that 'all' is the first target | ||
all: | ||
|
||
# Eliminate default suffix rules | ||
.SUFFIXES: | ||
|
||
# Delete target files if there is an error (or make is interrupted) | ||
.DELETE_ON_ERROR: | ||
|
||
# make it so that no intermediate .o files are ever deleted | ||
.PRECIOUS: %.o $(OBJDIR)/boot/%.o $(OBJDIR)/kern/%.o \ | ||
$(OBJDIR)/lib/%.o $(OBJDIR)/fs/%.o $(OBJDIR)/net/%.o \ | ||
$(OBJDIR)/user/%.o | ||
|
||
KERN_CFLAGS := $(CFLAGS) -DJOS_KERNEL -gstabs | ||
USER_CFLAGS := $(CFLAGS) -DJOS_USER -gstabs | ||
|
||
|
||
|
||
|
||
# Include Makefrags for subdirectories | ||
include boot/Makefrag | ||
include kern/Makefrag | ||
|
||
|
||
IMAGES = $(OBJDIR)/kern/kernel.img | ||
QEMUOPTS = -hda $(OBJDIR)/kern/kernel.img -serial mon:stdio $(QEMUEXTRA) | ||
|
||
.gdbinit: .gdbinit.tmpl | ||
sed "s/localhost:1234/localhost:$(GDBPORT)/" < $^ > $@ | ||
|
||
qemu: $(IMAGES) | ||
$(QEMU) $(QEMUOPTS) | ||
|
||
qemu-nox: $(IMAGES) | ||
@echo "***" | ||
@echo "*** Use Ctrl-a x to exit qemu" | ||
@echo "***" | ||
$(QEMU) -nographic $(QEMUOPTS) | ||
|
||
qemu-gdb: $(IMAGES) .gdbinit | ||
@echo "***" | ||
@echo "*** Now run 'gdb'." 1>&2 | ||
@echo "***" | ||
$(QEMU) $(QEMUOPTS) -S $(QEMUGDB) | ||
|
||
qemu-nox-gdb: $(IMAGES) .gdbinit | ||
@echo "***" | ||
@echo "*** Now run 'gdb'." 1>&2 | ||
@echo "***" | ||
$(QEMU) -nographic $(QEMUOPTS) -S $(QEMUGDB) | ||
|
||
print-qemu: | ||
@echo $(QEMU) | ||
|
||
print-gdbport: | ||
@echo $(GDBPORT) | ||
|
||
print-qemugdb: | ||
@echo $(QEMUGDB) | ||
|
||
# For deleting the build | ||
clean: | ||
rm -rf $(OBJDIR) .gdbinit jos.in | ||
|
||
realclean: clean | ||
rm -rf lab$(LAB).tar.gz jos.out | ||
|
||
distclean: realclean | ||
rm -rf conf/gcc.mk | ||
|
||
grade: $(LABSETUP)grade-lab$(LAB).sh | ||
@echo $(MAKE) clean | ||
@$(MAKE) clean || \ | ||
(echo "'make clean' failed. HINT: Do you have another running instance of JOS?" && exit 1) | ||
$(MAKE) all | ||
sh $(LABSETUP)grade-lab$(LAB).sh | ||
|
||
handin: tarball | ||
@echo Please visit http://pdos.csail.mit.edu/6.828/submit/ | ||
@echo and upload lab$(LAB)-handin.tar.gz. Thanks! | ||
|
||
tarball: realclean | ||
tar cf - `find . -type f | grep -v '^\.*$$' | grep -v '/CVS/' | grep -v '/\.svn/' | grep -v '/\.git/' | grep -v 'lab[0-9].*\.tar\.gz'` | gzip > lab$(LAB)-handin.tar.gz | ||
|
||
|
||
# This magic automatically generates makefile dependencies | ||
# for header files included from C source files we compile, | ||
# and keeps those dependencies up-to-date every time we recompile. | ||
# See 'mergedep.pl' for more information. | ||
$(OBJDIR)/.deps: $(foreach dir, $(OBJDIRS), $(wildcard $(OBJDIR)/$(dir)/*.d)) | ||
@mkdir -p $(@D) | ||
@$(PERL) mergedep.pl $@ $^ | ||
|
||
-include $(OBJDIR)/.deps | ||
|
||
always: | ||
@: | ||
|
||
.PHONY: all always \ | ||
handin tarball clean realclean distclean grade |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# | ||
# Makefile fragment for the JOS kernel. | ||
# This is NOT a complete makefile; | ||
# you must run GNU make in the top-level directory | ||
# where the GNUmakefile is located. | ||
# | ||
|
||
OBJDIRS += boot | ||
|
||
BOOT_OBJS := $(OBJDIR)/boot/boot.o $(OBJDIR)/boot/main.o | ||
|
||
$(OBJDIR)/boot/%.o: boot/%.c | ||
@echo + cc -Os $< | ||
@mkdir -p $(@D) | ||
$(V)$(CC) -nostdinc $(KERN_CFLAGS) -Os -c -o $@ $< | ||
|
||
$(OBJDIR)/boot/%.o: boot/%.S | ||
@echo + as $< | ||
@mkdir -p $(@D) | ||
$(V)$(CC) -nostdinc $(KERN_CFLAGS) -c -o $@ $< | ||
|
||
$(OBJDIR)/boot/main.o: boot/main.c | ||
@echo + cc -Os $< | ||
$(V)$(CC) -nostdinc $(KERN_CFLAGS) -Os -c -o $(OBJDIR)/boot/main.o boot/main.c | ||
|
||
$(OBJDIR)/boot/boot: $(BOOT_OBJS) | ||
@echo + ld boot/boot | ||
$(V)$(LD) $(LDFLAGS) -N -e start -Ttext 0x7C00 -o $@.out $^ | ||
$(V)$(OBJDUMP) -S $@.out >$@.asm | ||
$(V)$(OBJCOPY) -S -O binary -j .text $@.out $@ | ||
$(V)perl boot/sign.pl $(OBJDIR)/boot/boot | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
#include <inc/mmu.h> | ||
|
||
# Start the 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. | ||
|
||
.set PROT_MODE_CSEG, 0x8 # kernel code segment selector | ||
.set PROT_MODE_DSEG, 0x10 # kernel data segment selector | ||
.set CR0_PE_ON, 0x1 # protected mode enable flag | ||
|
||
.globl start | ||
start: | ||
.code16 # Assemble for 16-bit mode | ||
cli # Disable interrupts | ||
cld # String operations increment | ||
|
||
# Set up the important data segment registers (DS, ES, SS). | ||
xorw %ax,%ax # Segment number zero | ||
movw %ax,%ds # -> Data Segment | ||
movw %ax,%es # -> Extra Segment | ||
movw %ax,%ss # -> Stack Segment | ||
|
||
# Enable A20: | ||
# For backwards compatibility with the earliest PCs, physical | ||
# address line 20 is tied low, so that addresses higher than | ||
# 1MB wrap around to zero by default. This code undoes this. | ||
seta20.1: | ||
inb $0x64,%al # Wait for not busy | ||
testb $0x2,%al | ||
jnz seta20.1 | ||
|
||
movb $0xd1,%al # 0xd1 -> port 0x64 | ||
outb %al,$0x64 | ||
|
||
seta20.2: | ||
inb $0x64,%al # Wait for not busy | ||
testb $0x2,%al | ||
jnz seta20.2 | ||
|
||
movb $0xdf,%al # 0xdf -> port 0x60 | ||
outb %al,$0x60 | ||
|
||
# Switch from real to protected mode, using a bootstrap GDT | ||
# and segment translation that makes virtual addresses | ||
# identical to their physical addresses, so that the | ||
# effective memory map does not change during the switch. | ||
lgdt gdtdesc | ||
movl %cr0, %eax | ||
orl $CR0_PE_ON, %eax | ||
movl %eax, %cr0 | ||
|
||
# Jump to next instruction, but in 32-bit code segment. | ||
# Switches processor into 32-bit mode. | ||
ljmp $PROT_MODE_CSEG, $protcseg | ||
|
||
.code32 # Assemble for 32-bit mode | ||
protcseg: | ||
# Set up the protected-mode data segment registers | ||
movw $PROT_MODE_DSEG, %ax # Our data segment selector | ||
movw %ax, %ds # -> DS: Data Segment | ||
movw %ax, %es # -> ES: Extra Segment | ||
movw %ax, %fs # -> FS | ||
movw %ax, %gs # -> GS | ||
movw %ax, %ss # -> SS: Stack Segment | ||
|
||
# Set up the stack pointer and call into C. | ||
movl $start, %esp | ||
call bootmain | ||
|
||
# If bootmain returns (it shouldn't), loop. | ||
spin: | ||
jmp spin | ||
|
||
# Bootstrap GDT | ||
.p2align 2 # force 4 byte alignment | ||
gdt: | ||
SEG_NULL # null seg | ||
SEG(STA_X|STA_R, 0x0, 0xffffffff) # code seg | ||
SEG(STA_W, 0x0, 0xffffffff) # data seg | ||
|
||
gdtdesc: | ||
.word 0x17 # sizeof(gdt) - 1 | ||
.long gdt # address gdt | ||
|
Oops, something went wrong.