Navigation Menu

Skip to content

Commit

Permalink
lab1
Browse files Browse the repository at this point in the history
  • Loading branch information
Austin Clements committed Sep 6, 2011
0 parents commit 52e7e6a
Show file tree
Hide file tree
Showing 43 changed files with 5,524 additions and 0 deletions.
30 changes: 30 additions & 0 deletions .gdbinit.tmpl
@@ -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
37 changes: 37 additions & 0 deletions CODING
@@ -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.
199 changes: 199 additions & 0 deletions GNUmakefile
@@ -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
32 changes: 32 additions & 0 deletions boot/Makefrag
@@ -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

85 changes: 85 additions & 0 deletions boot/boot.S
@@ -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

0 comments on commit 52e7e6a

Please sign in to comment.