Skip to content

Commit 8df676d

Browse files
committed
Update kernels1 code from lecture/pset
1 parent ac9b2c2 commit 8df676d

23 files changed

+649
-430
lines changed

kernels1/ABOUT.md

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ This is WeensyOS, a teaching operating system built for Harvard’s
66

77
Quickstart: `make run` will run the OS using the [QEMU] emulator.
88

9-
Running the OS
10-
--------------
9+
Make targets
10+
------------
1111

1212
`make run` will run the OS. On Docker, the OS will run in your terminal
1313
window; on a Linux virtual machine, QEMU will open a new window. (`make
@@ -21,11 +21,14 @@ WeensyOS creates a debug log in `log.txt`. Run `make LOG=stdio run` to
2121
redirect the debug log to the standard output, or `make
2222
LOG=file:FILENAME run` to redirect it to `FILENAME`.
2323

24-
Run `make D=1 run` to ask QEMU to print verbose information about interrupts
25-
and CPU resets to the standard error. This setting will also cause QEMU to
26-
quit after encountering a [triple fault][] (normally it will reboot).
24+
`make D=1 run` tells QEMU to print verbose information about interrupts and
25+
CPU resets to the file `qemu.log`. This setting will also cause QEMU to quit
26+
after encountering a [triple fault][] (normally it will reboot).
27+
28+
`make run-PROGRAM` runs `p-PROGRAM.cc` as the first non-init process. The
29+
default is `allocators`, which runs four copies of `p-allocator.cc`.
2730

28-
Finally, run `make clean` to clean up your directory.
31+
Finally, `make clean` cleans up your directory.
2932

3033
Building
3134
--------
@@ -44,19 +47,23 @@ but only version 5 or later.
4447

4548
3. Install Homebrew’s QEMU: `brew install qemu`
4649

47-
4. Tap [Sergio Benitez’s collection of cross-compilers](https://github.com/SergioBenitez/homebrew-osxct): `brew tap SergioBenitez/osxct`
48-
49-
5. Install the `x86_64-unknown-linux-gnu` cross-compiler toolchain: `brew install x86_64-unknown-linux-gnu`
50+
4. Install a collection of cross-compilers for x86-64 Linux. At time of
51+
writing, [this
52+
collection](https://github.com/messense/homebrew-macos-cross-toolchains):
53+
works: `brew tap messense/homebrew-macos-cross-toolchains; brew install
54+
x86_64-unknown-linux-gnu`
5055

51-
6. Create a file `config.mk` in this directory containing this:
56+
5. Create a file `config.mk` in this directory containing this:
5257

5358
```make
5459
CCPREFIX=x86_64-unknown-linux-gnu-
55-
HOSTCC=gcc-12
56-
HOSTCXX=g++-12
60+
HOSTCC=gcc-14
61+
HOSTCXX=g++-14
5762
```
5863

59-
(Do not `git add config.mk`: it is intended for local configuration.)
64+
But do not add `config.mk` to your repository! It configures the
65+
build for your working directory environment, and the grading
66+
server (for instance) can’t use those settings.
6067

6168
Troubleshooting
6269
---------------
@@ -72,7 +79,8 @@ OS has become unresponsive).
7279
enter Docker via `../cs61-run-docker` before running `make stop`.
7380

7481
* If QEMU is running in a terminal window (in Docker, for instance), then
75-
press `Alt-2`. This will bring up the QEMU Monitor, which looks like this:
82+
press `Alt-2` (or `Option-2`). This will bring up the QEMU Monitor, which
83+
looks like this:
7684

7785
```
7886
compat_monitor0 console
@@ -85,9 +93,9 @@ OS has become unresponsive).
8593
command to restore it.
8694

8795
If `Alt-2` does not work, you may need to configure your terminal to
88-
properly send the Alt key. For instance, on Mac OS X’s Terminal, go to
89-
Terminal > Preferences > Keyboard and select “Use Option as Meta key”. You
90-
can also configure a special keyboard shortcut that sends the `Escape 2`
96+
properly send the Alt key. For instance, on Mac OS X’s Terminal, go to the
97+
Edit menu, select “Use Option as Meta key”, and press `Option-2`. You can
98+
also configure a special keyboard shortcut that sends the `Escape 2`
9199
sequence.
92100

93101
Run `make run-gdb` to start up the OS with support for GDB debugging.

kernels1/COPYRIGHT

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
The files in this directory are:
22

33
/*
4-
* Copyright (C) 2006-2022 Eddie Kohler
4+
* Copyright (C) 2006-2024 Eddie Kohler
55
* Copyright (C) 2005 Regents of the University of California
66
* Copyright (C) 1997 Massachusetts Institute of Technology
77
*

kernels1/GNUmakefile

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
QEMUIMAGEFILES = weensyos.img
22
all: $(QEMUIMAGEFILES)
3+
include build/flags.mk
34

45
# Place local configuration options, such as `CC=clang`, in
56
# `config.mk` so you don't have to list them every time.
6-
-include config.mk
7+
CONFIG ?= config.mk
8+
-include $(CONFIG)
79

810
# `$(V)` controls whether the makefiles print verbose commands (the shell
911
# commands run by Make) or brief commands (like `COMPILE`).
@@ -31,7 +33,9 @@ NCPU = 1
3133
LOG ?= file:log.txt
3234
QEMUOPT = -net none -parallel $(LOG) -smp $(NCPU)
3335
ifeq ($(D),1)
34-
QEMUOPT += -d int,cpu_reset,guest_errors -no-reboot
36+
QEMUOPT += -d int,cpu_reset,guest_errors -no-reboot -D qemu.log
37+
else ifeq ($(D),2)
38+
QEMUOPT += -d guest_errors -no-reboot -D qemu.log
3539
endif
3640
ifneq ($(NOGDB),1)
3741
QEMUGDB ?= -gdb tcp::12949
@@ -40,6 +44,8 @@ ifeq ($(STOP),1)
4044
QEMUOPT += -S
4145
endif
4246

47+
QEMURANDSEED := $(strip $(shell od -N8 -tu8 -An /dev/urandom))
48+
4349

4450
# Sets of object files
4551

@@ -91,33 +97,33 @@ endif
9197
# How to make object files
9298

9399
$(OBJDIR)/%.ko: %.cc $(KERNELBUILDSTAMPS)
94-
$(call cxxcompile,$(KERNELCXXFLAGS) -O1 -DWEENSYOS_KERNEL -c $< -o $@,COMPILE $<)
100+
$(call cxxcompile,-O1 $(KERNELCXXFLAGS) -DWEENSYOS_KERNEL -c $< -o $@,COMPILE $<)
95101

96102
$(OBJDIR)/%.ko: %.S $(OBJDIR)/k-asm.h $(KERNELBUILDSTAMPS)
97103
$(call assemble,-O2 -c $< -o $@,ASSEMBLE $<)
98104

99105
$(OBJDIR)/boot.o: $(OBJDIR)/%.o: boot.cc $(KERNELBUILDSTAMPS)
100-
$(call cxxcompile,$(CXXFLAGS) -Os -fomit-frame-pointer -DWEENSYOS_KERNEL -c $< -o $@,COMPILE $<)
106+
$(call cxxcompile,-Os $(CXXFLAGS) -fomit-frame-pointer -c $< -o $@,COMPILE $<)
101107

102108
$(OBJDIR)/bootentry.o: $(OBJDIR)/%.o: \
103109
bootentry.S $(OBJDIR)/k-asm.h $(KERNELBUILDSTAMPS)
104110
$(call assemble,-Os -fomit-frame-pointer -c $< -o $@,ASSEMBLE $<)
105111

106112
$(OBJDIR)/%.uo: %.cc $(BUILDSTAMPS)
107-
$(call cxxcompile,$(CXXFLAGS) -O1 -DWEENSYOS_PROCESS -c $< -o $@,COMPILE $<)
113+
$(call cxxcompile,-O1 $(CXXFLAGS) -DWEENSYOS_PROCESS -c $< -o $@,COMPILE $<)
108114

109115
$(OBJDIR)/%.uo: %.S $(OBJDIR)/u-asm.h $(BUILDSTAMPS)
110116
$(call assemble,-O2 -c $< -o $@,ASSEMBLE $<)
111117

112118

113119
# How to make supporting source files
114120

115-
$(OBJDIR)/k-asm.h: kernel.hh lib.hh types.h x86-64.h build/mkkernelasm.awk $(KERNELBUILDSTAMPS)
116-
$(call cxxcompile,-dM -E kernel.hh | awk -f build/mkkernelasm.awk | sort > $@,CREATE $@)
121+
$(OBJDIR)/k-asm.h: $(KERNELBUILDSTAMPS)
122+
$(call run,$(k_asm_h_input_command) | $(asm_h_build_command) > $@,CREATE $@)
117123
@if test ! -s $@; then echo '* Error creating $@!' 1>&2; exit 1; fi
118124

119-
$(OBJDIR)/u-asm.h: u-lib.hh lib.hh types.h x86-64.h build/mkkernelasm.awk $(BUILDSTAMPS)
120-
$(call cxxcompile,-dM -E u-lib.hh | awk -f build/mkkernelasm.awk | sort > $@,CREATE $@)
125+
$(OBJDIR)/u-asm.h: $(BUILDSTAMPS)
126+
$(call run,$(u_asm_h_input_command) | $(asm_h_build_command) > $@,CREATE $@)
121127
@if test ! -s $@; then echo '* Error creating $@!' 1>&2; exit 1; fi
122128

123129
$(OBJDIR)/k-firstprocess.h:
@@ -127,7 +133,7 @@ $(OBJDIR)/k-foreachimage.h: build/mkforeachimage.awk $(PROCESSES_BUILDSTAMP)
127133
$(call run,awk -f build/mkforeachimage.awk -v processes="$(PROCESSES)" > $@,CREATE $@)
128134

129135
$(OBJDIR)/firstprocess.gdb:
130-
$(call run,if test "$(WEENSYOS_FIRST_PROCESS)" = allocators; then echo "add-symbol-file obj/p-allocator.full 0x100000"; echo "add-symbol-file obj/p-allocator2.full 0x140000"; echo "add-symbol-file obj/p-allocator3.full 0x180000"; echo "add-symbol-file obj/p-allocator4.full 0x1C0000"; else echo "add-symbol-file obj/p-$(WEENSYOS_FIRST_PROCESS).full 0x100000"; fi > $@,CREATE $@)
136+
$(call run,if test "$(WEENSYOS_FIRST_PROCESS)" = friends; then echo "add-symbol-file obj/p-alice.full 0x100000"; echo "add-symbol-file obj/p-eve.full 0x140000"; else echo "add-symbol-file obj/p-$(WEENSYOS_FIRST_PROCESS).full 0x100000"; fi > $@,CREATE $@)
131137

132138
$(OBJDIR)/k-hardware.ko: $(OBJDIR)/k-foreachimage.h
133139

@@ -158,7 +164,7 @@ $(OBJDIR)/%: $(OBJDIR)/%.full
158164
$(call run,$(QUIETOBJCOPY) -j .text -j .rodata -j .data -j .bss -j .ctors -j .init_array $<,STRIP,$@)
159165

160166
$(OBJDIR)/bootsector: $(BOOT_OBJS) build/boot.ld
161-
$(call link,-T build/boot.ld -o $@.full $(BOOT_OBJS),LINK)
167+
$(call link,-T build/boot.ld -z noexecstack -o $@.full $(BOOT_OBJS),LINK)
162168
$(call run,$(OBJDUMP) -C -S $@.full >$@.asm)
163169
$(call run,$(NM) -n $@.full >$@.sym)
164170
$(call run,$(OBJCOPY) -S -O binary -j .text $@.full $@)
@@ -167,19 +173,19 @@ $(OBJDIR)/bootsector: $(BOOT_OBJS) build/boot.ld
167173
# How to make host program for ensuring a loaded symbol table
168174

169175
$(OBJDIR)/mkchickadeesymtab: build/mkchickadeesymtab.cc $(BUILDSTAMPS)
170-
$(call run,$(HOSTCXX) $(CPPFLAGS) $(HOSTCXXFLAGS) $(DEPCFLAGS) -g -o $@,HOSTCOMPILE,$<)
176+
$(call run,$(HOSTCXX) $(HOSTCPPFLAGS) $(HOSTCXXFLAGS) $(DEPCFLAGS) -g -o $@,HOSTCOMPILE,$<)
171177

172178

173179
# How to make host programs for constructing & checking file systems
174180

175181
$(OBJDIR)/%.o: %.cc $(BUILDSTAMPS)
176-
$(call run,$(HOSTCXX) $(CPPFLAGS) $(HOSTCXXFLAGS) $(DEPCFLAGS) -c -o $@,HOSTCOMPILE,$<)
182+
$(call run,$(HOSTCXX) $(HOSTCPPFLAGS) $(HOSTCXXFLAGS) $(DEPCFLAGS) -c -o $@,HOSTCOMPILE,$<)
177183

178184
$(OBJDIR)/%.o: build/%.cc $(BUILDSTAMPS)
179-
$(call run,$(HOSTCXX) $(CPPFLAGS) $(HOSTCXXFLAGS) $(DEPCFLAGS) -c -o $@,HOSTCOMPILE,$<)
185+
$(call run,$(HOSTCXX) $(HOSTCPPFLAGS) $(HOSTCXXFLAGS) $(DEPCFLAGS) -c -o $@,HOSTCOMPILE,$<)
180186

181187
$(OBJDIR)/mkbootdisk: build/mkbootdisk.cc $(BUILDSTAMPS)
182-
$(call run,$(HOSTCXX) $(CPPFLAGS) $(HOSTCXXFLAGS) $(DEPCFLAGS) -g -o $@,HOSTCOMPILE,$<)
188+
$(call run,$(HOSTCXX) $(HOSTCPPFLAGS) $(HOSTCXXFLAGS) $(DEPCFLAGS) -g -o $@,HOSTCOMPILE,$<)
183189

184190

185191
weensyos.img: $(OBJDIR)/mkbootdisk $(OBJDIR)/bootsector $(OBJDIR)/kernel
@@ -219,7 +225,7 @@ run-gdb-$(RUNSUFFIX): run-gdb
219225
run-gdb-graphic-$(RUNSUFFIX): run-gdb-graphic
220226
run-gdb-console-$(RUNSUFFIX): run-gdb-console
221227

222-
# Kill all my qemus
228+
# Stop all my qemus
223229
stop kill:
224230
-killall -u $$(whoami) $(QEMU)
225231
@sleep 0.2; if ps -U $$(whoami) | grep $(QEMU) >/dev/null; then killall -9 -u $$(whoami) $(QEMU); fi

kernels1/boot.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
// the boot device (hard drive) into memory at address 0x7C00, and jumps to
1515
// that address.
1616
//
17-
// The boot loader is contained in bootstart.S and boot.c. Control starts
18-
// in bootstart.S, which initializes the CPU and sets up a stack, then
17+
// The boot loader is contained in bootentry.S and boot.cc. Control starts
18+
// in bootentry.S, which initializes the CPU and sets up a stack, then
1919
// transfers here. This code reads in the kernel image and calls the
2020
// kernel.
2121
//
@@ -56,8 +56,9 @@ static void boot_readseg(uintptr_t dst, uint32_t src_sect,
5656

5757
// jump to the kernel
5858
using kernel_entry_t = void (*)();
59-
[[noreturn]] kernel_entry_t kernel_entry = (kernel_entry_t) ELFHDR->e_entry;
59+
kernel_entry_t kernel_entry = (kernel_entry_t) ELFHDR->e_entry;
6060
kernel_entry();
61+
__builtin_unreachable(); // tell compiler `kernel_entry` does not return
6162
}
6263

6364

kernels1/bootentry.S

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# Then it jumps to address 0x7C00 and the OS starts running!
88
#
99
# This file contains the code loaded at that address.
10-
# The `boot_start` routine switches the CPU out of compatibility mode,
10+
# The `boot_entry` routine switches the CPU out of compatibility mode,
1111
# then calls `boot` from `boot.cc` to finish the booting process.
1212
#
1313
# There is no need to understand this code in detail!
@@ -20,34 +20,35 @@
2020
# For Your Information: COMPATIBILITY MODES
2121
#
2222
# The Intel x86 architecture has many compatibility modes, going back to
23-
# the 8086, which supported only 16-bit addresses. When the BIOS calls
24-
# into the OS, it is running in the "most compatible" mode, 16-bit real
23+
# the 8086, which supported only 16-bit addresses. In the CPU we expect,
24+
# the BIOS starts the OS while running in the oldest mode, 16-bit real
2525
# mode. The machine acts like addresses are only 16 bits long,
2626
# there's no paging support, and there isn't even any support for
2727
# user-mode applications. The following weird magic transitions the
2828
# processor to 64-bit mode and sets up a page table suitable for initial
29-
# kernel execution.
29+
# kernel execution. More recent iterations of 64-bit processors boot
30+
# directly into 64-bit mode.
3031
#
3132
###############################################################################
3233

3334
/* import constants from kernel.hh and x86-64.h */
3435
#include "obj/k-asm.h"
3536

