Skip to content

Commit f5e7f43

Browse files
committed
update
1 parent 4714034 commit f5e7f43

114 files changed

Lines changed: 15012 additions & 72 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
6+
7+
SESSION_ORDER=(
8+
session02_stage0
9+
session03_protected_mode
10+
session04_memory
11+
session05_drivers
12+
session06_bios_video
13+
session07_libc
14+
session08_shell
15+
session09_graphics
16+
session10_fat
17+
session11_elf
18+
)
19+
20+
usage() {
21+
echo "usage: $0 [--start|--solution] <session02|session03|...|session11> <output-dir>"
22+
}
23+
24+
SELECTED_VARIANT="start"
25+
26+
case "${1-}" in
27+
--start)
28+
shift
29+
;;
30+
--solution|--solved)
31+
SELECTED_VARIANT="solution"
32+
shift
33+
;;
34+
esac
35+
36+
if [ "$#" -ne 2 ]; then
37+
usage
38+
exit 1
39+
fi
40+
41+
SESSION_SHORT="$1"
42+
TARGET_DIR="$2"
43+
44+
case "$SESSION_SHORT" in
45+
session02) SELECTED_SESSION="session02_stage0" ;;
46+
session03) SELECTED_SESSION="session03_protected_mode" ;;
47+
session04) SELECTED_SESSION="session04_memory" ;;
48+
session05) SELECTED_SESSION="session05_drivers" ;;
49+
session06) SELECTED_SESSION="session06_bios_video" ;;
50+
session07) SELECTED_SESSION="session07_libc" ;;
51+
session08) SELECTED_SESSION="session08_shell" ;;
52+
session09) SELECTED_SESSION="session09_graphics" ;;
53+
session10) SELECTED_SESSION="session10_fat" ;;
54+
session11) SELECTED_SESSION="session11_elf" ;;
55+
*)
56+
usage
57+
exit 1
58+
;;
59+
esac
60+
61+
if [ -e "$TARGET_DIR" ] && [ -n "$(find "$TARGET_DIR" -mindepth 1 -maxdepth 1 2>/dev/null)" ]; then
62+
echo "$0: output directory must be empty or not exist: $TARGET_DIR" >&2
63+
exit 1
64+
fi
65+
66+
mkdir -p "$TARGET_DIR"
67+
68+
if ! command -v rsync >/dev/null 2>&1; then
69+
echo "$0: rsync is required" >&2
70+
exit 1
71+
fi
72+
73+
copy_root_file() {
74+
local src_rel="$1"
75+
local src="$ROOT_DIR/$src_rel"
76+
local dest="$TARGET_DIR/$src_rel"
77+
78+
mkdir -p "$(dirname "$dest")"
79+
80+
if [ -d "$src" ]; then
81+
rsync -a "$src/" "$dest/"
82+
else
83+
cp -p "$src" "$dest"
84+
fi
85+
}
86+
87+
copy_repo_snapshot() {
88+
rsync -a \
89+
--exclude '.git' \
90+
--exclude 'build' \
91+
--exclude '.cache' \
92+
--exclude 'disk.img' \
93+
--exclude 'study' \
94+
"$ROOT_DIR/" \
95+
"$TARGET_DIR/"
96+
}
97+
98+
session_has_filelist() {
99+
[ -f "$ROOT_DIR/study/$1/FILES.lst" ]
100+
}
101+
102+
can_materialize_minimal_packet() {
103+
local session_dir
104+
105+
for session_dir in "${SESSION_ORDER[@]}"; do
106+
if ! session_has_filelist "$session_dir"; then
107+
return 1
108+
fi
109+
110+
if [ "$session_dir" = "$SELECTED_SESSION" ]; then
111+
return 0
112+
fi
113+
done
114+
115+
return 1
116+
}
117+
118+
copy_vendor_dep() {
119+
local src_dir="$1"
120+
local dest_dir="$2"
121+
122+
if [ -d "$src_dir" ]; then
123+
mkdir -p "$(dirname "$dest_dir")"
124+
rsync -a "$src_dir/" "$dest_dir/"
125+
fi
126+
}
127+
128+
copy_session_vendor_deps() {
129+
if [ "$SELECTED_SESSION" = "session11_elf" ]; then
130+
copy_vendor_dep "$ROOT_DIR/build/vellum/_deps/zlib-src" "$TARGET_DIR/third_party-src/zlib"
131+
copy_vendor_dep "$ROOT_DIR/build/vellum/_deps/uacpi-src" "$TARGET_DIR/third_party-src/uacpi"
132+
fi
133+
}
134+
135+
copy_manifest_file() {
136+
local session_dir="$1"
137+
local src_rel="$2"
138+
local dest_rel="$3"
139+
local src="$ROOT_DIR/study/$session_dir/$src_rel"
140+
local dest="$TARGET_DIR/$dest_rel"
141+
142+
mkdir -p "$(dirname "$dest")"
143+
cp -p "$src" "$dest"
144+
}
145+
146+
manifest_for_session() {
147+
local session_dir="$1"
148+
local selected="$2"
149+
150+
if [ "$session_dir" = "$selected" ] &&
151+
[ "$SELECTED_VARIANT" = "start" ] &&
152+
[ -f "$ROOT_DIR/study/$session_dir/START_MANIFEST.tsv" ]; then
153+
printf '%s' "$ROOT_DIR/study/$session_dir/START_MANIFEST.tsv"
154+
else
155+
printf '%s' "$ROOT_DIR/study/$session_dir/MANIFEST.tsv"
156+
fi
157+
}
158+
159+
apply_stage_files() {
160+
local session_dir manifest src_rel dest_rel
161+
162+
for session_dir in "${SESSION_ORDER[@]}"; do
163+
manifest="$(manifest_for_session "$session_dir" "$SELECTED_SESSION")"
164+
165+
while IFS=$'\t' read -r src_rel dest_rel; do
166+
[ -n "$src_rel" ] || continue
167+
copy_manifest_file "$session_dir" "$src_rel" "$dest_rel"
168+
done <"$manifest"
169+
170+
if [ "$session_dir" = "$SELECTED_SESSION" ]; then
171+
break
172+
fi
173+
done
174+
}
175+
176+
copy_allowlisted_files() {
177+
local session_dir file_rel
178+
179+
for session_dir in "${SESSION_ORDER[@]}"; do
180+
while IFS= read -r file_rel; do
181+
[ -n "$file_rel" ] || continue
182+
183+
case "$file_rel" in
184+
\#*) continue ;;
185+
esac
186+
187+
copy_root_file "$file_rel"
188+
done <"$ROOT_DIR/study/$session_dir/FILES.lst"
189+
190+
if [ "$session_dir" = "$SELECTED_SESSION" ]; then
191+
break
192+
fi
193+
done
194+
}
195+
196+
apply_future_overlays() {
197+
local overlay_now=0
198+
local session_dir manifest src_rel dest_rel
199+
200+
for session_dir in "${SESSION_ORDER[@]}"; do
201+
if [ "$session_dir" = "$SELECTED_SESSION" ]; then
202+
overlay_now=1
203+
fi
204+
205+
if [ "$overlay_now" -eq 0 ]; then
206+
continue
207+
fi
208+
209+
manifest="$ROOT_DIR/study/$session_dir/MANIFEST.tsv"
210+
211+
while IFS=$'\t' read -r src_rel dest_rel; do
212+
[ -n "$src_rel" ] || continue
213+
copy_manifest_file "$session_dir" "$src_rel" "$dest_rel"
214+
done <"$manifest"
215+
done
216+
}
217+
218+
remove_unused_student_files() {
219+
rm -f "$TARGET_DIR/vellum/arch/ia32/pc/bios/instruction.c"
220+
rm -f "$TARGET_DIR/vellum/arch/ia32/pc/bios/include/vellum/plat/instruction.h"
221+
}
222+
223+
if can_materialize_minimal_packet; then
224+
copy_allowlisted_files
225+
apply_stage_files
226+
copy_session_vendor_deps
227+
else
228+
copy_repo_snapshot
229+
copy_vendor_dep "$ROOT_DIR/build/vellum/_deps/zlib-src" "$TARGET_DIR/third_party-src/zlib"
230+
copy_vendor_dep "$ROOT_DIR/build/vellum/_deps/uacpi-src" "$TARGET_DIR/third_party-src/uacpi"
231+
apply_future_overlays
232+
fi
233+
234+
remove_unused_student_files
235+
236+
echo "Created buildable student checkout $SESSION_SHORT ($SELECTED_VARIANT) in $TARGET_DIR"

