duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit dbca6164f1e5e9f89dba17d02acc4e2f6d2d6461
parent 80d9d192ca1e650d1d492317d3514f0509cf2924
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Fri, 20 Jan 2023 14:20:35 -0500

Improve docs

Diffstat:
Mfs/doc/arch.txt | 17+++++++++--------
Mfs/doc/asm/index.txt | 2+-
Mfs/doc/cc/index.txt | 8++++----
Mfs/doc/cc/lib.txt | 12+++++++-----
Mfs/doc/cc/usage.txt | 4++--
Mfs/doc/deploy.txt | 16+++++++++-------
Mfs/doc/dirs.txt | 8++++++++
Mfs/doc/gr/rect.txt | 4+++-
Mfs/doc/hw/i386/arch.txt | 2++
Afs/doc/hw/i386/pc/com.txt | 29+++++++++++++++++++++++++++++
Mfs/doc/hw/i386/pc/deploy.txt | 8+++++---
Mfs/doc/index.txt | 9+++++++++
Mfs/doc/lib/meta.txt | 4++--
Mfs/doc/sys/file.txt | 8+++++---
Mfs/doc/sys/grid.txt | 11++++++-----
Mfs/doc/sys/io.txt | 6+++---
Mfs/doc/text/ed.txt | 23+++++++++++++----------
Mfs/doc/text/pager.txt | 28+++++++++++++++-------------
Afs/doc/tips.txt | 10++++++++++
19 files changed, 142 insertions(+), 67 deletions(-)