36-
.globl boot_start # Entry point
37-
boot_start:
37+
.globl boot_entry # Entry point
38+
boot_entry:
3839
.code16 # This runs in real mode
3940
cli # Disable interrupts
4041
cld # String operations increment
4142

4243
# All segments are initially 0.
4344
# Set up the stack pointer, growing downward from 0x7c00.
44-
movw $boot_start, %sp
45+
movw $boot_entry, %sp
4546

4647
notify_bios64:
4748
# Notify the BIOS (the machine's firmware) to optimize itself
4849
# for x86-64 code. https://wiki.osdev.org/X86-64
4950
movw $0xEC00, %ax
50-
movw $2, %dx
51+
movw $2, %bx
5152
int $0x15
5253

5354
init_boot_pagetable:

kernels1/build/boot.ld

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
OUTPUT_FORMAT(elf64-x86-64)
22
OUTPUT_ARCH(i386:x86-64)
3-
ENTRY(boot_start)
3+
ENTRY(boot_entry)
44

55
SECTIONS {
66
. = 0x7c00;

kernels1/build/findgcc.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#! /bin/sh
22

3-
# Look for gcc-12 or gcc-11 or gcc-10 or gcc-9.
4-
wantv=9
3+
# Look for gcc-{14,9}; prefer gcc-12 or above
4+
wantv=12
55

66
ver1 () {
77
( $1 -dumpversion 2>/dev/null || echo 0 ) | sed 's/[^0-9].*//'
@@ -12,7 +12,7 @@ if "$prog" -v 2>&1 | grep '^gcc' >/dev/null; then
1212
base=`echo "$prog" | sed 's/^\([^g]\)/g\1/'`
1313
v=`ver1 "$prog"`
1414
if [ $v -lt $wantv ]; then
15-
for vx in 12 11 10 9; do
15+
for vx in 14 13 12 11 10 9; do
1616
if [ `ver1 "$base-$vx"` -ge $wantv ]; then
1717
echo "$base-$vx"; exit
1818
fi

kernels1/build/flags.mk

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Initialize compiler flags so `config.mk` can augment them
2+
3+
# Set up dependency files
4+
DEPCFLAGS = -MD -MF $(DEPSDIR)/$(@F).d -MP
5+
6+
# Flags for building programs that run on the host (not in WeensyOS)
7+
HOSTCPPFLAGS = $(DEFS) -I.
8+
HOSTCFLAGS := $(CFLAGS) -std=gnu2x -Wall -W
9+
HOSTCXXFLAGS := $(CXXFLAGS) -std=gnu++2a -Wall -W
10+
11+
# Flags for building WeensyOS kernel and process code
12+
CPPFLAGS = $(DEFS) -I.
13+
14+
CCOMMONFLAGS := -m64 -mno-mmx -mno-sse -mno-sse2 -mno-sse3 \
15+
-mno-3dnow -ffreestanding -fno-pic \
16+
-fno-omit-frame-pointer -mno-omit-leaf-frame-pointer \
17+
-fno-stack-protector \
18+
-Wall -W -Wshadow -Wno-format -Wno-unused-parameter
19+
20+
CFLAGS := $(CFLAGS) $(CCOMMONFLAGS) -std=gnu2x -gdwarf-4
21+
22+
CXXFLAGS := $(CXXFLAGS) $(CCOMMONFLAGS) -std=gnu++2a \
23+
-fno-exceptions -fno-rtti -gdwarf-4 -ffunction-sections
24+
KERNELCXXFLAGS := $(CXXFLAGS) -mno-red-zone $(SANITIZEFLAGS)
25+
26+
ASFLAGS := $(CCOMMONFLAGS)
27+
28+
LDFLAGS := $(LDFLAGS) -Os --gc-sections -z max-page-size=0x1000 \
29+
-z noexecstack -static -nostdlib

kernels1/build/process.ld

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
OUTPUT_FORMAT(elf64-x86-64)
22
OUTPUT_ARCH(i386:x86-64)
3-
ENTRY(_Z12process_mainv)
3+
ENTRY(process_main)
44

55
PHDRS {
66
text PT_LOAD;
@@ -19,17 +19,37 @@ SECTIONS {
1919
*(.text .stub .text.* .gnu.linkonce.t.*)
2020
} :text
2121
PROVIDE(etext = .); /* Define the `etext` symbol at this location */
22+
23+
/* support several signatures for `process_main` */
24+
process_main = (DEFINED(process_main) ? process_main
25+
: DEFINED(_Z12process_mainiPPc) ? _Z12process_mainiPPc
26+
: _Z12process_mainv);
27+
2228
.rodata : {
2329
*(.rodata .rodata.* .gnu.linkonce.r.*)
2430
*(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*)
2531
*(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*)
2632
} :text
2733

34+
/* Constructors: these sections support global initialization
35+
functions, such as for global C++ objects with constructors. */
36+
.init_array : {
37+
PROVIDE(__init_array_start = .);
38+
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*)
39+
SORT_BY_INIT_PRIORITY(.ctors.*)))
40+
KEEP (*(.init_array .ctors))
41+
PROVIDE(__init_array_end = .);
42+
} :text
43+
.ctors : {
44+
KEEP (*crtbegin.o(.ctors))
45+
KEEP (*(SORT(.ctors.*)))
46+
KEEP (*(.ctors))
47+
} :text
48+
2849
/* Data segment: read/write and zero-initialized globals */
2950
. = ALIGN(4096); /* Align to a page boundary */
3051
.data : {
3152
*(.data .data.* .gnu.linkonce.d.*)
32-
SORT(CONSTRUCTORS)
3353
} :data
3454
PROVIDE(edata = .);
3555
.bss : {

0 commit comments

Comments
 (0)