Skip to content

appleweiping/hit-os

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

hit-os — HIT《操作系统》hit-oslab labs on Linux 0.11

Real kernel modifications to a modified Linux 0.11 running under Bochs — an independent, from-skeleton implementation of the laboratory assignments of 哈尔滨工业大学《操作系统》(Harbin Institute of Technology "Operating Systems", 李治军), the classic hit-oslab course, part of a csdiy.wiki full-catalog build.

status language kernel license

Overview

Each experiment is a genuine modification of the Linux 0.11 kernel (boot loader, system calls, scheduler, memory manager, char drivers, filesystem) — not a simulation. Every experiment is built with the period toolchain (gcc-3.4, as86/ld86), booted in Bochs, and its effect is captured as real evidence (screenshots and extracted files) under results/.

Because WSL2's kernel has no MINIX filesystem support, a small userspace tools/mfs.py reads and writes the MINIX-v1 disk image directly, so test programs, /etc/rc and generated output are injected and extracted fully headlessly.

Results (measured — Bochs 2.7 under Xvfb, WSL2 Ubuntu on a Windows CPU-only host)

# Experiment What it does Status / evidence
1 操作系统的引导 (bootloader) custom banners in bootsect.s + setup.s, still boots to a shell results/01.png, 01_shell.png
2 系统调用 (system calls) new iam() / whoami() syscalls whoami reads back name set by another process; 36-char name → EINVAL (results/02*)
3 进程运行轨迹跟踪与统计 (process trace) scheduler logs N/J/R/W/E to /var/process.log ✅ 267 events, CPU-bound child 400 jiffies running/0 blocked, IO-bound 0/424; timeline figure
4 基于内核栈切换的进程切换 (kernel-stack switch) replace TSS task-switch with kernel-stack switch_to ⚠️ documented partial — see below
5 信号量的实现与应用 (semaphores) sem_open/wait/post/unlink + producer/consumer ✅ 20 items, each produced & consumed exactly once (results/05*)
6 地址映射与共享 (shared memory) shmget/shmat/shmdt, one page mapped into two processes ✅ parent reads the string the child wrote to shared memory (results/06*)
7 终端设备的控制 (terminal control) custom ESC[nz uppercase-toggle in the console driver ✅ line renders uppercase after ESC[1z (results/07.png)
8 proc 文件系统 (/proc pseudo fs) char-device /proc/psinfo & /proc/meminfo cat shows live process table + uptime/free-mem (results/08*)

Process-state timeline (Experiment 3)

process timeline

Green = running, amber = ready, red = blocked. pid 0 (the idle task) fills every gap; pid 10 is the CPU-bound child, pid 11 the IO-bound child.

Implemented experiments

  • 1 — bootloader (experiments/01-bootloader)
  • 2 — system calls (experiments/02-syscall)
  • 3 — process trace (experiments/03-process-trace)
  • 4 — kernel-stack switch (experiments/04-kernel-stack-switch) — documented partial
  • 5 — semaphores (experiments/05-semaphore)
  • 6 — shared memory (experiments/06-shm)
  • 7 — terminal control (experiments/07-terminal)
  • 8 — /proc filesystem (experiments/08-procfs)

Each experiment directory has its own README.md, an overlay/ of the exact modified kernel source files, any user/ test programs, the /etc/rc used to drive it, and an outputs manifest of files extracted from the disk image.

Project structure

hit-os/
├── linux-0.11/            # pristine hit-oslab Linux 0.11 base (GPLv2)
├── experiments/NN-name/   # per-lab overlay + user programs + rc + README
├── scripts/               # setup / build / run (Bochs-under-Xvfb capture)
├── tools/mfs.py           # userspace MINIX-v1 fs reader/writer
├── results/               # captured screenshots, logs, timeline figure
├── LICENSE  NOTICE

How to run

Everything runs in WSL2 Ubuntu (Linux-only kernel work).

# one-time: toolchain (gcc-multilib, bin86, bochs, bochs-x, xvfb, imagemagick)
# + the oslab-provided gcc-3.4, and the hit-oslab package at $OSLAB
scripts/setup.sh

# build + boot + capture one experiment (id, wait-seconds):
scripts/run.sh 01 5      # bootloader banners
scripts/run.sh 03 160    # process trace  (then plot the figure:)
python experiments/03-process-trace/stat_log.py \
       results/03__var_process.log results/03_process_timeline.png
scripts/run.sh 08 22     # /proc pseudo filesystem

scripts/build.sh NN reconstructs experiment NN's kernel = the committed linux-0.11/ base + experiments/NN/overlay/, and builds it with the period toolchain. scripts/run.sh NN also injects the experiment's user programs and /etc/rc into a fresh copy of the disk image, boots it headlessly in Bochs (under Xvfb), screenshots the VGA console, and extracts the declared outputs.

Verification

QEMU cannot drive Linux 0.11's ancient hd.c (it panics with "harddisk I/O error / Unable to mount root"), so all booting uses Bochs. Ubuntu's bochs is a debugger build, so the harness feeds it a continue command and captures the X framebuffer under Xvfb with ImageMagick. Every ✅ row above was produced by an actual boot; the screenshots and extracted files under results/ are those runs.

Documented partial — Experiment 4 (kernel-stack switch)

Experiment 4 replaces Linux 0.11's TSS-based hardware task switch (switch_to is just an ljmp through a task's TSS descriptor) with a kernel-stack switch: switch_to becomes a routine that saves callee-saved registers on the current kernel stack, swaps ESP to the next task's kernel stack, and returns into it; schedule() calls it with the next PCB; and copy_process() must hand-craft the new task's kernel stack so the very first switch "returns" cleanly into user mode. experiments/04-kernel-stack-switch/ contains the design and the specific edits. It is shipped as a documented partial: rewriting the context-switch mechanism is the single most invasive change in the course and any of its several interlocking pieces being subtly wrong faults the kernel on the first switch; it is not fully brought up here. The other seven experiments span the full range of kernel subsystems and are all verified end-to-end.

Tech stack

Linux 0.11 (C + x86 real-mode/protected-mode assembly), gcc-3.4 / as86 / ld86, Bochs 2.7 + Xvfb + ImageMagick for headless boot capture, Python 3 (tools/mfs.py MINIX-v1 fs tool; matplotlib for the timeline figure), WSL2.

Key ideas / what I learned

  • The x86 boot sequence: bootsectsetup → protected mode → the kernel.
  • Adding system calls end-to-end: sys_call_table, int 0x80, and moving data across the user/kernel boundary with get_fs_byte/put_fs_byte.
  • Instrumenting the scheduler and the danger of re-entrancy (logging from inside schedule() overflows the 4 KB kernel stack without a guard).
  • Two ways to build a semaphore on Linux 0.11's primitives, and why sleep_on/ wake_up are fragile when waiters exit.
  • Address mapping: sharing one physical page between processes with put_page.
  • Extending a VT102 console and building a /proc-style pseudo file as a char device when there is no VFS to hang a filesystem on.

Credits & license

Based on the laboratory assignments of 哈尔滨工业大学《操作系统》(HIT "Operating Systems", 李治军) and the hit-oslab environment (modified Linux 0.11, root filesystem by Zhao Jiong / oldlinux.org). This repository is an independent educational reimplementation; all course materials belong to their original authors. See NOTICE: the kernel and its lab modifications are GPLv2 (derivative of Linux 0.11, © Linus Torvalds); the original tooling, test programs, scripts and docs are MIT (LICENSE).

About

HIT 哈工大《操作系统》(李治军) hit-oslab labs: real Linux 0.11 kernel modifications (bootloader, syscalls, scheduler trace, semaphores, shared memory, terminal, /proc) verified under Bochs. A csdiy.wiki build.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors