Skip to content

Commit 7b7bae2

Browse files
committed
Add initial project files for uROS mini operating system
- Created .gitignore to exclude build artifacts and IDE files. - Added core project files including kernel, drivers, and documentation. - Implemented basic structure for UART and timer drivers. - Established initial Makefile for building the project. - Included comprehensive documentation for usage and project overview.
0 parents  commit 7b7bae2

50 files changed

Lines changed: 9918 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
<!-- 1385f545-517d-450c-a7c8-44bb3f38e523 5ba95bfc-3710-4aa8-830e-0628fb274a0f -->
2+
# uROS RISC-V Mini-OS Implementation
3+
4+
## Architecture Overview
5+
6+
- **Platform**: QEMU virt, RISC-V 64 (rv64gc), S-mode bare metal
7+
- **Base address**: 0x80200000 (linker script)
8+
- **Boot**: OpenSBI (-bios default)
9+
- **Timer**: SBI set_timer, 100 Hz tickrate (~10ms)
10+
- **Scheduler**: RR preemptive (quantum=5 ticks) + SJF non-preemptive
11+
- **Tasks**: Kernel threads with context switching
12+
13+
## File Structure
14+
15+
```
16+
/Users/thom/Library/Mobile Documents/com~apple~CloudDocs/Universidad/OS/mini-os/
17+
├── Makefile
18+
├── linker.ld
19+
├── boot/start.S
20+
├── kernel/kmain.c
21+
├── kernel/trap.c
22+
├── kernel/task.c
23+
├── kernel/sched.c
24+
├── kernel/shell.c
25+
├── drivers/uart.c
26+
├── drivers/timer.c
27+
├── lib/printf.c
28+
├── include/uros.h
29+
├── scripts/run-qemu.sh
30+
├── scripts/demo.sh
31+
└── docs/README.md
32+
```
33+
34+
## Implementation Steps
35+
36+
### 1. Core Infrastructure & Headers
37+
38+
**File: `include/uros.h`**
39+
40+
- Define basic types (u8, u16, u32, u64, size_t)
41+
- Define `context_t` struct (x1-x31, sstatus, sepc)
42+
- Define `pcb_t` struct with: pid, state (NEW/READY/RUNNING/SLEEPING/ZOMBIE), context, stack pointer, entry function, ticks_used, burst_hint, burst_estimate, arrival_time, finish_time, wait_time
43+
- Prototypes for all subsystems: uart, timer, trap, task, sched, shell, printf
44+
- SBI call interface prototype
45+
- Constants: UART_BASE=0x10000000, TICK_HZ=100, RR_QUANTUM=5
46+
47+
### 2. Linker Script & Boot Assembly
48+
49+
**File: `linker.ld`**
50+
51+
- BASE = 0x80200000
52+
- Sections: .text, .rodata, .data, .bss
53+
- PROVIDE(_stack_top) for main kernel stack
54+
55+
**File: `boot/start.S`**
56+
57+
- Entry point: set sp to _stack_top
58+
- Jump to kmain
59+
- **ctx_switch(from, to)** implementation:
60+
- Save x1-x31, sstatus, sepc to from->context
61+
- Restore x1-x31, sstatus, sepc from to->context
62+
- Use register pairs: sd/ld with offset calculations
63+
- Handle sp specially (x2)
64+
65+
### 3. UART Driver (NS16550A)
66+
67+
**File: `drivers/uart.c`**
68+
69+
- MMIO base 0x10000000
70+
- Registers: THR (0), RBR (0), LSR (5), IER (1), LCR (3)
71+
- `uart_init()`: configure 8N1, disable interrupts
72+
- `uart_putc(char c)`: wait for THRE bit in LSR, write to THR
73+
- `uart_getc()`: poll RBR with timeout
74+
- `uart_puts(const char *s)`: loop uart_putc
75+
- Input buffering with echo and backspace support
76+
77+
### 4. Printf Implementation
78+
79+
**File: `lib/printf.c`**
80+
81+
- `kprintf(const char *fmt, ...)` with va_args
82+
- Support: %s, %d, %u, %x, %c
83+
- Use uart_putc for output
84+
- Simple number-to-string conversion helpers
85+
86+
### 5. Timer Driver (SBI)
87+
88+
**File: `drivers/timer.c`**
89+
90+
- `sbi_call(eid, fid, a0-a5)`: inline assembly for ecall
91+
- `sbi_set_timer(u64 stime_value)`: EID=0, FID=0
92+
- `rdtime()`: read CSR time with inline asm
93+
- `timer_init(hz)`: calculate tick_delta = TIMEBASE_FREQ / hz (assume 10MHz)
94+
- `timer_schedule_next()`: rdtime() + tick_delta, call sbi_set_timer
95+
- Global g_ticks counter
96+
97+
### 6. Trap Handling
98+
99+
**File: `kernel/trap.c`**
100+
101+
- `trap_init()`:
102+
- Set stvec to trap_handler address (direct mode)
103+
- Enable SIE bit in sstatus: `sstatus |= (1 << 1)`
104+
- Enable STIE bit in sie: `sie |= (1 << 5)`
105+
- `trap_handler()`: read scause
106+
- If supervisor timer interrupt (bit 63 set, code 5):
107+
- Call timer_schedule_next()
108+
- Increment g_ticks
109+
- Call sched_on_tick()
110+
- Handle other traps (print and halt)
111+
112+
### 7. Task Management
113+
114+
**File: `kernel/task.c`**
115+
116+
- Bump allocator: static heap array, `kmalloc(size)` advances pointer
117+
- Task table: MAX_TASKS=32, array of pcb_t
118+
- `task_create(void (*entry)(void*), void *arg, int burst_hint)`:
119+
- Allocate PID, stack (4KB per task)
120+
- Initialize context: set sepc to entry, sp to stack_top
121+
- Set burst_hint and burst_estimate
122+
- Set arrival_time = g_ticks
123+
- State = NEW → READY, add to scheduler
124+
- `task_exit()`: mark ZOMBIE, yield
125+
- `yield()`: call sched_yield() which does ctx_switch
126+
- `task_get_by_pid(pid)`: lookup helper
127+
- Track memory usage for meminfo
128+
129+
### 8. Scheduler (RR + SJF)
130+
131+
**File: `kernel/sched.c`**
132+
133+
- Mode enum: SCHED_RR, SCHED_SJF
134+
- Global: current_mode, current_task, ready_queue
135+
- **Round-Robin (preemptive)**:
136+
- `sched_on_tick()`: if mode==RR, decrement quantum; if 0, yield
137+
- `sched_pick_next()`: FIFO from ready_queue
138+
- **SJF (non-preemptive)**:
139+
- `sched_pick_next()`: sort/find task with min burst_estimate
140+
- Tie-break: arrival_time (FCFS) or PID
141+
- Update estimate after task completes: τ_new = 0.5 * real + 0.5 * τ_old
142+
- `sched_set_mode(mode)`: switch between RR/SJF
143+
- `sched_yield()`: ctx_switch to next task
144+
- Track wait_time, finish_time for metrics
145+
146+
### 9. Shell & Commands
147+
148+
**File: `kernel/shell.c`**
149+
150+
- `shell_run()`: infinite loop reading lines from UART
151+
- Parse command and dispatch:
152+
- **help**: list all commands
153+
- **ps**: print PID, state, ticks_used, burst_estimate for all tasks
154+
- **run cpu**: create CPU-bound task (loop with occasional yield)
155+
- **run io**: create I/O task (sleep 5 ticks between prints)
156+
- **kill \<pid\>**: mark task as ZOMBIE
157+
- **sched rr|sjf**: call sched_set_mode()
158+
- **bench**: run benchmark (see below)
159+
- **uptime**: print g_ticks / 100.0 seconds
160+
- **meminfo**: print bump allocator usage, stack memory
161+
162+
**Benchmark implementation**:
163+
164+
- Create 6-10 tasks with known burst_hints (e.g., 10, 20, 15, 30, 25, 12 ticks)
165+
- **Round 1 (RR)**:
166+
- Set mode to RR
167+
- Create tasks, wait until all ZOMBIE
168+
- Collect: wait_time, turnaround (finish - arrival), total duration
169+
- **Round 2 (SJF)**:
170+
- Reset task table
171+
- Set mode to SJF
172+
- Create same tasks (reset arrival times)
173+
- Wait until all ZOMBIE
174+
- Collect same metrics
175+
- Print comparison table:
176+
```
177+
Benchmark Results:
178+
RR SJF
179+
Wait: X.XX Y.YY ticks
180+
T.around: X.XX Y.YY ticks
181+
T.put: X.XX Y.YY tasks/sec
182+
```
183+
184+
185+
### 10. Kernel Main
186+
187+
**File: `kernel/kmain.c`**
188+
189+
- Call uart_init()
190+
- Call trap_init()
191+
- Call timer_init(100)
192+
- Call sched_init()
193+
- Print banner: "uROS (rv64gc, QEMU virt) - console ready\nticks=0\n"
194+
- Create 1-2 demo tasks (optional)
195+
- Call shell_run() (never returns)
196+
197+
### 11. Build System
198+
199+
**File: `Makefile`**
200+
201+
- Toolchain: CROSS=riscv64-unknown-elf-
202+
- CFLAGS: -march=rv64gc -mabi=lp64 -ffreestanding -nostdlib -nostartfiles -Wall -Wextra -O2 -I include
203+
- LDFLAGS: -T linker.ld -nostdlib
204+
- Targets:
205+
- **all**: compile all .c and .S files, link to build/kernel.elf, generate kernel.map
206+
- **run**: execute scripts/run-qemu.sh
207+
- **clean**: rm -rf build/
208+
- **dtb**: dump QEMU DTB and convert to DTS with dtc
209+
210+
**File: `scripts/run-qemu.sh`**
211+
212+
```bash
213+
#!/bin/bash
214+
qemu-system-riscv64 -machine virt -nographic -bios default -kernel build/kernel.elf
215+
```
216+
217+
**File: `scripts/demo.sh`**
218+
219+
```bash
220+
#!/bin/bash
221+
(sleep 1; echo "help"; sleep 1; echo "ps"; sleep 1;
222+
echo "run cpu"; sleep 1; echo "run io"; sleep 1;
223+
echo "sched rr"; sleep 1; echo "bench") | ./scripts/run-qemu.sh
224+
```
225+
226+
### 12. Documentation
227+
228+
**File: `docs/README.md`**
229+
230+
- Requirements: QEMU, riscv64-unknown-elf toolchain
231+
- Build steps: make, make run
232+
- Shell commands reference
233+
- RR vs SJF explanation with metrics definitions
234+
- Example output log
235+
236+
## Definition of Done
237+
238+
- `make run` boots to "uROS ready" banner
239+
- Interactive prompt "uROS> " accepts commands
240+
- `help` lists all commands
241+
- `run cpu` and `run io` create visible tasks
242+
- `ps` shows task states and metrics
243+
- `sched rr` and `sched sjf` switch modes
244+
- `bench` prints comparison table with wait, turnaround, throughput
245+
- `uptime` and `meminfo` work correctly
246+
- Tasks preempt visibly under RR
247+
- Context switch preserves registers correctly
248+
249+
### To-dos
250+
251+
- [ ] Create include/uros.h with types, structs (context_t, pcb_t), and all function prototypes
252+
- [ ] Implement linker.ld with BASE=0x80200000, sections, and stack
253+
- [ ] Implement boot/start.S with entry point and ctx_switch assembly routine
254+
- [ ] Implement drivers/uart.c for NS16550A at 0x10000000
255+
- [ ] Implement lib/printf.c with kprintf supporting %s %d %u %x
256+
- [ ] Implement drivers/timer.c with SBI calls and 100Hz tick scheduling
257+
- [ ] Implement kernel/trap.c with stvec setup, SIE/STIE enable, and timer interrupt handler
258+
- [ ] Implement kernel/task.c with bump allocator, task_create, yield, exit
259+
- [ ] Implement kernel/sched.c with RR preemptive and SJF non-preemptive modes
260+
- [ ] Implement kernel/shell.c with all commands including bench with RR vs SJF comparison
261+
- [ ] Implement kernel/kmain.c with initialization sequence and banner
262+
- [ ] Create Makefile with all/run/clean/dtb targets
263+
- [ ] Create scripts/run-qemu.sh and scripts/demo.sh
264+
- [ ] Create docs/README.md with requirements, usage, and explanation

.github/workflows/build.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: build
2+
on: [push, pull_request]
3+
4+
jobs:
5+
build:
6+
runs-on: ubuntu-latest
7+
8+
steps:
9+
- name: Checkout code
10+
uses: actions/checkout@v4
11+
12+
- name: Install dependencies
13+
run: |
14+
sudo apt-get update
15+
sudo apt-get install -y make gcc-riscv64-unknown-elf qemu-system-misc device-tree-compiler
16+
17+
- name: Build kernel
18+
run: make
19+
20+
- name: Check kernel.elf exists
21+
run: |
22+
if [ ! -f build/kernel.elf ]; then
23+
echo "Error: kernel.elf not generated"
24+
exit 1
25+
fi
26+
echo "✅ Build successful!"
27+

.gitignore

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
build/
2+
*.o
3+
*.map
4+
*.asm
5+
virt.dtb
6+
virt.dts
7+
.DS_Store
8+
.vscode/
9+
.idea/
10+
.venv/
11+
build/
12+
*.o
13+
*.map
14+
*.asm
15+
virt.dtb
16+
virt.dts
17+
.DS_Store
18+
*.swp
19+
*~
20+
.vscode/
21+
.idea/
22+
.venv/

0 commit comments

Comments
 (0)