diff --git a/fs/doc/arch.txt b/fs/doc/arch.txt @@ -1,9 +1,11 @@ # Dusk OS Architecture +Prerequisites: sys/io + This document describes the hardware-independent part of Dusk OS. To have a complete picture, you'll also want to read the hardware-dependent part: -* i386: doc/hw/i386/arch +* i386: hw/i386/arch ## Subroutine Threaded Code @@ -32,7 +34,7 @@ Xb name The "previous entry" field in an entry refers to this same place. -The link to "metadata" is a linked list, initialized to 0. See doc/usage. +The link to "metadata" is a linked list, initialized to 0. The "name length" field is a 7 bit length with the 8th bit reserved for the "immediate" flag (1=immediate). @@ -170,12 +172,11 @@ in the POSIX package, then this file has been constructed from two parts. A machine- specific part and a machine-independent part. For the PC platform, "init.fs" is constructed from xcomp/i386/pc/init.fs and xcomp/init.fs. -One of the things that your "init" word has to do is to set up Console's readio -(see doc/sys/io), which until now is still on BootIn, a structure that reads the -embedded code from memory. That code stream is about to run out. If your system -is interactive, you'll typically want to load sys/rdln and have init call -"rdln$" which sets Console's readio to RdlnIn, which then makes the system -interactive. +One of the things that your "init" word has to do is to set up Console's readio, +which until now is still on BootIn, a structure that reads the embedded code +from memory. That code stream is about to run out. If your system is +interactive, you'll typically want to load sys/rdln and have init call "rdln$" +which sets Console's readio to RdlnIn, which then makes the system interactive. The system is yours. diff --git a/fs/doc/asm/index.txt b/fs/doc/asm/index.txt @@ -19,7 +19,7 @@ which is the faster equivalent to: Each assembler is different and you'll want to refer to arch-specific assembler documentation before you begin using it: -* i386 (doc/asm/i386) +* i386 (asm/i386) While each assembler is different, they follow broad conventions which are described below. diff --git a/fs/doc/cc/index.txt b/fs/doc/cc/index.txt @@ -27,7 +27,7 @@ For this reason, the core of the language is very close to ANSI C. ## Topics -* Usage (doc/cc/usage) -* Implementation details (doc/cc/impl) -* Standard Library (doc/cc/lib) -* DuskCC's Forth VM details (doc/cc/forth) +* Usage (cc/usage) +* Implementation details (cc/impl) +* Standard Library (cc/lib) +* DuskCC's Forth VM details (cc/forth) diff --git a/fs/doc/cc/lib.txt b/fs/doc/cc/lib.txt @@ -1,5 +1,7 @@ # DuskCC standard library +Prerequisites: sys/io + While DuskCC's core language tries to stay very close to ANSI C, we allow ourselves significant deviations from ANSI when it comes to the standard library. Dusk's I/O is different from a regular UNIX, it handles counted strings @@ -39,8 +41,8 @@ int isdigit(char c) ### I/O -The I/O API is a simple layer over the system I/O described at doc/sys/io. `hdl` -is a regular I/O handle. +The I/O API is a simple layer over the system I/O. `hdl` is a regular I/O +handle. int fgetc(int hdl) --> IO :getc void fputc(char c, int hdl) --> IO :putc @@ -80,7 +82,7 @@ variable number of arguments which must match the number of formatting placeholder in `fmt`, *in reverse order* (this simplifies the implementation logic a lot). For example, `printf(3, 2, 1, "%b %w %d")` prints `01 0002 3`. -printf formatting arguments are described in doc/sys/io. +printf formatting arguments are described in sys/io. fscanf doesn't exist in sys/io yet and is only and CC stdlib. It supports only the `%d` placeholder. Like printf, it's funky in its arguments, but in the @@ -96,8 +98,8 @@ For example, `sscanf("%d %d %d", "5 6 7")` results in PS receiveing elements to PS. printf and scanf each have `f` and `s` variants. Without a variant, printing and -scanning is done through StdIO (see doc/sys/io). The `f` variant allow us to -choose another target I/O handle. +scanning is done through StdIO. The `f` variant allow us to choose another +target I/O handle. For the `s` variant, we have a static buffer wrapped around a `MemFile` that is used. The resulting string is a memory in that buffer and is overwritten at each diff --git a/fs/doc/cc/usage.txt b/fs/doc/cc/usage.txt @@ -46,7 +46,7 @@ are a few differences: the address of the literal by 1 (to skip the count) and adds an extra 0 at the end. * Added pspop() and pspush() built-in functions. They're tricky to use and are - described in doc/cc/impl. + described in cc/impl. * No "varargs". pspop() and pspush() replace that functionality. * "struct MyStruct {...};" automatically creates a "typedef" to the struct. * The "struct" keyword can't be used to reference structs, only to define them. @@ -119,7 +119,7 @@ modifying RS, you are on risky grounds and you should know what you do. The best approach with these situation is to proxy the word as "void()" and use "pspop()" and "pspush()" for argument passing. -Also, note that CC's lib (doc/cc/lib) already proxies quite a few system words. +Also, note that CC's lib (cc/lib) already proxies quite a few system words. ## Symbols, types and macro visibility and lifetime diff --git a/fs/doc/deploy.txt b/fs/doc/deploy.txt @@ -1,5 +1,7 @@ # Deploying Dusk OS +Prerequisites: arch, sys/io + To deploy Dusk OS on your hardware, you need to craft a bootable media for it. If you're deploying to an already supported platform, then it's only a matter of using the existing build scripts, maybe tweak the init.fs a bit. @@ -28,7 +30,7 @@ To deploy to a supported platform, it's generally only a matter of tweaking the init.fs file and run the build script. You should follow hardware-dependent deploy documentation: -* PC: doc/hw/i386/pc/deploy +* PC: hw/i386/pc/deploy ## New platforms @@ -40,9 +42,9 @@ trial and errors. Maybe these little guidelines can help you. The first thing you have to do is to write your bootloader. I don't know your platform, so I can't tell you how, but what I can tell you is that it has to load both the kernel and the boot "stream" in memory. By "stream", I mean that -the content of all the source files that compose the boot sequence (see -doc/arch) are lined up one after the other so that the Forth interpreter can -consume it all from memory. +the content of all the source files that compose the boot sequence are lined up +one after the other so that the Forth interpreter can consume it all from +memory. You have to place your boot stream so that the "boot<" word reads from it. It's generally going to be right after the kernel in memory, but it doesn't have to. @@ -102,9 +104,9 @@ Did you try a f<< call? Working too? You're on a roll! You have a working Dusk system. The rest is up to you. You probably want a prompt, right? To have that, you need to set the Console. So, write your drivers for input and output (a serial console is usually the quickest way to this) and -have those drivers create structures that extend IO (see doc/sys/io). You'll -want your input driver to implement :readbuf and your output driver to implement -:writebuf. I recommend looking at PC drivers for inspiration. +have those drivers create structures that extend IO. You'll want your input +driver to implement :readbuf and your output driver to implement :writebuf. I +recommend looking at PC drivers for inspiration. Once you have those drivers, you instantiate them in your init.fs and plug them to the Console and StdIO. diff --git a/fs/doc/dirs.txt b/fs/doc/dirs.txt @@ -22,6 +22,7 @@ a wide root directory structure based on general topics of the included code. /emul Emulators /fs Filesystems /gr Graphics +/home Virgil's workspace /lib Miscellanous little routines /sys Subsystems /tests Automated tests @@ -76,6 +77,13 @@ emulation logic. Filesystem implementations, which run on top of storage drivers. +## /home -- Virgil's workspace + +The contents of this directory is not really a part of Dusk because it +represents the "work" files that Dusk's main author uses when working within +Dusk. It's included in Dusk's packages because it's a good example of how Dusk +ought to be used effectively. + ## /lib -- Miscellanous little routines Each unit in this directory contain collections of little useful routines with diff --git a/fs/doc/gr/rect.txt b/fs/doc/gr/rect.txt @@ -1,5 +1,7 @@ # Rectangles +Prerequisites: lib/alloc + Provides a Rect structure that helps with operations on rectangles. ## API @@ -15,7 +17,7 @@ height Allocate a new rectangle with specified values. :tmpnew ( x y width height -- rect ) - Allocate new rectangle in system scratchpad (doc/lib/alloc). + Allocate new rectangle in system scratchpad. :topleft ( self -- x y ) Top-left point of the rectangle. diff --git a/fs/doc/hw/i386/arch.txt b/fs/doc/hw/i386/arch.txt @@ -1,5 +1,7 @@ # i386 architecture +Prerequisites: arch + The i386 kernel source code is xcomp/i386/kernel.fs. Register roles: PSP: EBP diff --git a/fs/doc/hw/i386/pc/com.txt b/fs/doc/hw/i386/pc/com.txt @@ -0,0 +1,29 @@ +# Serial communications + +Prerequisites: sys/io + +The driver at drv/pc/com.fs allows transmission of data through PC's COM1 port +(yes, for now it's hardcoded. It's even hardcoded to 115200 bauds 8N1). + +To use it, you simply initialize it with "com$" and then use the API described +below. + +## API + +com$ ( -- ) + Initializes COM1 to 115200 bauds 8N1. + +>com ( c -- ) + Send a character to COM1. + +com>? ( -- c? f ) + Poll COM1. If a character is present, f=1 and c is present. Otherwise, f=0 and + c is absent. + +com> ( -- c ) + Block until a character is received from COM1. + +struct COM1 extends IO + A simple IO implementation around COM1. + +structbind COM1 com1 diff --git a/fs/doc/hw/i386/pc/deploy.txt b/fs/doc/hw/i386/pc/deploy.txt @@ -1,5 +1,7 @@ # Deploying Dusk to a PC +Prerequisites: arch, deploy + As long as the PC has a 80386 CPU, it should be good enough to run Dusk, which has very small memory and disk requirements. @@ -31,14 +33,14 @@ internal disk and enable the AHCI driver. Whatever the BIOS can read through INT13h, Dusk can boot from it. Dusk is installed as a FAT volume with a bootloader embedded in its first sector. Following that first sector are a few dozens "reserved" sectors which contain -Dusk's kernel followed by its embedded boot code (see doc/arch). +Dusk's kernel followed by its embedded boot code. The task of the bootloader is to load those reserved sectors in memory, go in 32-bit protected mode, then jump to the first address of these sectors we've just loaded. Then, bootstrapping takes placed normally. Then, what you need to do is to copy all files of the Dusk system into that new -FAT volume, and craft a proper "/init.fs" file (see doc/arch). +FAT volume, and craft a proper "/init.fs" file. There is some helper code to craft such a volume in xcomp/i386/pc/build.fs. Upon loading this unit, a bootloader and kernel are compiled, and FAT creation @@ -103,4 +105,4 @@ the right one setup in your FAT headers. For example, I was really confused by how I couldn't get my Zenith Data System Pentium 75Mhz laptop to cross the first cylinder boundary, after head $0f (the BIOS *says* the HDD has 16 heads), but it turns out that, on that 1G hard drive, the proper value for "numheads" is 46. -Weird but true. To do this kind of debugging, see doc/hw/i386/pc/bios13. +Weird but true. To do this kind of debugging, see hw/i386/pc/bios13. diff --git a/fs/doc/index.txt b/fs/doc/index.txt @@ -24,6 +24,15 @@ terms Terminology dirs Directory structure arch Architecture details code Understanding Dusk's code +tips Tips and tricks asm/ Assemblers documentation cc/ C compiler documentation design/ Description and justification of design decisions + +## Prerequisites + +Documentation often refer to concepts explained elsewhere. When that's the case, +the page will begin with a "Prerequisites:" line with references to other doc +pages. It is assumed that the reader for a given page has also read +prerequisites. "usage" and "dict" are prerequisites to all other pages and are +not explicitly listed. diff --git a/fs/doc/lib/meta.txt b/fs/doc/lib/meta.txt @@ -42,8 +42,8 @@ forget ( "name" -- ) WARNING: not all "forget" operations are clean. In fact, many "forget" operations are unclean. Use with care. For example, context switching (see - doc/lib/context) and forgetting don't go well together. Arena memory - allocation (see doc/lib/alloc) and forgetting don't go well together. + lib/context) and forgetting don't go well together. Arena memory allocation + (see lib/alloc) and forgetting don't go well together. The forget operation is useful in many situations, but be aware of its effects when you use it. diff --git a/fs/doc/sys/file.txt b/fs/doc/sys/file.txt @@ -1,5 +1,7 @@ # File subsystem +Prerequisites: drive, sys/io + The file subsystem allows the system to interact with filesystems. Files and directories all live within filesystems. More than one filesystem can @@ -33,7 +35,7 @@ bar.fs file "bar.fs" in active directory When the code refers to a filesystem, it does so through a definite structure: -drv -- Drive pointer (see doc/drive) +drv -- Drive pointer :child ( dirid name fs -- id ) Enumerate the contents of directory "dirid" and look for name "name". If @@ -78,8 +80,8 @@ independent of the underlying implementation: ## File API -The File API is a specialization of the I/O API (doc/sys/io) for accessing files -in a filesystem. It also works with "handles", which we call a File handle. Of +The File API is a specialization of the I/O API for accessing files in a +filesystem. It also works with "handles", which we call a File handle. Of course, it starts with the I/O prelude, but then adds its own prelude: (I/O prelude) diff --git a/fs/doc/sys/grid.txt b/fs/doc/sys/grid.txt @@ -1,14 +1,15 @@ # Grid subsystem +Prerequisites: sys/io + The grid is a matrix of characters that represents what is seen on a screen. It has a fixed number of columns (COLS) and lines (LINES) and maintains a current position (pos) as a single number encoded as "y*COLS+x". -The grid is implemented as a IO structure extending ByteWriter (see doc/sys/io). -Its "pos" field is the "cursor" position on the screen and the IO screen -represents the terminal screen: whenever a byte is written to it through the IO -methods, the character is written at cursor position and that cursor is advanced -by one. +The grid is implemented as a IO structure extending ByteWriter. Its "pos" field +is the "cursor" position on the screen and the IO screen represents the terminal +screen: whenever a byte is written to it through the IO methods, the character +is written at cursor position and that cursor is advanced by one. If a NL character ($0a) is written to it, the grid skips to the next line. If a BS character ($08) is written to it, the cursor goes back one character. diff --git a/fs/doc/sys/io.txt b/fs/doc/sys/io.txt @@ -104,9 +104,9 @@ Filters can be applied to :readbuf and :writebuf through :addrfilter and :addwfilter. These take "word" arguments which have the same input arguments as :readbuf and :writebuf. For the output, it's funky. Read on. -Filters are chained to :readbuf/:writebuf and previous filters through "chain" -(see doc/dict). This means that when the word exits, the next word in the chain -is called, until finally the :readbuf/:writebuf word is called. +Filters are chained to :readbuf/:writebuf and previous filters through "chain". +This means that when the word exits, the next word in the chain is called, until +finally the :readbuf/:writebuf word is called. If all your filter only has to do stuff *before* the next word is called, but not after, then things are straightforward. Simply do your things and make sure diff --git a/fs/doc/text/ed.txt b/fs/doc/text/ed.txt @@ -1,5 +1,7 @@ # Text Editor +Prerequisites: sys/io, sys/file, lib/alloc, lib/context + This line based text editor lives at text/ed.fs and allows the examination and modification of text contents. @@ -9,8 +11,8 @@ this unit automatically instantiate one and binds it to the "edbuf" structbind. This structure has all the methods to need to load, save and modify text contents from within it. The buffer is a linked list of Line structures which -themselves reference buffers in an Arena allocator (see doc/lib/alloc). Lines -have a maximum length of ARENASZ bytes. +themselves reference buffers in an Arena allocator. Lines have a maximum length +of ARENASZ bytes. Interacting directly with the buffer structure gives you a maximum of flexibility, but is a bit verbose. To make text operations more efficient, @@ -18,7 +20,7 @@ shortcut words are provided. This collection of words is called the Convenience Layer. Because these shortcut can clash with other words in the system, it is -recommended to load the text editor in its own context (see doc/lib/context). +recommended to load the text editor in its own context. ## Line API @@ -50,10 +52,9 @@ character after the end of the line (it's a valid position. from there, we can append contents). At all times, we keep "cpos" within the bounds of "sel" (it can't be greater than "Line cnt"). -Edbuf extends the IO struct (see doc/sys/io), allowing some pretty nice -interactions with other IO-aware words. How it works is rather simple: reading -and writing happen at current position which advances the position by one -character to the right. +Edbuf extends the IO struct, allowing some pretty nice interactions with other +IO-aware words. How it works is rather simple: reading and writing happen at +current position which advances the position by one character to the right. When writing, whenever a LF character is encountered, we insert a new line after the selected one and move current position at the beginning of that empty line. @@ -68,7 +69,7 @@ Line numbers are 0-indexed. Fields: -buf An arena buffer with the contents of lines (see doc/lib/alloc). +buf An arena buffer with the contents of lines. lines The first Line of the LL. sel A pointer to the select Line. lpos Numerical index of "sel" @@ -198,5 +199,7 @@ eof ( -- ) Go to the last line of the buffer. edload ( -- ) - Empty the buffer and load the entire contents of "file" (see doc/sys/file) - into it. + Empty the buffer and load the entire contents of "file" into it. + +edsave ( -- ) + Save contents of edbuf into "file", truncate and flush. diff --git a/fs/doc/text/pager.txt b/fs/doc/text/pager.txt @@ -1,18 +1,20 @@ # Pager -Pagers are a way to interactively control an IO (see doc/sys/io) stream. For -now, there is only one page implementation, the "spager" (for Serial Pager), -that is, the lowest common denominator, paging-wise. It doesn't require a Grid -(see doc/sys/grid) and simply inserts a "Next page..." line at regular -intervals, waiting for user input before continuing. Pressing any key shows the -next page, pressing ESC calls "quit" (this generally returns to prompt). - -The pager is implemented as a set of Pipe filters (see doc/sys/io) and can be -hooked to any Pipe but will generally be hooked to the Console, with its "input" -companion on the "in" side of it. What this companion does is to reset the pager -threshold any time a key is requested. This way, the pager will only be -activated when there's a lot of contents to spit *at once*. It will not be -activated for commands with small outputs. +Prerequisites: sys/io, sys/grid + +Pagers are a way to interactively control an IO stream. For now, there is only +one page implementation, the "spager" (for Serial Pager), that is, the lowest +common denominator, paging-wise. It doesn't require a Grid and simply inserts a +"Next page..." line at regular intervals, waiting for user input before +continuing. Pressing any key shows the next page, pressing ESC calls "quit" +(this generally returns to prompt). + +The pager is implemented as a set of Pipe filters and can be hooked to any Pipe +but will generally be hooked to the Console, with its "input" companion on the +"in" side of it. What this companion does is to reset the pager threshold any +time a key is requested. This way, the pager will only be activated when there's +a lot of contents to spit *at once*. It will not be activated for commands with +small outputs. For now, the pager counter is global. diff --git a/fs/doc/tips.txt b/fs/doc/tips.txt @@ -0,0 +1,10 @@ +# Tips and tricks + +## Alternate init path + +Working on your init.fs often puts you at high risk of rendering it unbootable +with one tiny mistake. If you're working on the "high-level" part (after "emit" +and "key" are there) of your init, you can create a fork of it to allow you to +boot to the old init if needed. Example: + + key 'z' = [if] f<< /init2.fs \s [then]