study/README.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# SSCC OS Study Track
2+
3+
This directory stores the student-facing overlays for each study session.
4+
5+
The important change is that these files are now meant to be applied
6+
incrementally, not read side-by-side with the full reference tree. Each
7+
`sessionXX_*` folder only contains the new source files opened in that session.
8+
9+
To build a cumulative student packet:
10+
11+
1. Pick the target session.
12+
2. Run `scripts/materialize_student_stage.sh <session> <output-dir>` for the starter packet, or
13+
`scripts/materialize_student_stage.sh --solution <session> <output-dir>` for the filled-in one.
14+
3. The script copies only the files allowed for that stage and overlays the
15+
session files up to that point.
16+
4. `session02` through `session11` now use the strict minimal packet mode.
17+
5. When a session has `START_MANIFEST.tsv`, the selected stage gets that
18+
starter overlay, while earlier sessions still apply their solved
19+
`MANIFEST.tsv` overlays.
20+
21+
Example:
22+
23+
```sh
24+
scripts/materialize_student_stage.sh session04 ../pack-session04
25+
scripts/materialize_student_stage.sh --solution session04 ../pack-session04-solved
26+
```
27+
28+
Recommended branch flow:
29+
30+
- `codex/session02-start`
31+
- `codex/session02-solution`
32+
- `codex/session03-start`
33+
- `codex/session03-solution`
34+
- ...
35+
36+
Session mapping:
37+
38+
- `session01_ot`
39+
No code overlay. Environment and architecture walkthrough only.
40+
- `session02_stage0`
41+
Stage0 boot path and a temporary stage1 assembly hello-world.
42+
- `session03_protected_mode`
43+
Real-mode startup, GDT setup, and the C-based stage1 FAT loader.
44+
- `session04_memory`
45+
Physical memory allocator and early paging.
46+
- `session05_drivers`
47+
Device registry and minimal ISA UART driver.
48+
- `session06_bios_video`
49+
BIOS video wrappers and mode selection command.
50+
- `session07_libc`
51+
Minimal freestanding libc functions plus `vcprintf`.
52+
- `session08_shell`
53+
Line input, variable expansion, parsing, and dispatch.
54+
- `session09_graphics`
55+
Framebuffer console and a tiny ANSI subset.
56+
- `session10_fat`
57+
Read-only FAT subset.
58+
- `session11_elf`
59+
ELF loading subset.
60+
- `session12_showcase`
61+
Demo and compare against the reference implementation.
62+
63+
Notes:
64+
65+
- The reference implementation under `vellum/` stays untouched for instructor use.
66+
- The materialized student packet is the one students should see.
67+
- Each later session now replaces the boot-stage `init.c` and BIOS-side
68+
`CMakeLists.txt` so the emitted artifact matches that week's topic.
69+
- `session06` keeps BIOS video calls in `stage1`, because the 16-bit BIOS thunk
70+
is only safe there once the later kernels grow larger.
71+
- Each session can also widen the copied file set through `FILES.lst`, so the
72+
student checkout gradually grows toward the real repository layout.
73+
- This makes `session09` look like “session08 solved + session09 starter”, which
74+
is the intended cumulative teaching flow.
75+
- The same starter/solution split now exists from `session04` onward, so the
76+
selected stage exposes allocator/UART/BIOS-video/libc TODOs while later
77+
sessions automatically carry their solved versions forward.

