X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;f=README.md;h=39b9eb61a2b3e76902a206f8292e473d0d5fd6b1;hb=f0df53c35124c9a5e2b045aba60b513faa344567;hp=2ed38d52851dd3679fa2236efc9bb14a795d45c1;hpb=a6faff31f03d96b6a62188f330848004119d5165;p=rrq%2Fjonasforth.git diff --git a/README.md b/README.md index 2ed38d5..39b9eb6 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,26 @@ The `example.f` file contains an example that you can run with: $ cat sys.f example.f | ./main +## Running with UEFI + +We are currently in the process of implementing support for running without +Linux, by instead relying on UEFI. Eventually, this will be the only supported +method of running the interpreter, but currently the UEFI-related code is +isolated in the `uefi/` directory and does not yet contain an implementation of +the main program. + +You should have the following dependencies installed (assuming Arch Linux): + + $ pacman -S qemu ovmf + +To run a UEFI shell inside qemu, cd to `uefi/` and run: + + $ make run + +### Running on read hardware + +* [ ] This is not supported yet + # Notes on implementation This is my summary of the most important parts of @@ -21,7 +41,8 @@ https://raw.githubusercontent.com/nornagon/jonesforth/master/jonesforth.S. ## Dictionary -In Forth, words are stored in a dictionary. The dictionary is a linked list whose entries look like this: +In Forth, words are stored in a dictionary. The dictionary is a linked list +whose entries look like this: +------------------------+--------+---------- - - - - +----------- - - - - | LINK POINTER | LENGTH/| NAME | DEFINITION @@ -155,3 +176,122 @@ then switches back to immediate mode. These words rely on `,` to append words to the currently compiling definition. This word simply appends some literal value to `HERE` and moves the `HERE` pointer forward. + +# Notes on UEFI + +`JONASFORTH` is runs without an operating system, instead using the facilities +provided by UEFI by running as a UEFI application. (Or rather, in the future it +hopefully will. Right now, it uses Linux.) This section contains some notes +about how this functionality is implemented. + +## Packaging and testing the image + +UEFI expects a UEFI application to be stored in a FAT32 file system on a +GPT-partitioned disk. + +Luckily, QEMU has a convenient way of making a subdirectory availabe as a +FAT-formatted disk (see [the relevant section in the QEMU User +Documentation](https://qemu.weilnetz.de/doc/qemu-doc.html#disk_005fimages_005ffat_005fimages) +for more information): + + $ qemu-sytem-x86_64 ... -hda fat:/some/directory + +We use this to easily test the image in QEMU; see the Makefile for more information. + +* [ ] How to build the image for real hardware (what should the image look like, + which programs, commands, etc.) + +## Interfacing with UEFI + +From [OSDev Wiki](https://wiki.osdev.org/UEFI#How_to_use_UEFI): + +>Traditional operating systems like Windows and Linux have an existing software +>architecture and a large code base to perform system configuration and device +>discovery. With their sophisticated layers of abstraction they don't directly +>benefit from UEFI. As a result, their UEFI bootloaders do little but prepare +>the environment for them to run. +> +>An independent developer may find more value in using UEFI to write +>feature-full UEFI applications, rather than viewing UEFI as a temporary +>start-up environment to be jettisoned during the boot process. Unlike legacy +>bootloaders, which typically interact with BIOS only enough to bring up the OS, +>a UEFI application can implement sophisticated behavior with the help of UEFI. +>In other words, an independent developer shouldn't be in a rush to leave +>"UEFI-land". + +For `JONASFORTH`, I have decided to run as a UEFI application, taking advantage +of UEFI's features, including its text I/O features and general graphical device +drivers. Eventually, we would like to add some basic graphical drawing +capabilities to `JONASFORTH`, and it's my impression that this would be possible +using what is provided to us by UEFI. + +A UEFI images is basically a windows EXE without symbol tables. There are three +types of UEFI images; we use the EFI application, which has subsystem `10`. It +is an x68-64 image, which has value `0x8664`. + +UEFI applications use [Microsoft's 64-bit calling convention](https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention) for x68-64 functions. See the linked article for a full description. Here is the short version: + +* Integer or pointer arguments are given in RCX, RDX, R8 and R9. +* Additional arguments are pushed onto the stack from right to left. +* Integer or pointer values are returned in RAX. +* An integer-sized struct is passed directly; non-integer-sized structs are passed as pointers. +* The caller must allocate 32 bytes of "shadow space" on the stack immediately + before calling the function, regardless of the number of parameters used, and + the caller is responsible for popping the stack afterwards. +* The following registers are volatile (caller-saved): RAX, RCX, RDX, R8, R9, R10, R11 +* The following registers are nonvolatile (callee-saved): RBX, RBP, RDI, RSI, RSP, R12, R13, R14, R15 + +When the application is loaded, RCX contains a firmware allocated `EFI_HANDLE` +for the UEFI image, RDX contains a `EFI_SYSTEM_TABLE*` pointer to the EFI system +table and RSP contains the return address. For more infromation about how a UEFI +application is entered, see "4 - EFI System Table" in [the latest UEFI +specification as of March 2020 (PDF)](https://uefi.org/sites/default/files/resources/UEFI_Spec_2_8_A_Feb14.pdf). + +**Sources:** + +* [UEFI applications in detail - OSDev Wiki](https://wiki.osdev.org/UEFI#UEFI_applications_in_detail) +* [Microsoft x64 calling convention](https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention) +* [UEFI Specifications](https://uefi.org/specifications) + +### UEFI with FASM + +We might want to consider using something like this: https://wiki.osdev.org/Uefi.inc) + +FASM can generate UEFI application binaries by default. Use the following +template to output a 64-bit UEFI application: + + format pe64 dll efi + entry main + + section '.text' code executable readable + + main: + ;; ... + ret + + section '.data' data readable writable + + ;; ... + +Use `objdump -x` to inspect the assembled application binary. + +### UEFI documentation + +* [Latest specification as of March 2020 (PDF)](https://uefi.org/sites/default/files/resources/UEFI_Spec_2_8_A_Feb14.pdf) + +Notable sections: + +* 2\. Overview (14) +* 4\. EFI System Table (89) +* 7\. Services - Boot Services (140) +* 8\. Services - Runtime Services (228) +* 12\. Protocols - Console Support (429) +* 13\. Protocols - Media Access (493) +* Appendix B - Console (2201) +* Appendix D - Status Codes (2211) + +## Resources + +* [UEFI - OSDev Wiki](https://wiki.osdev.org/UEFI) +* [Unified Extensible Firmware Interface (Wikipedia)](https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface) +* [UEFI Specifications](https://uefi.org/specifications)