Chapter 30 — First User-Mode Shell

Chapter 30 — First User-Mode Shell
This entry is part 27 of 28 in the series Writing A Linux Style Operating System From Scratch

In Chapter 29, we added the first shared userland runtime. This chapter extends that runtime with formatted output and shell-oriented helpers, then uses it to build the first real long-running user-mode program: This first shell will run entirely in ring 3. It will read lines from stdin, parse commands, and execute a few built-in commands.

Chapter 28 — Pattern-Based User Program Build System

Chapter 28 — Pattern-Based User Program Build System
This entry is part 25 of 28 in the series Writing A Linux Style Operating System From Scratch

In Chapter 27, we added a second user program: That proved the program registry can handle more than one embedded ELF. But the Makefile now has duplicated build rules: That will not scale. This chapter cleans up the user-program build system so adding a new user program is mostly: and then adding: The build system

Chapter 27 — A Second User Program for Safe Background Execution

This entry is part 24 of 28 in the series Writing A Linux Style Operating System From Scratch

In Chapter 26, we added: That gave us a real background process path. But our only user program, demo, waits for terminal input: That makes it awkward for runbg, because a background process can compete with the monitor for keyboard input. This chapter adds a second embedded user program: counter does not read from stdin.

Chapter 26 — Process Table, ps, runbg, and wait PID

Chapter 26 — Process Table, ps, runbg, and wait PID
This entry is part 23 of 28 in the series Writing A Linux Style Operating System From Scratch

In Chapter 25, the monitor gained an embedded program registry and a foreground run command: That gave us an exec-like path, but only in foreground mode: This chapter adds the next process-management layer: After this chapter, the monitor will support: The kernel still does not have job control, signals, or a filesystem, but it now

Chapter 24 — User argc / argv and a Real Initial Stack

Chapter 24 — User argc / argv and a Real Initial Stack
This entry is part 22 of 28 in the series Writing A Linux Style Operating System From Scratch

In Chapter 23, we crossed another major boundary: But the user program still started like this: That is not how we want user programs to look long-term. This chapter adds a real initial user stack with: Then crt0.S will pass those arguments to: This moves us closer to a normal process startup model. ELF process

Chapter 23 — Building a Real User C Program and Embedding Its ELF

Chapter 23 — Building a Real User C Program and Embedding Its ELF
This entry is part 21 of 28 in the series Writing A Linux Style Operating System From Scratch

In Chapter 22, the kernel gained a first ELF32 loader. That was a big step, but our test ELF was still built by hand inside process.c: This chapter removes that artificial piece. We will add a tiny userland build pipeline: GNU objcopy is specifically designed to copy and transform object files between formats; we will

Chapter 21 — Process Teardown and Address-Space Cleanup

Chapter 21 — Process Teardown and Address-Space Cleanup
This entry is part 20 of 28 in the series Writing A Linux Style Operating System From Scratch

In Chapter 20, we added the TOYEXE loader: But there is still a lifecycle problem. The process can exit, but we are not yet reclaiming everything it owns. Right now this leaks: This chapter closes that loop. After this chapter, the process lifecycle becomes: The milestone output will look like: 1. What this chapter adds

Chapter 20 — A Tiny Executable Format and User Program Loader

Chapter 20 — A Tiny Executable Format and User Program Loader
This entry is part 5 of 28 in the series Writing A Linux Style Operating System From Scratch

In Chapter 19, we gave each process its own address space: That was a major architectural milestone. But our user program is still not really “loaded.” We are still building a TOYEXE image inside process.c and handing it to the loader. This chapter adds a small executable format before jumping to ELF. We will call

Chapter 19 — Per-Process Address Spaces and CR3 Switching

Chapter 19 — Per-Process Address Spaces and CR3 Switching
This entry is part 19 of 28 in the series Writing A Linux Style Operating System From Scratch

In Chapter 18, user programs gained a much more realistic syscall interface: But all user processes still shared the same page directory. That means every process saw the same user mappings: This chapter gives each process its own address space. The new model becomes: When the scheduler switches between processes, it will also switch CR3.

Chapter 18 — File-Descriptor Syscalls and a Tiny User-Mode Console Program

Chapter 18 — File-Descriptor Syscalls and a Tiny User-Mode Console Program
This entry is part 18 of 28 in the series Writing A Linux Style Operating System From Scratch

In Chapter 17, we added the first minimal process object: That was a big step, but the syscall interface was still a little too artificial. This chapter makes user programs feel more like real programs by adding a tiny file-descriptor-style interface: We will update SYS_WRITE to use a file descriptor, add SYS_READ, and run a