Skip to content

Commit 8f3d130

Browse files
authored
Merge pull request #96 from ryanbreen/feature/pty-support
feat(pty): implement POSIX pseudo-terminal support
2 parents d0f80e3 + b111fe6 commit 8f3d130

File tree

30 files changed

+3525
-10
lines changed

30 files changed

+3525
-10
lines changed

docs/planning/INIT_SYSTEM_PLAN.md

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
# Init System & Virtual Consoles Implementation Plan
2+
3+
## Overview
4+
5+
Replace `init_shell` as PID 1 with a proper init system that:
6+
1. Manages system services (telnetd, etc.)
7+
2. Supports multiple interaction modes (console, telnet, serial)
8+
3. Spawns shells on virtual consoles like Linux
9+
4. Handles process supervision and cleanup
10+
11+
## Current State
12+
13+
- `init_shell` runs as PID 1 (interactive mode)
14+
- No service management
15+
- No virtual console support
16+
- telnetd exists but has test limits and must be manually started
17+
18+
## Architecture
19+
20+
### Init Process Responsibilities
21+
22+
```
23+
/sbin/init (PID 1)
24+
├── Parse /etc/inittab or built-in config
25+
├── Mount filesystems (future)
26+
├── Start services
27+
│ ├── telnetd on port 2323
28+
│ └── (future: sshd, httpd, etc.)
29+
├── Spawn getty on virtual consoles
30+
│ ├── /dev/tty1 → getty → login → shell
31+
│ ├── /dev/tty2 → getty → login → shell
32+
│ └── /dev/ttyS0 → getty (serial console)
33+
├── Reap orphaned processes (wait for zombies)
34+
└── Handle shutdown signals
35+
```
36+
37+
### Virtual Console Model (Linux-style)
38+
39+
```
40+
/dev/console - System console (kernel messages)
41+
/dev/tty0 - Current virtual console
42+
/dev/tty1-6 - Virtual text consoles (Alt+F1 through Alt+F6)
43+
/dev/ttyS0 - Serial console (QEMU -serial stdio)
44+
/dev/pts/* - Pseudo-terminals (telnet, ssh, screen)
45+
```
46+
47+
## Implementation Phases
48+
49+
### Phase 1: Basic Init Structure
50+
51+
**Goal:** Create init binary that starts services and shells
52+
53+
**Files:**
54+
- `userspace/tests/init.rs` - Main init process
55+
- `kernel/src/main.rs` - Load init instead of init_shell
56+
57+
**Behavior:**
58+
```rust
59+
// init.rs pseudocode
60+
fn main() {
61+
// We are PID 1
62+
println!("Breenix init starting...");
63+
64+
// Start telnetd in background
65+
if fork() == 0 {
66+
exec("/bin/telnetd");
67+
}
68+
69+
// Start shell on console
70+
if fork() == 0 {
71+
exec("/bin/init_shell");
72+
}
73+
74+
// Reap zombies forever
75+
loop {
76+
waitpid(-1, WNOHANG);
77+
yield();
78+
}
79+
}
80+
```
81+
82+
### Phase 2: Virtual Console Infrastructure
83+
84+
**Goal:** Implement /dev/ttyN virtual consoles
85+
86+
**Kernel Changes:**
87+
- `kernel/src/tty/vt.rs` - Virtual terminal multiplexer
88+
- `kernel/src/tty/console.rs` - Console output routing
89+
- Support Alt+Fn switching between consoles
90+
91+
**Each VT has:**
92+
- Input buffer (keyboard → VT)
93+
- Output buffer (VT → screen)
94+
- Foreground process group
95+
- Termios settings
96+
97+
### Phase 3: Getty/Login
98+
99+
**Goal:** Proper login flow on consoles
100+
101+
**Files:**
102+
- `userspace/tests/getty.rs` - Open TTY, prompt for login
103+
- `userspace/tests/login.rs` - Authenticate and exec shell (future)
104+
105+
**Flow:**
106+
```
107+
init spawns: getty /dev/tty1
108+
getty: opens /dev/tty1, sets termios, prints "login: "
109+
getty: reads username, execs login
110+
login: (future: authenticate), execs shell
111+
shell: runs as user session
112+
```
113+
114+
For now (single-user): getty → shell directly
115+
116+
### Phase 4: Service Management
117+
118+
**Goal:** Structured service start/stop
119+
120+
**Config format (simple):**
121+
```
122+
# /etc/inittab or built-in
123+
::sysinit:/bin/mount -a
124+
::respawn:/sbin/getty /dev/tty1
125+
::respawn:/sbin/getty /dev/tty2
126+
::once:/sbin/telnetd
127+
```
128+
129+
**Respawn logic:**
130+
- If service exits, restart it
131+
- Rate-limit restarts (don't spin)
132+
133+
### Phase 5: Serial Console Support
134+
135+
**Goal:** Shell accessible via QEMU serial
136+
137+
**Current:** Kernel output goes to serial
138+
**Needed:** Bidirectional serial I/O for shell
139+
140+
**Approach:**
141+
- `/dev/ttyS0` backed by UART 0x3F8
142+
- getty spawns on ttyS0
143+
- Serial becomes interactive shell
144+
145+
## File Structure
146+
147+
```
148+
userspace/tests/
149+
├── init.rs # PID 1 init process
150+
├── getty.rs # TTY login prompt
151+
├── init_shell.rs # Interactive shell (unchanged)
152+
└── telnetd.rs # Telnet server (remove test limits)
153+
154+
kernel/src/tty/
155+
├── mod.rs # TTY subsystem
156+
├── pty/ # Pseudo-terminals (done)
157+
├── vt.rs # Virtual terminal multiplexer (new)
158+
└── console.rs # Console driver (new)
159+
```
160+
161+
## Migration Path
162+
163+
### Step 1: Create init binary
164+
- Copy minimal logic from init_shell
165+
- Fork telnetd and shell
166+
- Reap zombies
167+
168+
### Step 2: Update kernel to load init
169+
- Change `kernel_main_continue()` to load `/sbin/init`
170+
- Keep init_shell as fallback
171+
172+
### Step 3: Fix telnetd
173+
- Remove MAX_ATTEMPTS/MAX_CYCLES limits
174+
- Run as proper daemon
175+
176+
### Step 4: Add virtual consoles
177+
- Implement /dev/tty1-6
178+
- Add console switching
179+
180+
### Step 5: Add getty
181+
- Simple program: open tty, print prompt, exec shell
182+
183+
## Success Criteria
184+
185+
1. **Boot sequence:**
186+
```
187+
Kernel starts
188+
init (PID 1) starts
189+
telnetd starts (PID 2)
190+
getty/shell starts on console (PID 3)
191+
```
192+
193+
2. **Telnet works:**
194+
```bash
195+
# From host
196+
telnet localhost 2323
197+
# Get shell prompt
198+
breenix>
199+
```
200+
201+
3. **Process tree:**
202+
```
203+
PID 1: init
204+
├── PID 2: telnetd
205+
│ └── PID N: init_shell (per connection)
206+
└── PID 3: init_shell (console)
207+
```
208+
209+
4. **Zombie reaping:**
210+
- Exited processes don't accumulate
211+
- init waits on children
212+
213+
## Open Questions
214+
215+
1. **Config format:** Built-in vs /etc/inittab file?
216+
- Start built-in, add file support later
217+
218+
2. **Console switching:** How to handle Alt+Fn in QEMU?
219+
- QEMU may intercept these; may need different keys
220+
221+
3. **Serial vs VGA console:** Which is primary?
222+
- Serial for now (easier in QEMU)
223+
- VGA console requires framebuffer work
224+
225+
## References
226+
227+
- Linux init(8) man page
228+
- systemd architecture (for modern comparison)
229+
- SysV init behavior
230+
- FreeBSD init/rc system

0 commit comments

Comments
 (0)