Idea for an Operating System written in BrainFuck ------------------------------------------------- by Daniel Marschall 18 August 2020 It is not possible to write an Operating System for a x86 machine which is completely written in BrainFuck. The only thing that can be done is writing a kernel written in x86 assembly which does following tasks: - Run BrainFuck - Offers low-level functions (I/O etc.) via "SysCalls" - Communicates with I/O devices My plan is that the kernel runs a hard-coded BrainFuck program which loads another BrainFuck program which is stored on a disk or somewhere else. If the BrainFuck code is self-modifying, the program can append the loaded program to its own code and therefore automatically executing it, once the program counter hits the spot where the code was loaded. An Operating System could look like this: - Kernel loads hardcoded BrainFuck program (which we call "bootloader") - The BF "bootloader" uses SysCalls to read from a device (e.g. a floppy disk) - Various things can happen, e.g. the BF program could read from some kind of file system, and presents the user a list of program which can be executed. Or just a single program is stored on that disk. - The chosen program will be written at the end of the "bootloader" - The program counter will hit the end of the "bootloader" and therefore executes the loaded program - In case the appending does not work, we should make sure that the "bootloader" ends with an infinite loop (this infinite loop will be overwritten by the loaded program), and at the end of the loaded program, such an infinite loop should also be appended, to avoid that the system crashes if the loaded program expects that the interpreter should stop if the program counter hits it end of the program. Alternatively, the the code at the end of the program could just jump back to the "bootloader"/OperatingSystem, so that the user could chose another program to run. Since the BrainFuck instruction set has no possibility to interact with peripherals or other low-level functions, we need to use SysCalls to in order to instruct the x86 kernel performing the low-level functions. A SysCall could be performed like this: - The BF program outputs a null-byte. - The BF interpreter will therefore enter a special state. - The BF program now outputs a number which is the SysCall number - If the SysCall expects additional arguments, then the arguments now need to be presented by the BF program, also via the output instruction. - The kernel will now perform the requested action. - If the SysCall defines a return value, then the kernel will write the result in the input-buffer, right in front of the keyboard/input queue. - Therefore, the BF program can then receive the output via the "," read instruction Example: Imagine there is a SysCall #2 which performs an addition. Input arguments: 2 numbers Output argument: 1 number which is the sum To calculate 2+3=5, and output 5, we do this: [-]. Enter SysCall mode ++. Choose SysCall #2 . Write argument #1 (2) +. Write argument #2 (3) , Read result (5) . Write it to the screen Ideas for SysCalls: SysCall# Description 1 Outputs hardcoded value "1" to check if the BF interpreter accepts SysCalls Input: None Output: "1" 2 PC speaker Input: Frequency, Duration Output: none 3 Read from disk Input: Disk ID (A=0,B=1,...), Sector Output: Data 4 Write to disk Input: Disk ID (A=0,B=1,...), Sector, Data Output: none