From 3c8b28becf989ec7903ee90884037b39806858e8 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Fri, 26 Apr 2019 17:47:59 -0700 Subject: 5128 --- subx/Readme.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 9 deletions(-) (limited to 'subx') diff --git a/subx/Readme.md b/subx/Readme.md index b3b58c86..3e7f0e68 100644 --- a/subx/Readme.md +++ b/subx/Readme.md @@ -2,12 +2,18 @@ SubX is a simple, minimalist stack for programming your computer. - ``` + ```sh $ git clone https://github.com/akkartik/mu $ cd mu/subx $ ./subx # print out a help message ``` +SubX is designed: + +* to explore ways to turn arbitrary manual tests into reproducible automated tests, +* to be easy to implement in itself, and +* to help learn and teach the x86 instruction set. + It requires a Unix-like environment with a C++ compiler (Linux or BSD or Mac OS). Running `subx` will transparently compile it as necessary. @@ -513,10 +519,39 @@ trace, or if you have questions or complaints. ### 'system calls' -A major goal of SubX is testable wrappers for operating system syscalls. -Here's what I've built so far: +As I said at the top, a primary design goal of SubX (and Mu more broadly) is +to explore ways to turn arbitrary manual tests into reproducible automated +tests. SubX aims for this goal by baking testable interfaces deep into the +stack, at the OS syscall level. The idea is that every syscall that interacts +with hardware (and so the environment) should be *dependency injected* so that +it's possible to insert fake hardware in tests. + +The hypothesis is that designing the entire system to be testable from day 1 +and from the ground up would radically impact the culture of the eco-system in +a way that no bolted-on tool or service at higher levels can replicate: + +* Tests would make it easier to write programs that can be easily understood + by newcomers. -* `write`: takes two arguments, a file `f` and an address to array `s`. +* More broad-based understanding would lead to more forks. + +* Tests would make it easy to share code across forks. Copy the tests over, + and then copy code over and polish it until the tests pass. Manual work, but + tractable and without major risks. + +* The community would gain a diversified portfolio of forks for each program, + a “wavefront” of possible combinations of features and alternative + implementations of features. Application writers who wrote thorough tests + for their apps (something they just can’t do today) would be able to bounce + around between forks more easily without getting locked in to a single one + as currently happens. + +* There would be a stronger culture of reviewing the code for programs you use + or libraries you depend on. [More eyeballs would make more bugs shallow.](https://en.wikipedia.org/wiki/Linus%27s_Law) + +But those are big goals. Here are the syscalls I have so far: + +1. `write`: takes two arguments, a file `f` and an address to array `s`. Comparing this interface with the Unix `write()` syscall shows two benefits: @@ -527,7 +562,7 @@ Here's what I've built so far: SubX's wrapper keeps the two together to increase the chances that we never accidentally go out of array bounds. -* `read`: takes two arguments, a file `f` and an address to stream `s`. Reads +1. `read`: takes two arguments, a file `f` and an address to stream `s`. Reads as much data from `f` as can fit in (the free space of) `s`. Like with `write()`, this wrapper around the Unix `read()` syscall adds the @@ -538,7 +573,7 @@ Here's what I've built so far: to another. See [the comments before the implementation](http://akkartik.github.io/mu/html/subx/058read.subx.html) for a discussion of alternative interfaces. -* `stop`: takes two arguments: +1. `stop`: takes two arguments: - `ed` is an address to an _exit descriptor_. Exit descriptors allow us to `exit()` the program in production, but return to the test harness within tests. That allows tests to make assertions about when `exit()` is called. @@ -547,13 +582,13 @@ Here's what I've built so far: For more details on exit descriptors and how to create one, see [the comments before the implementation](http://akkartik.github.io/mu/html/subx/057stop.subx.html). -* `new-segment` +1. `new-segment` Allocates a whole new segment of memory for the program, discontiguous with both existing code and data (heap) segments. Just a more opinionated form of [`mmap`](http://man7.org/linux/man-pages/man2/mmap.2.html). -* `allocate`: takes two arguments, an address to allocation-descriptor `ad` +1. `allocate`: takes two arguments, an address to allocation-descriptor `ad` and an integer `n` Allocates a contiguous range of memory that is guaranteed to be exclusively @@ -566,7 +601,11 @@ Here's what I've built so far: management, where a sub-system gets a chunk of memory and further parcels it out to individual allocations. Particularly helpful for (surprise) tests. -* ... _(to be continued)_ +1. ... _(to be continued)_ + +I will continue to import syscalls over time from [the old Mu VM in the parent +directory](https://github.com/akkartik/mu), which has experimented with +interfaces for the screen, keyboard, mouse, disk and network. ### primitives built atop system calls -- cgit 1.4.1-2-gfad0