study/session01_ot/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Session 01: OT and Environment Setup
2+
3+
There is no fill-in-the-blank source file for this session.
4+
5+
Suggested use of the live repository:
6+
7+
- Explain the overall directory layout.
8+
- Walk through `scripts/run.sh`, `scripts/gdb.sh`, and `scripts/mkdisk.sh`.
9+
- Show how BIOS boot, stage loading, and the kernel entry connect at a high level.
10+
- Confirm that everyone can build, run, and attach GDB before session 02.

study/session02_stage0/FILES.lst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
cmake/ia32/Toolchain.cmake
2+
vellum/arch/ia32/pc/bios/fdboot.S
3+
vellum/arch/ia32/pc/bios/ldscript_stage1.lds
4+
vellum/arch/ia32/pc/bios/ldscript_vbr.lds
5+
vellum/arch/ia32/pc/bios/mbrboot.S
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
root_CMakeLists.txt CMakeLists.txt
2+
vellum_CMakeLists.txt vellum/CMakeLists.txt
3+
bios_CMakeLists.txt vellum/arch/ia32/pc/bios/CMakeLists.txt
4+
mkdisk.sh scripts/mkdisk.sh
5+
stage1.S vellum/arch/ia32/pc/bios/stage1.S
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
cmake_minimum_required(VERSION 3.13)
2+
3+
function(add_boot_binary target_name source_name linker_script output_name)
4+
add_executable(${target_name})
5+
set_target_properties(${target_name} PROPERTIES SUFFIX ".elf")
6+
target_compile_options(${target_name} PUBLIC
7+
$<$<COMPILE_LANGUAGE:C,ASM>:
8+
-Werror
9+
-Wall
10+
-Wno-unused-function
11+
-pedantic
12+
-pedantic-errors
13+
>
14+
)
15+
target_sources(${target_name} PRIVATE ${source_name})
16+
target_link_options(${target_name} PUBLIC -T "${CMAKE_CURRENT_SOURCE_DIR}/${linker_script}")
17+
set_target_properties(${target_name} PROPERTIES LINK_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${linker_script}")
18+
19+
if ("${target_name}" STREQUAL "stage1")
20+
target_link_libraries(${target_name} gcc)
21+
endif()
22+
23+
add_custom_target(${target_name}_execbin ALL
24+
COMMAND ${CMAKE_OBJCOPY} -O binary "$<TARGET_FILE:${target_name}>" "${output_name}"
25+
DEPENDS ${target_name}
26+
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
27+
COMMENT "Creating ${target_name} binary"
28+
)
29+
endfunction()
30+
31+
add_boot_binary(fdboot fdboot.S ldscript_vbr.lds fdboot.bin)
32+
add_boot_binary(mbrboot mbrboot.S ldscript_vbr.lds mbrboot.bin)
33+
add_boot_binary(stage1 stage1.S ldscript_stage1.lds stage1.bin)

0 commit comments

Comments
 (0)