From d5233696c8096f86212ed6758d6465be8f1f43e1 Mon Sep 17 00:00:00 2001 From: Emil Momchev <80454439+Mrgoblings@users.noreply.github.com> Date: Mon, 25 Nov 2024 16:20:15 +0200 Subject: [PATCH] [Patch] Documentation for Bootloader, Kernel, VGA, CI Github Actions and Multiboot (#20) --- README.md | 65 +++++++- docs/README.md | 98 ++++++++++++ docs/applications/README.md | 9 ++ docs/applications/browser.md | 3 + docs/applications/terminal.md | 3 + docs/bootloader/README.md | 46 ++++++ docs/bootloader/boot-64.md | 71 +++++++++ docs/bootloader/boot.md | 205 ++++++++++++++++++++++++ docs/bootloader/header.md | 39 +++++ docs/ci-github-actions/README.md | 15 ++ docs/ci-github-actions/release.md | 256 ++++++++++++++++++++++++++++++ docs/ci-github-actions/test.md | 64 ++++++++ docs/kernel/README.md | 20 +++ docs/kernel/vga.md | 142 +++++++++++++++++ docs/multiboot/README.md | 45 ++++++ docs/window-manager/README.md | 3 + 16 files changed, 1082 insertions(+), 2 deletions(-) create mode 100644 docs/README.md create mode 100644 docs/applications/README.md create mode 100644 docs/applications/browser.md create mode 100644 docs/applications/terminal.md create mode 100644 docs/bootloader/README.md create mode 100644 docs/bootloader/boot-64.md create mode 100644 docs/bootloader/boot.md create mode 100644 docs/bootloader/header.md create mode 100644 docs/ci-github-actions/README.md create mode 100644 docs/ci-github-actions/release.md create mode 100644 docs/ci-github-actions/test.md create mode 100644 docs/kernel/README.md create mode 100644 docs/kernel/vga.md create mode 100644 docs/multiboot/README.md create mode 100644 docs/window-manager/README.md diff --git a/README.md b/README.md index 0e253e81..d06c6216 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,65 @@ # AnasOS -an operatin system -Curently in development. +AnasOS is a lightweight operating system developed as a graduation project. The primary goal is to create a functional OS from scratch using modern technologies. + +## Download + +You can download the latest release of AnasOS, including the `iso.zip` file, from the [releases page](https://github.com/Mrgoblings/AnasOS/releases). + +## Technologies Used + +- **Rust**: The core of the operating system is written in Rust for safety and performance. +- **Assembly**: Utilized for low-level system programming. +- **Makefile**: Used for managing build automation. + +## Building the OS + +If you want to build AnasOS yourself, please follow these instructions for a Debian-based Linux distribution: + +1. **Clone the repository**: + +```sh +git clone https://github.com/Mrgoblings/AnasOS.git +cd AnasOS +``` + +2. **Install dependencies**: + +```sh +sudo apt update +sudo apt install -y nasm grub-pc-bin grub-common make mtools xorriso +rustup update nightly +rustup target add x86_64-unknown-none --toolchain nightly +rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu +``` + +3. **Build & Run the OS in qemu**: + +```sh +make +``` + +## Documentation + +For more detailed instructions and documentation, please refer to the [docs/](docs/) directory. There is a README file that explains everything needed for the OS. + +## References + +Here are some tutorials and resources that were used in the creation of AnasOS: + +- [ Writing an OS in Rust from Philipp Oppermann's blog](https://os.phil-opp.com/) +- [Write Your Own 64-bit Operating System Kernel by CodePulse](https://www.youtube.com/playlist?list=PLZQftyCk7_SeZRitx5MjBKzTtvk0pHMtp) +- [Making an OS (x86) by Daedalus Community](https://www.youtube.com/playlist?list=PLm3B56ql_akNcvH8vvJRYOc7TbYhRs19M) +- [Operating Systems by OliveStem](https://www.youtube.com/playlist?list=PL2EF13wm-hWAglI8rRbdsCPq_wRpYvQQy) +- [Stack Unwinding](https://www.bogotobogo.com/cplusplus/stackunwinding.php) +- [Rust Standard Library Runtime](https://github.com/rust-lang/rust/blob/bb4d1491466d8239a7a5fd68bd605e3276e97afb/src/libstd/rt.rs#L32-L73) +- [Name Mangling](https://en.wikipedia.org/wiki/Name_mangling) +- [Calling Convention](https://en.wikipedia.org/wiki/Calling_convention) +- [Cross Compilation with Clang](https://clang.llvm.org/docs/CrossCompilation.html#target-triple) +- [Multiboot Specification](https://wiki.osdev.org/Multiboot) +- [GNU GRUB Multiboot](https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#OS-image-format) +- [Paging in Operating System](https://www.geeksforgeeks.org/paging-in-operating-system/) + +## Author and Licensing + +AnasOS is developed by Emil Momchev. The project is licensed under the [MIT License](LICENSE). When distributing, mention the author and the repository. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..fde33ecc --- /dev/null +++ b/docs/README.md @@ -0,0 +1,98 @@ +# AnasOS Documentation + +Welcome to the AnasOS documentation. This document will guide you through the various components of the AnasOS operating system, including the multiboot configuration, kernel, window manager, and applications. + +## Table of Contents + +1. [Introduction](#introduction) +2. [File Structure](#file-structure) +3. [Multiboot Configuration](#multiboot-configuration) +4. [Bootloader](#bootloader) +4. [Kernel](#kernel) +5. [Window Manager](#window-manager) +6. [Applications](#applications) +7. [Technologies Used](#technologies-used) +8. [CI with GitHub Actions](#ci-with-github-actions) +9. [Requirements](#requirements) + +## Introduction + +AnasOS is a custom operating system designed for educational purposes as part of a 12th-grade thesis project. This documentation provides detailed information about the different parts of the OS and how they work together. AnasOS is built for the **_x86_64_** architecture, chosen over ARM due to the availability of more and better resources on the topic. + +## Technologies Used + +- **Rust**: The core of the operating system is written in Rust for safety and performance. +- **NASM**: The assembler used for writing assembly code for the bootloader. +- **Makefile**: Used for managing build automation. +- **GRUB**: The bootloader used for loading the kernel. +- **QEMU**: The emulator used for testing the operating system. +- **GitHub Actions**: Used for continuous integration and deployment. + +## File Structure + +Below is the file structure for the AnasOS documentation: + +``` +/docs + ├── README.md + ├── applications + │ ├── README.md + │ ├── browser.md + │ └── terminal.md + ├── bootloader + │ ├── README.md + │ ├── header.md + │ ├── boot.md + │ └── boot-64.md + ├── ci-github-actions + │ ├── README.md + │ ├── header.md + │ ├── boot.md + │ └── boot-64.md + ├── kernel + │ ├── README.md + │ └── kernel.md + ├── multiboot + │ ├── README.md + │ └── multiboot.md + └── window-manager + ├── README.md + └── window_manager.md +``` + +## Multiboot Configuration + +The multiboot configuration is responsible for initializing the hardware and loading the kernel into memory. Detailed documentation about the multiboot configuration can be found [here](multiboot/). + +## Bootloader + +The bootloader is a critical component that initializes the system and loads the kernel into memory. It is responsible for setting up the environment so that the kernel can execute properly. Detailed documentation about the bootloader can be found [here](bootloader/). + +## Kernel + +The kernel is the core component of AnasOS, managing system resources and providing essential services. Detailed documentation about the kernel can be found [here](kernel/). + +## Window Manager + +The window manager **WILL** handle the graphical user interface and window management. Detailed documentation about the window manager will be available [here](window-manager/). + +## Applications + +AnasOS **WILL** include two main applications: a [browser](applications/browser.md) and a [terminal](applications/terminal.md). Detailed documentation about these applications will be available [here](applications/). + +## CI with GitHub Actions + +GitHub Actions is used for continuous integration (CI) to automate the build, testing, and release processes of AnasOS. This ensures that every change is verified, the system remains stable, and new versions are released efficiently. The workflows are defined in the `.github/workflows` directory, with detailed documentation available in the [here](ci-github-actions/). + +## Requirements + +Before fully testing the OS, ensure you have the following requirements installed: + +- **Rust**: Install Rust from [rust-lang.org](https://www.rust-lang.org/). +- **NASM**: Install NASM from [nasm.us](https://www.nasm.us/). +- **GRUB**: Install GRUB using your package manager. +- **QEMU**: Install QEMU from [qemu.org](https://www.qemu.org/). +- **Make**: Ensure Make is installed on your system. + + +You can install the required packages on Debian-based Linux distributions using `apt` with the example from the [main README](../) file \ No newline at end of file diff --git a/docs/applications/README.md b/docs/applications/README.md new file mode 100644 index 00000000..1a0df92b --- /dev/null +++ b/docs/applications/README.md @@ -0,0 +1,9 @@ +# Applications + +## Available Applications + +### Browser +For more information, see [Browser](browser.md). + +### Terminal +For more information, see [Terminal](terminal.md). diff --git a/docs/applications/browser.md b/docs/applications/browser.md new file mode 100644 index 00000000..7892ce82 --- /dev/null +++ b/docs/applications/browser.md @@ -0,0 +1,3 @@ +# Browser Application + +Coming soon. Not yet implemented. diff --git a/docs/applications/terminal.md b/docs/applications/terminal.md new file mode 100644 index 00000000..920e0ae3 --- /dev/null +++ b/docs/applications/terminal.md @@ -0,0 +1,3 @@ +# Terminal Application + +Coming soon. Not yet implemented. \ No newline at end of file diff --git a/docs/bootloader/README.md b/docs/bootloader/README.md new file mode 100644 index 00000000..9959d434 --- /dev/null +++ b/docs/bootloader/README.md @@ -0,0 +1,46 @@ +# AnasOS Bootloader Documentation + +## Overview + +The AnasOS bootloader is a critical component of the AnasOS operating system. Written in NASM assembly, it is responsible for initializing the system and transitioning the CPU from real mode to 64-bit long mode. This document provides an overview of the bootloader's functionality and its role in the boot process. + +## Boot Files + +The bootloader consists of three main files: +- **header.asm**: Contains the Multiboot2 header required for bootloader compatibility. More in the [header.md](header.md) +- **boot.asm**: The main bootloader code, responsible for the entire boot process including setting up the stack, checking Multiboot compatibility, enabling paging, and handling errors More in the [boot.md](boot.md) +- **boot-64.asm**: Handles the transition to 64-bit long mode. More in the [boot-64.md](boot-64.md) + +## Integration with the Kernel + +The bootloader is tightly integrated with the AnasOS kernel. The build process is managed by a `build.rs` script, which automates the compilation and linking of the bootloader and kernel object files into a single binary. + +### Build Process + +The `build.rs` script performs the following steps: +1. **Assemble Bootloader**: The NASM assembler is used to compile the bootloader assembly files into object files. + ```sh + nasm -f elf64 header.asm -o header.o + nasm -f elf64 boot.asm -o boot.o + nasm -f elf64 boot-64.asm -o boot-64.o + ``` +2. **Link Object Files**: The object files are linked together with the kernel object files to create a single binary. + ```sh + ld -n -o bootloader.bin -T linker.ld header.o boot.o boot-64.o kernel.o + ``` + +### Bootloader Compilation + +To compile only the bootloader manually, you would typically run the following commands: +```sh +nasm -f elf64 header.asm -o header.o +nasm -f elf64 boot.asm -o boot.o +nasm -f elf64 boot-64.asm -o boot-64.o +ld -n -o bootloader.bin -T linker.ld header.o boot.o boot-64.o +``` + +For simplicity, there is a Makefile in the `anasos-kernel/bootloader` folder that handles this compilation. This Makefile is a simplified version of the main Makefile from the root folder, but its purpose is to compile correctly and run the newly created ISO from the bootloader with QEMU. + +## Conclusion + +The AnasOS bootloader is a sophisticated piece of software that ensures a smooth transition from the initial power-on state to a fully operational 64-bit environment. Its careful design and implementation in NASM assembly make it a reliable foundation for the AnasOS operating system. diff --git a/docs/bootloader/boot-64.md b/docs/bootloader/boot-64.md new file mode 100644 index 00000000..683eb147 --- /dev/null +++ b/docs/bootloader/boot-64.md @@ -0,0 +1,71 @@ +# BOOT-64.ASM Documentation + +## Introduction +This document provides a detailed explanation of the `BOOT-64.ASM` file, which is responsible for initializing the CPU in 64-bit long mode. After jumping into 64-bit mode, it's essential to set up the CPU environment correctly to ensure proper operation. The code is written in assembly language and is crucial for setting up the environment before the operating system kernel takes over. This documentation aims to explain each instruction and its purpose. + +## Code Explanation + +### Section: Setting Up Long Mode +```assembly +GLOBAL long_mode_start +EXTERN _start + +SECTION .text +BITS 64 +long_mode_start: + ; load null to all data segment registers (needed for the cpu to work as intended) + MOV ax, 0 + MOV ss, ax + MOV ds, ax + MOV es, ax + MOV fs, ax + MOV gs, ax + + CALL _start + + HLT +``` + +#### Detailed Breakdown + +1. **GLOBAL long_mode_start** + - Makes the `long_mode_start` label available to other files, allowing them to reference this entry point. + +2. **EXTERN _start** + - Declares an external symbol `_start`, which is the main function of the Rust kernel. This is where the kernel's execution begins. + +3. **SECTION .text** + - Defines the beginning of a code section named `.text`, where the executable code resides. + +4. **BITS 64** + - Informs the assembler that the following code is intended for 64-bit mode. + +5. **long_mode_start:** + - A label marking the entry point of the long mode setup code. At this point, the system has just transitioned into 64-bit mode. + +6. **MOV ax, 0** + - Loads the value `0` into the `AX` register to prepare for initializing the segment registers. + +7. **MOV ss, ax** + - Sets the `SS` (Stack Segment) register to `0`. In 64-bit mode, all segment registers need to be set to `0` for the CPU to function properly, ensuring correct memory addressing. + +8. **MOV ds, ax** + - Sets the `DS` (Data Segment) register to `0`, which is necessary for proper data access. + +9. **MOV es, ax** + - Sets the `ES` (Extra Segment) register to `0`. + +10. **MOV fs, ax** + - Sets the `FS` (Additional Data Segment) register to `0`. + +11. **MOV gs, ax** + - Sets the `GS` (Additional Data Segment) register to `0`. Initializing all these registers prevents segmentation errors and ensures the CPU operates as expected. + +12. **CALL _start** + - Calls the `_start` function, transferring control to the Rust kernel's main function. + +13. **HLT** + - Halts the CPU, typically used if there is nothing else to execute. + +## Conclusion +The `BOOT-64.ASM` file is a critical component in the boot process of an operating system. After entering 64-bit long mode, setting all segment registers to `0` is essential for the CPU to function properly. This setup prepares the environment for the kernel's main function `_start` to take over. Each instruction serves a specific purpose to ensure the CPU operates correctly and transitions smoothly to the kernel. diff --git a/docs/bootloader/boot.md b/docs/bootloader/boot.md new file mode 100644 index 00000000..f9e75acd --- /dev/null +++ b/docs/bootloader/boot.md @@ -0,0 +1,205 @@ +# Bootloader Deep Dive + +This document provides a detailed explanation of the bootloader assembly code that transitions the CPU from 32-bit protected mode to 64-bit long mode. It performs essential checks and configurations to ensure the system is ready for the operating system to take over. + +## Table of Contents + +1. [Introduction](#introduction) +2. [Stack Setup](#2-stack-setup) +3. [Power-On Self Test (POST)](#3-power-on-self-test-post) + - [Multiboot Check](#31-multiboot-check) + - [CPUID Check](#32-cpuid-check) + - [Long Mode Check](#33-long-mode-check) +4. [Page Table Setup](#4-page-table-setup) +5. [GDT Setup](#5-gdt-setup) +6. [Enabling Paging](#6-enabling-paging) +7. [Error Handling](#7-error-handling) +8. [Conclusion](#conclusion) + +## Introduction + +A bootloader initializes the system hardware and prepares the environment for the operating system. This specific bootloader sets up the necessary conditions to enable long mode, allowing the CPU to operate in 64-bit mode. + +## 2. Stack Setup + +Before performing any operations, the bootloader sets up the stack: + +```assembly +MOV esp, stack_top ; Set the stack pointer to the top of the stack +``` + +- **`ESP` (Extended Stack Pointer)**: Points to the top of the stack. Initializing `ESP` ensures that function calls and interrupts have a valid stack space to work with. + +## 3. Power-On Self Test (POST) + +The bootloader performs a series of checks to verify the system's capabilities before proceeding. + +### 3.1. Multiboot Check + +Verifies if the bootloader is loaded by a Multiboot-compliant bootloader: + +```assembly +CMP eax, 0x36d76289 ; Compare EAX with the Multiboot magic number +JNE .no_multiboot ; Jump if not equal to the error handler +``` + +- **`EAX`**: Contains the magic number passed by the Multiboot bootloader. Comparing it verifies compatibility. +- **`CMP`**: Sets flags based on the comparison between `EAX` and the magic number. +- **`JNE`**: Jumps to `.no_multiboot` if the zero flag is not set, indicating a mismatch. + +### 3.2. CPUID Check + +Checks if the CPU supports the `CPUID` instruction: + +```assembly +PUSHFD ; Save current EFLAGS to the stack +POP eax ; Copy EFLAGS into EAX +MOV ecx, eax ; Store original EFLAGS in ECX +XOR eax, 1 << 21 ; Toggle the ID flag (bit 21) +PUSH eax ; Push modified EFLAGS back to the stack +POPFD ; Restore modified EFLAGS +PUSHFD ; Save modified EFLAGS to stack +POP eax ; Copy modified EFLAGS into EAX +PUSH ecx ; Restore original EFLAGS from ECX +POPFD ; Restore original EFLAGS +CMP eax, ecx ; Compare modified EFLAGS with original +JE .no_cpuid ; If equal, CPUID is not supported +``` + +- **ID Flag (Bit 21 of EFLAGS)**: Indicates support for `CPUID` when it can be modified. +- **`XOR`**: Toggles the specified bit in `EAX`. +- **`PUSHFD`/`POPFD`**: Preserve and restore the EFLAGS register. +- **`CMP` and `JE`**: Determines if the ID flag change was successful. + +### 3.3. Long Mode Check + +Determines if the CPU supports 64-bit long mode: + +```assembly +MOV eax, 0x80000000 ; Set EAX to check extended CPUID functions +CPUID ; Get highest extended function supported +CMP eax, 0x80000001 ; Check if extended functions are sufficient +JB .no_long_mode ; Jump if not supported +MOV eax, 0x80000001 ; Get extended processor info +CPUID +TEST edx, 1 << 29 ; Test if Long Mode bit is set in EDX +JZ .no_long_mode ; Jump if Long Mode is not supported +``` + +- **Extended Function 0x80000001**: Provides feature bits in `EDX`. +- **Long Mode Bit (Bit 29 of `EDX`)**: Indicates support for 64-bit mode. +- **`TEST`**: Performs bitwise AND without altering operands, sets flags accordingly. +- **`JZ`**: Jumps if the result of `TEST` is zero. + +## 4. Page Table Setup + +Configures identity-mapped page tables for long mode: + +```assembly +MOV eax, page_table_l3 ; Load address of L3 page table +OR eax, 0b11 ; Set Present and Write flags +MOV [page_table_l4], eax ; Link L4 to L3 + +MOV eax, page_table_l2 ; Load address of L2 page table +OR eax, 0b11 ; Set flags +MOV [page_table_l3], eax ; Link L3 to L2 + +MOV ecx, 0 ; Initialize counter +.loop_setup_page_tables: +MOV eax, 0x200000 ; Load 2MiB page size +MUL ecx ; Calculate offset +OR eax, 0b10000011 ; Set Huge Page, Present, and Write flags +MOV [page_table_l2 + ecx * 8], eax + +INC ecx +CMP ecx, 512 ; Check if entire table is mapped +JNE .loop_setup_page_tables +``` + +- **`EAX`**: Used to hold addresses and manipulate page table entries. +- **`OR eax, 0b11`**: Sets the Present and Write flags in the page table entry. +- **`MOV [destination], eax`**: Stores the updated entry in the page table. +- **`ECX`**: Serves as a loop counter for page table entries. +- **`MUL`**: Multiplies `EAX` by `ECX` to compute the memory address for each page. +- **Huge Page**: Indicates a page size of 2MiB. + +## 5. GDT Setup + +Loads the Global Descriptor Table (GDT) to define the code segment for long mode: + +```assembly +LGDT [gdt64.pointer] ; Load the address of the GDT +``` + +- **`LGDT`**: Loads the GDT register with the address of the GDT. +- **GDT**: Defines memory segments; in long mode, segmentation is largely unused but a minimal GDT is still required. + +The GDT is defined in the `.rodata` section: + +```assembly +SECTION .rodata +gdt64: + dq 0 ; null descriptor +.code_segment: EQU $ - gdt64 + dq (1 << 43) | (1 << 44) | (1 << 47) | (1 << 53) ; code segment descriptor +.pointer: + dw $ - gdt64 - 1 ; size of GDT + dq gdt64 ; address of GDT +``` + +- **Code Segment Descriptor**: Configured for 64-bit code execution. +- **`EQU`**: Assembler directive to define constants. + +## 6. Enabling Paging + +Enables paging and prepares the CPU for long mode: + +```assembly +; Load the page table address into CR3 +MOV eax, page_table_l4 +MOV cr3, eax + +; Enable Physical Address Extension (PAE) +MOV eax, cr4 +OR eax, 1 << 5 +MOV cr4, eax + +; Enable Long Mode +MOV ecx, 0xC0000080 +RDMSR ; Read from the Model Specific Register +OR eax, 1 << 8 +WRMSR ; Write back to the MSR + +; Enable paging +MOV eax, cr0 +OR eax, 1 << 31 +MOV cr0, eax +``` + +- **`CR3`**: Control register that holds the address of the page table. +- **PAE (Physical Address Extension)**: Allows 32-bit processors to access more than 4GB of memory. +- **`CR4`**: Used to enable PAE. +- **`RDMSR`/`WRMSR`**: Read and write Model Specific Registers; used here to enable Long Mode. +- **`CR0`**: Control register used to enable paging. + +## 7. Error Handling + +Handles errors encountered during the boot process: + +```assembly +error: + ; Display "ERR: X" where X is the error code + MOV dword [0xB8000], 0x4F524F45 + MOV dword [0xB8004], 0x4F3A4F52 + MOV dword [0xB8008], 0x4F204F20 + MOV byte [0xB800C], al + HLT +``` + +- **VGA Text Mode Memory (`0xB8000`)**: Used to display text on the screen. +- **Error Codes**: The error code stored in `AL` is displayed. +- **`HLT`**: Halts the CPU. + +## Conclusion + +The bootloader meticulously prepares the system for 64-bit operation by performing hardware checks and setting up crucial structures like the stack, page tables, and GDT. It enables paging and long mode before transferring control to the operating system. diff --git a/docs/bootloader/header.md b/docs/bootloader/header.md new file mode 100644 index 00000000..f0ab9422 --- /dev/null +++ b/docs/bootloader/header.md @@ -0,0 +1,39 @@ +# Assembly Code Documentation + +## Introduction +This section of assembly code is designed to perform a specific set of operations at the hardware level. Assembly language is a low-level programming language that is closely related to machine code. It allows programmers to write instructions that the CPU can execute directly. Understanding this code requires a basic knowledge of CPU registers, memory addressing, and instruction sets. + +## Functionality Breakdown + +### 1. Initialization +The code begins by initializing certain registers. Registers are small storage locations within the CPU that hold data temporarily. They are used to perform arithmetic, logic, control, and input/output operations. + +### 2. Data Movement +The code moves data between registers and memory. This is crucial because the CPU can only perform operations on data that is in its registers. Moving data from memory to registers and vice versa is a common task in assembly programming. + +### 3. Arithmetic and Logic Operations +The code performs arithmetic and logic operations using the data in the registers. These operations include addition, subtraction, multiplication, division, and logical operations like AND, OR, and XOR. Each operation is performed using specific instructions that the CPU understands. + +### 4. Control Flow +The code includes instructions that control the flow of execution. This includes jumps, loops, and conditional statements. These instructions allow the program to make decisions and repeat certain operations based on specific conditions. + +### 5. Input/Output Operations +The code may include instructions to perform input/output operations. This involves reading data from input devices (like a keyboard) and writing data to output devices (like a screen). These operations are essential for interacting with the user and other hardware components. + +## Detailed Explanation + +### Register Usage +- **General Purpose Registers (e.g., EAX, EBX, ECX, EDX)**: These registers are used for a variety of operations, including arithmetic and logic operations. They are versatile and can be used to hold temporary data, counters, and addresses. +- **Index and Pointer Registers (e.g., ESI, EDI, ESP, EBP)**: These registers are used for indexing and pointing to memory locations. They are essential for accessing arrays, stacks, and other data structures in memory. +- **Segment Registers (e.g., CS, DS, SS, ES)**: These registers hold the addresses of different segments in memory. They are used to access code, data, stack, and extra segments. + +### Why Each Register is Used +- **EAX**: Often used as an accumulator for arithmetic operations. It is the default register for many instructions. +- **EBX**: Used as a base register for addressing memory. It can hold the base address of data structures. +- **ECX**: Commonly used as a counter in loop operations. It is the default register for loop instructions. +- **EDX**: Used for I/O operations and as an extension of EAX for certain arithmetic operations. +- **ESI and EDI**: Used for string operations and memory copying. They hold source and destination addresses, respectively. +- **ESP and EBP**: Used for stack operations. ESP points to the top of the stack, while EBP is used to access function parameters and local variables. + +### Conclusion +This assembly code section demonstrates the fundamental operations performed by the CPU, including data movement, arithmetic and logic operations, control flow, and input/output operations. Each register is used in a specific way to optimize the performance and efficiency of the code. Understanding the purpose and usage of each register is crucial for writing and debugging assembly code effectively. \ No newline at end of file diff --git a/docs/ci-github-actions/README.md b/docs/ci-github-actions/README.md new file mode 100644 index 00000000..78544b22 --- /dev/null +++ b/docs/ci-github-actions/README.md @@ -0,0 +1,15 @@ +# Continuous Integration (CI) Automation + +Continuous Integration (CI) automation is essential for maintaining a stable and reliable codebase. By automating the testing and release processes, we ensure that every change is thoroughly tested before being merged, and that new releases are created seamlessly when pull requests are merged. This helps in catching bugs early, maintaining code quality, and speeding up the development process. + +## Release Workflow + +The release workflow is triggered when a pull request is merged into the main branch. It automatically determines the new version based on the pull request title, creates a new release, and uploads the build artifacts. This ensures that every change is properly versioned and released without manual intervention. + +[Read more about the release workflow](release.md) + +## Test Workflow + +The test workflow runs on every push and pull request to the main branch. It installs necessary dependencies and runs the project's tests to ensure that new changes do not break existing functionality. This is crucial for maintaining a stable codebase and preventing regressions. + +[Read more about the test workflow](test.md) \ No newline at end of file diff --git a/docs/ci-github-actions/release.md b/docs/ci-github-actions/release.md new file mode 100644 index 00000000..4966a8c0 --- /dev/null +++ b/docs/ci-github-actions/release.md @@ -0,0 +1,256 @@ +# Release Workflow Documentation + +This document provides a comprehensive overview of the GitHub Actions workflow defined in `release.yaml`. The workflow is designed to automate the release process of the AnasOS project. It triggers on pull requests merged into the `main` branch, determines the appropriate version increment based on the pull request title, creates a new release, and builds the project packages. + +## Workflow Overview + +The release workflow is triggered when a pull request is closed and merged into the `main` branch. It performs the following key steps: + +1. Checks out the repository. +2. Fetches the tags to determine the highest release version. +3. Determines the version increment based on the pull request title. +4. Creates a new release with the incremented version. +5. Builds the project packages. +6. Uploads the build artifacts to the release. + +## Detailed Breakdown + +### Triggering the Workflow + +```yaml +on: + pull_request: + branches: ["main"] + types: [closed] +``` + +The workflow is triggered when a pull request targeting the `main` branch is closed. + +### Permissions + +```yaml +permissions: + contents: write + pull-requests: read +``` + +The workflow requires write access to the repository contents and read access to pull requests. + +### Create Release Job + +#### Job Conditions + +```yaml +if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'main' +``` + +The `create-release` job runs only if the pull request is merged into the `main` branch. + +#### Steps + +1. **Checkout Repository** + +```yaml +- name: Checkout with GitHub + uses: actions/checkout@v3 +``` + +Checks out the repository to the runner. + +2. **Fetch Tags** + +```yaml +- name: Fetch tags + run: git fetch --prune --unshallow --tags +``` + +Fetches all tags to determine the highest release version. + +3. **Get Highest Release Version** + +```yaml +- name: Get highest release version + id: get_version + run: | + version=$(git tag --list 'v*' | sort -V | tail -n 1 || echo "v0.0.0") + echo "TAG=$version" >> $GITHUB_ENV + echo "Highest version is $version" +``` + +Determines the highest release version tag. + +4. **Determine Version Increment** + +```yaml +- name: Determine version increment + id: determine_increment + run: | + major=$(echo "$TAG" | cut -d '.' -f1 | sed 's/v//') + minor=$(echo "$TAG" | cut -d '.' -f2) + patch=$(echo "$TAG" | cut -d '.' -f3) + + pr_title="${{ github.event.pull_request.title }}" + if [[ "$pr_title" == *"[Major]"* ]]; then + major=$((major + 1)) + minor=0 + patch=0 + elif [[ "$pr_title" == *"[Minor]"* ]]; then + minor=$((minor + 1)) + patch=0 + elif [[ "$pr_title" == *"[Patch]"* ]]; then + patch=$((patch + 1)) + else + minor=$((minor + 1)) + patch=0 + fi + + TAG="v$major.$minor.$patch" + echo "TAG=$TAG" >> $GITHUB_ENV +``` + +Determines the new version based on the pull request title. The version increment follows these rules: + +- If the title contains `[Major]`, the major version is incremented, and the minor and patch versions are reset to 0. +- If the title contains `[Minor]`, the minor version is incremented, and the patch version is reset to 0. +- If the title contains `[Patch]`, the patch version is incremented. +- If none of these keywords are present, the minor version is incremented, and the patch version is reset to 0. + +5. **Create Release** + +```yaml +- name: Create Release + id: release-action + uses: ncipollo/release-action@v1 + with: + tag: ${{ env.TAG }} + name: Release ${{ env.TAG }} + commit: ${{ github.sha }} + body: ${{ github.event.pull_request.body }} +``` + +Creates a new release with the determined version. + +6. **Output Release URL File** + +```yaml +- name: Output Release URL File + run: | + echo "${{ steps.release-action.outputs.upload_url }}" > release_url.txt +``` + +Writes the release URL to a file for future use. + +7. **Save Release URL File for Publish** + +```yaml +- name: Save Release URL File for publish + uses: actions/upload-artifact@v4 + with: + name: release_url + path: release_url.txt +``` + +Saves the release URL file as an artifact. + +### Build Job + +#### Job Dependencies + +```yaml +needs: create-release +``` + +The `build` job depends on the successful completion of the `create-release` job. + +#### Steps + +1. **Checkout Repository** + +```yaml +- name: Checkout with GitHub + uses: actions/checkout@v4 +``` + +Checks out the repository to the runner. + +2. **Install Dependencies** + +```yaml +- name: Install additional dependencies + run: | + sudo apt update + sudo apt install -y nasm grub-pc-bin grub-common make mtools xorriso + rustup update nightly + rustup target add x86_64-unknown-none --toolchain nightly + rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu +``` + +Installs necessary dependencies for building the project. + +3. **Build Project** + +```yaml +- name: Build project + run: make no-run +``` + +Builds the project using the `make` command with the `no-run` argument, which generates the image file to be included in the release. + +4. **Archive Build Output** + +```yaml +- name: Archive build output + run: | + zip -r AnasOS.iso.zip AnasOS.iso +``` + +This step archives the build output into a zip file. Although the build output is a single ISO file, archiving it has several benefits: + +- **Compression**: Reduces the file size, which can save storage space and reduce upload/download times. +- **Compatibility**: Some systems and tools handle zip files more gracefully than raw ISO files. +- **Convenience**: Packaging the file in a zip format can make it easier for users to manage and extract the contents if needed. + +5. **Load Release URL File** + +```yaml +- name: Load Release URL File from release job + id: download_release_info + uses: actions/download-artifact@v4 + with: + name: release_url +``` + +Downloads the release URL file from the `create-release` job. + +6. **Get Release File Name & Upload URL** + +```yaml +- name: Get Release File Name & Upload URL + id: get_release_info + shell: bash + run: | + value=`cat "${{steps.download_release_info.outputs.download-path}}/release_url.txt"` + echo ::set-output name=upload_url::$value +``` + +Extracts the release upload URL from the file. + +7. **Upload Release Asset** + +```yaml +- name: Upload Release Asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.get_release_info.outputs.upload_url }} + asset_path: AnasOS.iso.zip + asset_name: AnasOS.iso.zip + asset_content_type: application/zip +``` + +Uploads the build artifact to the release. + +## Conclusion + +The release workflow for the AnasOS project automates the process of creating a new release and building the project packages. By leveraging GitHub Actions, the workflow ensures that every pull request merged into the `main` branch triggers a series of steps to determine the new version, create a release, and upload the build artifacts. This automation not only saves time but also reduces the potential for human error, ensuring a consistent and reliable release process. diff --git a/docs/ci-github-actions/test.md b/docs/ci-github-actions/test.md new file mode 100644 index 00000000..a4ed2aa7 --- /dev/null +++ b/docs/ci-github-actions/test.md @@ -0,0 +1,64 @@ +# GitHub Actions Workflow Documentation + +This document provides a detailed explanation of the GitHub Actions workflow defined in the `test.yaml` file. The workflow is designed to automate the testing process for the AnasOS kernel project. It triggers on pushes and pull requests to the `main` branch, installs necessary dependencies, and runs the tests to ensure the integrity of the codebase. + +## Workflow Overview + +The workflow is named "Tests" and is triggered by two events: +- A push to the `main` branch. +- A pull request targeting the `main` branch. + +When triggered, the workflow runs a series of steps on an `ubuntu-latest` runner to set up the environment, install dependencies, and execute the tests. + +## Detailed Breakdown + +### `name: Tests` + +This specifies the name of the workflow. + +### `on` + +Defines the events that trigger the workflow: +- `push`: Triggers the workflow when there is a push to the `main` branch. +- `pull_request`: Triggers the workflow when a pull request is opened, synchronized, or reopened targeting the `main` branch. + +### `jobs` + +Defines the jobs that will be run as part of the workflow. In this case, there is a single job named `build`. + +#### `build` + +This job runs on the `ubuntu-latest` virtual environment. + +##### `steps` + +The steps define the sequence of actions to be performed in the `build` job. + +1. **Checkout the repository** +```yaml +- uses: actions/checkout@v4 +``` +This step uses the `actions/checkout` action to clone the repository to the runner. + +2. **Install additional dependencies** +```yaml +- name: Install additional dependencies + run: | + sudo apt update + sudo apt install -y nasm grub-pc-bin grub-common make mtools xorriso + rustup update nightly + rustup target add x86_64-unknown-none --toolchain nightly + rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu +``` +This step installs the necessary dependencies for building and testing the AnasOS kernel. It updates the package list, installs various tools such as `nasm`, `grub-pc-bin`, `grub-common`, `make`, `mtools`, and `xorriso`. It also updates Rust to the nightly version, adds the `x86_64-unknown-none` target, and installs the Rust source component. + +3. **Run Tests** +```yaml +- name: Run Tests + run: make test +``` +This step runs the tests using the `make test` command to ensure that the codebase is functioning correctly. + +## Conclusion + +The GitHub Actions workflow described in this document provides an automated and efficient way to test the AnasOS kernel project. By triggering on pushes and pull requests to the `main` branch, it ensures that any changes to the codebase are thoroughly tested. The workflow sets up the necessary environment, installs dependencies, and runs tests, helping to maintain the integrity and stability of the project. This automation not only saves time but also enhances the reliability of the development process. \ No newline at end of file diff --git a/docs/kernel/README.md b/docs/kernel/README.md new file mode 100644 index 00000000..79403b56 --- /dev/null +++ b/docs/kernel/README.md @@ -0,0 +1,20 @@ +# AnasOS Kernel + +Welcome to the AnasOS Kernel documentation. This kernel is written in Rust and is designed as a thesis project. + +## Overview + +The AnasOS Kernel is currently in development and includes the following features: +- VGA text mode support (see [vga.md](vga.md) for more in-depth documentation) +- A `build.rs` script to bundle the kernel with the bootloader + +## Upcoming Features + +I am actively working on adding support for: +- Programmable Interrupt Timer (PIT) +- I/O interrupts +- PS/2 keyboard driver + +## Building the Kernel + +To build the kernel, you will need to have Rust installed on your system. You can then use the following commands to build and run the kernel: diff --git a/docs/kernel/vga.md b/docs/kernel/vga.md new file mode 100644 index 00000000..4b6b66f5 --- /dev/null +++ b/docs/kernel/vga.md @@ -0,0 +1,142 @@ +# VGA Module Documentation + +## Introduction + +The VGA module in the AnasOS kernel is responsible for handling text output to the screen using the VGA text buffer. This module provides functionality to write characters and strings to the screen, manage colors, and handle special characters like newlines and tabs. The implementation leverages Rust's safety features and abstractions to ensure reliable and efficient text output. + +This module was created by following [this tutorial](https://os.phil-opp.com/vga-text-mode/). + +## Implementation Details + +### Color Enum + +The `Color` enum defines the various colors that can be used for text and background in the VGA buffer. Each color is represented by a unique 4-bit value. + +```rust +#[allow(dead_code)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u8)] +pub enum Color { + Black = 0, + Blue = 1, + Green = 2, + Cyan = 3, + Red = 4, + Magenta = 5, + Brown = 6, + LightGray = 7, + DarkGray = 8, + LightBlue = 9, + LightGreen = 10, + LightCyan = 11, + LightRed = 12, + White = 15 +} +``` + +### ColorCode Struct + +The `ColorCode` struct encapsulates the foreground and background colors, as well as additional attributes like blinking. It provides methods to create new color codes and retrieve the individual colors. + +```rust +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(transparent)] +pub struct ColorCode(u8); + +impl ColorCode { + pub fn new(foreground: Color, background: Color) -> ColorCode { + ColorCode((background as u8) << 4 | (foreground as u8)) + } +} +``` + +### ScreenChar Struct + +The `ScreenChar` struct represents a single character on the screen, including its ASCII value and color code. It provides methods to create new screen characters and blank characters. + +```rust +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(C)] +pub struct ScreenChar { + ascii_character: u8, + color_code: ColorCode, +} + +impl ScreenChar { + pub fn new(ascii_character: u8, color_code: ColorCode) -> ScreenChar { + ScreenChar { + ascii_character, + color_code, + } + } +} +``` + +### Buffer Struct + +The `Buffer` struct represents the VGA text buffer, which is a 2D array of `ScreenChar` instances. It uses the `Volatile` wrapper to prevent the compiler from optimizing away memory accesses. + +```rust +use volatile::Volatile; + +#[repr(transparent)] +pub struct Buffer { + chars: [[Volatile; BUFFER_WIDTH]; BUFFER_HEIGHT], +} +``` + +### Writer Struct + +The `Writer` struct is responsible for writing characters and strings to the VGA buffer. It maintains the current cursor position and color code. The `Writer` provides methods to write bytes, handle special characters, scroll the screen, and clear rows. + +```rust +pub struct Writer { + column_position: usize, + color_code: ColorCode, + buffer: &'static mut Buffer, +} + +impl Writer { + pub fn write_byte(&mut self, byte: u8) { + match byte { + b'\n' => self.new_line(), + byte => { + if self.column_position >= BUFFER_WIDTH { + self.new_line(); + } + + let row = BUFFER_HEIGHT - 1; + let col = self.column_position; + + let color_code = self.color_code; + self.buffer.chars[row][col].write(ScreenChar { + ascii_character: byte, + color_code, + }); + self.column_position += 1; + } + } + } +} +``` + +### Macros + +The `print!` and `println!` macros provide convenient ways to write formatted strings to the VGA buffer. They use the `format_args!` macro from the core library to handle formatting. + +```rust +#[macro_export] +macro_rules! print { + ($($arg:tt)*) => ($crate::vga::_print(format_args!($($arg)*))); +} + +#[macro_export] +macro_rules! println { + () => ($crate::print!("\n")); + ($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*))); +} +``` + +## Conclusion + +The VGA module is a crucial component of the AnasOS kernel, enabling text output to the screen. By leveraging Rust's safety features and abstractions, the module ensures reliable and efficient text handling. The provided enums, structs, and macros make it easy to manage colors, write text, and handle special characters, contributing to a robust and user-friendly kernel. diff --git a/docs/multiboot/README.md b/docs/multiboot/README.md new file mode 100644 index 00000000..0e7779ec --- /dev/null +++ b/docs/multiboot/README.md @@ -0,0 +1,45 @@ +# Multiboot Configuration for AnasOS + +This document explains the Multiboot configuration file used to boot AnasOS. + +## Introduction + +The [Multiboot specification](https://en.wikipedia.org/wiki/Multiboot_specification) is an open standard that defines how bootloaders can load x86 operating system kernels. This standard ensures compatibility between bootloaders and operating system kernels, simplifying the boot process. By adhering to the Multiboot specification, developers can create and maintain operating systems more efficiently. + +## Why Choose Multiboot Over Custom Bootloaders? + +Opting for Multiboot instead of developing a custom bootloader offers several benefits: +- **Standardization**: Multiboot provides a consistent interface for bootloaders and kernels, reducing development complexity. +- **Flexibility**: It supports various filesystems and kernel formats, making it adaptable to different environments. +- **Community Support**: Widely used and well-documented, Multiboot offers extensive resources and community assistance. + +## Multiboot1 vs Multiboot2 + +[Multiboot2](https://en.wikipedia.org/wiki/Multiboot_specification) is an enhanced version of the original Multiboot specification (Multiboot1). Key improvements include: +- **Extended Information**: Provides detailed information about the boot environment, such as memory maps and boot modules. +- **64-bit Support**: Designed to support 64-bit long mode, essential for modern 64-bit operating systems like AnasOS. +- **Modularity**: Allows for more modular and flexible boot configurations. + +## GRUB Multiboot2 Setup + +AnasOS uses GRUB Multiboot2 for booting. The GRUB configuration file is located at `AnasOS/boot/grub/grub.cfg`. + +- `set timeout=5` + - Sets the boot menu timeout to 5 seconds. + +- `menuentry "AnasOS" {` + - Defines a menu entry named "AnasOS". + +- `multiboot2 /boot/kernel` + - Specifies the kernel file path to be loaded using Multiboot2. + +- `boot` + - Instructs the bootloader to boot the selected operating system. + +## Multiboot Magic Number + +The Multiboot2 specification uses a unique "magic number" (0x36d76289) to identify Multiboot-compliant kernels. This magic number is checked by the bootloader to ensure compatibility. In AnasOS, the bootloader incorporates this check to verify that the kernel adheres to the Multiboot2 standard, ensuring a smooth and standardized boot process. + +## References + +- [Multiboot Specification](https://en.wikipedia.org/wiki/Multiboot_specification) diff --git a/docs/window-manager/README.md b/docs/window-manager/README.md new file mode 100644 index 00000000..6f18eb68 --- /dev/null +++ b/docs/window-manager/README.md @@ -0,0 +1,3 @@ +# Window Manager + +Coming soon. Not yet implemented. \ No newline at end of file