### Building QEMU Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/E_Cross_Compilers.md Build QEMU using 'make -j $(nproc)' to leverage all available CPU cores for faster compilation. Follow with 'make install' to install the emulator. ```bash make -j $(nproc) make install ``` -------------------------------- ### Build and Install Binutils Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/E_Cross_Compilers.md Builds and installs the configured Binutils tools. These commands are typically run after the configure script has successfully completed. ```bash make make install ``` -------------------------------- ### Starting a Virtual Machine with VirtualBox Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/F_Debugging.md Launch a virtual machine from the command line using its name or UUID. ```bash virtualboxvm --startvm vmname ``` -------------------------------- ### Building and Installing GDB Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/E_Cross_Compilers.md Build and install the custom GDB configuration using 'make all-gdb' and 'make install-gdb'. This process is similar to building other GNU toolchain components. ```bash make all-gdb make install-gdb ``` -------------------------------- ### Install Limine for BIOS Booting Source: https://github.com/dreamportdev/osdev-notes/blob/master/01_Build_Process/05_Generating_Iso.md Installs the Limine bootloader onto an existing ISO image to enable BIOS booting. This command is run from within the cloned Limine directory. ```bash ./limine/limine bios-install my_iso.iso ``` -------------------------------- ### Build and Install GCC Components Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/E_Cross_Compilers.md Builds and installs specific GCC components required for a freestanding environment, namely the compiler and libgcc. This avoids building unnecessary parts of GCC. ```bash make all-gcc make all-target-libgcc make install-gcc make install-target-libgcc ``` -------------------------------- ### Limine Configuration for Stivale 2 Source: https://github.com/dreamportdev/osdev-notes/blob/master/01_Build_Process/05_Generating_Iso.md Example configuration file for the Limine bootloader, specifying boot entries and parameters for booting with the Stivale 2 protocol. ```toml ``` -------------------------------- ### Virtual Address Translation Example (3-Level Paging) Source: https://github.com/dreamportdev/osdev-notes/blob/master/04_Memory_Management/03_Paging.md Demonstrates how a 32-bit virtual address is broken down into components for address translation in a hypothetical 3-level paging system. This example shows offset, page table entry, and page directory entries. ```c virtaddress = 0x2F880120 ``` -------------------------------- ### Create ISO with Limine (UEFI) Source: https://github.com/dreamportdev/osdev-notes/blob/master/01_Build_Process/05_Generating_Iso.md Utilizes xorriso to construct a bootable ISO image with Limine, suitable for UEFI booting. Requires specific flags for bootloader and EFI partition setup. ```bash xorriso -as mkisofs -b limine-cd.bin -no-emul-boot \ -boot-load-size 4 -boot-info-table --efi-boot \ limine-cd-efi.bin -efi-boot-part --efi-boot-image \ --protective-msdos-label disk -o my_iso.iso ``` -------------------------------- ### Heap Traversal Example Source: https://github.com/dreamportdev/osdev-notes/blob/master/04_Memory_Management/05_Heap_Allocation.md This C code snippet illustrates how to iterate through allocated memory blocks on the heap, given a starting pointer and the current heap position. It prints the size and address of each allocated block. ```c uint8_t *cur_pointer = start_pointer; while(cur_pointer < cur_heap_pointer) { printf("Allocated address: size: %d - 0x%x\n", *cur_pointer, cur_pointer+1); cur_pointer = cur_pointer + (*cur_pointer) + 1; } ``` -------------------------------- ### Create Mountpoint Data Structure Source: https://github.com/dreamportdev/osdev-notes/blob/master/08_VirtualFileSystem/02_VirtualFileSystem.md Example code demonstrating the creation and initialization of a mountpoint data structure within the VFS. Assumes a `malloc` equivalent is available. ```c mountpoint_t *new_mountpoint = malloc(sizeof(mountpoint_t)); // We assume a kind of malloc is present if(new_mountpoint == NULL) return -1; strcpy(new_mountpoint->device, device); strcpy(new_mountpoint->type, type); strcpy(new_mountpoint->mountpoint, target); new_mountpoint->operations = NULL; ``` -------------------------------- ### C Code Example for Watchpoint Demonstration Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/F_Debugging.md This C code snippet demonstrates a scenario where a watchpoint can be used to monitor changes in a global variable. ```c int myVar2 = 3; int test_function() { int myVar = 0; myVar = 5; myVar2 = myVar return myVar; } ``` -------------------------------- ### Setting Initial VMA with Dot Operator Source: https://github.com/dreamportdev/osdev-notes/blob/master/01_Build_Process/04_Linker_Scripts.md Sets the starting Virtual Memory Address (VMA) for sections using the dot operator. This example places sections at the upper 2GB of the 64-bit address space. ```linker-script SECTIONS { . = 0xFFFFFFFF80000000; /* section descriptions go here */ } ``` -------------------------------- ### Example Allocation Request Source: https://github.com/dreamportdev/osdev-notes/blob/master/04_Memory_Management/05_Heap_Allocation.md Demonstrates a scenario where a small allocation request is made from a larger free memory block, illustrating potential memory waste. ```c alloc(10); ``` -------------------------------- ### Macro Expansion Example in NASM Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/D_Nasm.md Illustrates how a macro call is expanded by the NASM preprocessor into actual assembly instructions and labels. ```nasm my_first_macro_label_42: push ebp mov ebp, esp sub esp 42 ``` -------------------------------- ### Virtual to Physical Address Mapping Example Source: https://github.com/dreamportdev/osdev-notes/blob/master/04_Memory_Management/03_Paging.md Illustrates a conceptual mapping between a virtual address and a physical address. This is a simplified representation. ```c phys(0x123'456) = virt(0xFFF'F234'5235) ``` -------------------------------- ### Start VirtualBox VM with Debugger Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/F_Debugging.md Launch a VirtualBox virtual machine with the `--debug` option to enable the debugger. Ensure VBOX_GUI_DBG_ENABLED or VBOX_GUI_DBG_AUTO_SHOW is set to true. ```bash virtualboxvm --startvm vmname --debug ``` -------------------------------- ### Initialize Heap with a Single Node Source: https://github.com/dreamportdev/osdev-notes/blob/master/04_Memory_Management/05_Heap_Allocation.md Sets up the initial heap structure with a starting node. This function defines the initial memory block and its status as free. ```c Heap_Node *heap_start; Heap_Node *heap_end; void initialize_heap() { heap_start = INITIAL_HEAP_ADDRESS //Remember is a virtual address; heap_start->prev = NULL; heap_start->next = NULL; // Just make sure that prev and next are not going anywhere heap_start->status = FREE; heap_start->size = INITIAL_HEAP_SIZE // 8096 = 8k; heap_end = heap_start } ``` -------------------------------- ### QEMU Monitor via Unix Socket Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/F_Debugging.md Start QEMU with the `-monitor unix:qemu-monitor-socket,server,nowait` parameter to enable the monitor via a Unix socket. Connect using socat. ```bash qemu-system-i386 [..other params..] -monitor unix:qemu-monitor-socket,server,nowait ``` ```bash socat -,echo=0,icanon=0 unix-connect:qemu-monitor-socket ``` -------------------------------- ### Configuring QEMU for Emulation Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/E_Cross_Compilers.md Configure QEMU with a target list to specify supported platforms and enable features like the GTK UI and host utilities. Ensure necessary build dependencies are installed. ```bash /path/qemu_src/configure --prefix=$PREFIX --target-list=riscv64-softmmu,x86_64-softmmu --enable-gtk --enable-gtk-clipboard --enable-tools --enable-vhost-net ``` -------------------------------- ### GDB: Examine Memory as Instructions Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/F_Debugging.md Display memory content starting from a given address, formatted as CPU instructions. ```gdb x/10i 0x1234 ``` -------------------------------- ### USTAR File System Operations Source: https://github.com/dreamportdev/osdev-notes/blob/master/08_VirtualFileSystem/02_VirtualFileSystem.md These are example function signatures for basic operations on a USTAR file system. They are assumed to be implemented for VFS integration. ```c int ustar_open(char *path, int flags); int ustar_close(int ustar_fd); void ustar_read(int ustar_fd, void *buffer, size_t count); int ustar_close(int ustar_fd); ``` -------------------------------- ### Instantiate Macro with Argument in NASM Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/D_Nasm.md Example of calling a NASM macro with a specific argument. This call will generate a global label and execute the macro's body. ```nasm my_first_macro 42 ``` -------------------------------- ### VFS Open Function Pseudocode Source: https://github.com/dreamportdev/osdev-notes/blob/master/08_VirtualFileSystem/02_VirtualFileSystem.md Pseudocode illustrating the VFS open function logic, including getting the mountpoint, relative path, calling the FS driver's open function, and registering the resource. ```c int open(const char *path, int flags){ mountpoint_t *mountpoint = get_mountpoint(pathname); if (mountpoint != NULL) { char *rel_path = get_rel_path(mountpoint, path); int fs_specific_id = mountpoint->operations->open(rel_path, flags); if (fs_specific_id != ERROR) { /* IMPLEMENTATION LEFT AS EXERCISE */ // Get a new vfs descriptor id vfs_id vfs_opened_files[vfs_id] = //fill the file descriptor entry at position resource_t *res = // left as an exercise, see below // Open the resource and return its id to the calling process int handle = register_resource(current_process, res); return handle; } } return ERROR; } ``` -------------------------------- ### Initialize Keyboard Driver and State Source: https://github.com/dreamportdev/osdev-notes/blob/master/02_Architecture/11_Keyboard_Driver_Implementation.md Initializes the keyboard driver by setting the current state to NORMAL_STATE. This function should also include other necessary setup like clearing the input buffer and enabling interrupts. ```c #define NORMAL_STATE 0 #define PREFIX_STATE 1 uint8_t current_state; void init_keyboard() { // You'll want to do other setup here in your own driver: // ensure the input buffer of the keyboard is empty, check which scancode // set is in use, enable irqs. current_state = NORMAL_STATE; } ``` -------------------------------- ### Populating a struct from a uint64_t register value (Bad Idea) Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/B_Tips_And_Tricks.md This example shows a naive approach to breaking down a 64-bit register value into individual byte fields using bitwise operations. It is less efficient and more verbose than using a union. ```c struct BadIdea { uint8_t a; uint8_t b; uint8_t c; uint8_t d; uint8_t e; uint8_t f; uint8_t g; uint8_t h; }; uint64_t reg = read_register(); BadIdea bi; bi.a = reg & 0xFF; bi.b = (reg >> 8) & 0xFF; bi.c = (reg >> 16) & 0xFF; //T AND is not necessary, but it makes the point. etc... ``` -------------------------------- ### Heap Fragmentation Example Source: https://github.com/dreamportdev/osdev-notes/blob/master/04_Memory_Management/05_Heap_Allocation.md Demonstrates a scenario leading to heap fragmentation where small allocations cannot be satisfied despite available free memory. This illustrates the problem coalescing aims to solve. ```c a = third_alloc(6); b = third_alloc(6); c = third_alloc(6); free(c); free(b); free(a); ``` ```c alloc(7); ``` -------------------------------- ### Using a union to access uint64_t register fields (Good Idea) Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/B_Tips_And_Tricks.md This example demonstrates using a union to access a 64-bit hardware register value either as a single uint64_t or as individual uint8_t fields. This approach simplifies access and can be more efficient. ```c union GoodIdea { //each item inside of union shares the same memory. //using an anonymous struct ensures these fields are treated as 'a single item'. struct { uint8_t a; uint8_t b; uint8_t c; uint8_t d; uint8_t e; uint8_t f; uint8_t g; uint8_t h; }; uint64_t squished; }; GoodIdea gi; gi.squished = read_register(); //now the fields in gi will represent what they would in the register. //assuming a is bits 7:0, b is bits 16:8, etc ... ``` -------------------------------- ### QEMU Monitor Help Prompt Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/F_Debugging.md This is the initial prompt when connecting to the QEMU monitor, indicating that the monitor is active and ready to receive commands. ```text QEMU 6.1.0 monitor - type 'help' for more information (qemu) ``` -------------------------------- ### Get Mountpoint Function Header Source: https://github.com/dreamportdev/osdev-notes/blob/master/08_VirtualFileSystem/02_VirtualFileSystem.md Declares the function signature for retrieving the mountpoint associated with a given path. The function should return NULL on failure, though in a single-root setup, it should always succeed by returning the root mountpoint. ```c mountpoint_t get_mountpoint(char *path); ``` -------------------------------- ### Thread One Logging Example Source: https://github.com/dreamportdev/osdev-notes/blob/master/05_Scheduling/04_Locks.md Example of a thread calling the serial_log function to send its message. ```c void thead_one() { serial_log("I am the first string"); } ``` -------------------------------- ### Thread Two Logging Example Source: https://github.com/dreamportdev/osdev-notes/blob/master/05_Scheduling/04_Locks.md Example of a second thread calling the serial_log function, potentially causing a race condition. ```c void thead_two() { serial_log("while I am the second string"); } ``` -------------------------------- ### Create Binutils Build Directory Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/E_Cross_Compilers.md Creates a directory for building Binutils and navigates into it. This is a preparatory step before configuring the build. ```bash mkdir binutils_build cd binutils_build ``` -------------------------------- ### Declare Limine Requests Start Marker Source: https://github.com/dreamportdev/osdev-notes/blob/master/01_Build_Process/02_Boot_Protocols.md Declares the start marker for Limine requests. This variable must be placed in the .requests_start_marker section and marked as 'used' and 'volatile'. ```c __attribute__((used, section(".requests_start_marker"))) static volatile LIMINE_REQUESTS_START_MARKER; ``` -------------------------------- ### QEMU Monitor via Telnet Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/F_Debugging.md Enable QEMU monitor on a specified port using the `-monitor telnet::45454,server,nowait` parameter. Connect using Telnet. ```bash qemu-system-i386 [..other params..] -monitor telnet::45454,server,nowait ``` ```bash telnet localhost 45454 ``` -------------------------------- ### Connect to QEMU with GDB Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/F_Debugging.md Launch QEMU with the -s and -S flags to enable remote debugging. Then, connect to the QEMU instance using GDB's remote target command. ```bash qemu-system-x86_64 -s -S path/to/your/kernel.bin ``` ```bash target remote localhost:1234 ``` -------------------------------- ### Run Kernel with QEMU Source: https://github.com/dreamportdev/osdev-notes/blob/master/01_Build_Process/01_Overview.md Basic command to run the kernel in QEMU. Ensure the ISO_FILENAME variable is set. ```makefile run: qemu-system-x86_64 -cdrom $(ISO_FILENAME) ``` -------------------------------- ### GDB: Examine Memory as Bytes (Hex) Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/F_Debugging.md Display memory content starting from a given address, formatted as hexadecimal bytes. ```gdb x/10xb 0x1234 ``` -------------------------------- ### GDB: Examine Memory Pointed to by Register Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/F_Debugging.md Display the content of the memory address pointed to by a register. For example, '$rax' holds the address. ```gdb x/h ($rax) ``` -------------------------------- ### Load Stack Segment Register (SS) Source: https://github.com/dreamportdev/osdev-notes/blob/master/02_Architecture/04_GDT.md Loads the SS register with a descriptor from the GDT. The example uses a selector value of 0x10. ```x86asm mov $0x10, %ax mov %ax, %ss ``` -------------------------------- ### Limine Bootloader Configuration Source: https://github.com/dreamportdev/osdev-notes/blob/master/01_Build_Process/05_Generating_Iso.md This configuration file specifies the entry name for the boot menu and the Limine boot protocol. It also defines the path to the kernel executable. ```text # The entry name that will be displayed in the boot menu. /My Operating System # We use the Limine boot protocol. protocol: limine # Path to the kernel to boot. boot():/ represents the partition on which limine.conf is located. kernel_path: boot():/boot/kernel.elf ``` -------------------------------- ### Load Data Segment Register (DS) Source: https://github.com/dreamportdev/osdev-notes/blob/master/02_Architecture/04_GDT.md Loads the DS register with a descriptor from the GDT. The example uses a selector value of 0x8. ```x86asm mov $0x8, %ax mov %ax, %ds ``` -------------------------------- ### Makefile for ISO Generation and Testing with Qemu Source: https://github.com/dreamportdev/osdev-notes/blob/master/01_Build_Process/01_Overview.md This Makefile snippet demonstrates how to define variables for ISO filename and includes a rule to build a bootable ISO using Qemu. It assumes the ISO filename is stored in the ISO_FILENAME variable. ```makefile ISO_FILENAME := $(shell pwd)/default.iso all: $(ISO_FILENAME) $(ISO_FILENAME): kernel.elf @echo "Building ISO..." @qemu-system-x86_64 \ -drive format=raw,file=$(ISO_FILENAME) \ -kernel kernel.elf \ -append "-no-reboot" clean: @echo "Cleaning up..." rm -f $(ISO_FILENAME) ``` -------------------------------- ### Run Kernel with KVM Acceleration Source: https://github.com/dreamportdev/osdev-notes/blob/master/01_Build_Process/01_Overview.md Command to run the kernel in QEMU with KVM acceleration enabled for better performance. Ensure the ISO_FILENAME variable is set. ```makefile run-with-kvm: qemu-system-x86_64 -cdrom $(ISO_FILENAME) --enable-kvm ``` -------------------------------- ### Multiboot2 Tar Module Tag Structure Source: https://github.com/dreamportdev/osdev-notes/blob/master/08_VirtualFileSystem/03_TarFileSystem.md This is the structure of the Multiboot2 tag that provides information about loaded modules, including their start and end addresses. ```assembly +-------------------+ u32 | type = 3 | u32 | size | u32 | mod_start | u32 | mod_end | u8[n] | string | +-------------------+ ``` -------------------------------- ### Generate ISO with Grub Source: https://github.com/dreamportdev/osdev-notes/blob/master/01_Build_Process/05_Generating_Iso.md Uses grub-mkrescue to create a bootable ISO image from a specified directory containing bootloader files and the kernel. ```bash grub-mkrescue -o my_iso.iso disk ``` -------------------------------- ### Setting a Modifier Key Bit Source: https://github.com/dreamportdev/osdev-notes/blob/master/02_Architecture/11_Keyboard_Driver_Implementation.md Example of updating the current modifier state when a control key is pressed. Uses bitwise OR to set the corresponding bit. ```c current_modifiers |= 1 << CTRL_MASK; ``` -------------------------------- ### Using Immediate Values in Assembly Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/C_Language_Info.md Demonstrates how to use an immediate value (a constant) within an inline assembly instruction by prefixing it with a '$'. ```C asm("movl $5, %rcx;"); ``` -------------------------------- ### Calculating First Glyph Address Source: https://github.com/dreamportdev/osdev-notes/blob/master/03_Video_Output/02_DrawingTextOnFB.md Calculates the memory address of the first glyph in the PSF font. It adds the header size to the start of the font data. ```C uint8_t* first_glyph = (uint8_t*) &_binary_font_psf_start + default_font->headersize; ``` -------------------------------- ### Listing Virtual Machines with VBoxManage Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/F_Debugging.md View a list of all available virtual machines managed by VirtualBox, including their labels and UUIDs. ```bash vboxmanage list vms ``` -------------------------------- ### Create New Process in C Source: https://github.com/dreamportdev/osdev-notes/blob/master/05_Scheduling/03_Processes_And_Threads.md Allocates memory for a new process, initializes its properties including PID, status, and execution context, and adds it to the process list. Error handling and interrupt disabling are omitted for brevity. ```c size_t next_free_pid = 0; process_t* create_process(char* name, void(*function)(void*), void* arg) { process_t* process = alloc(sizeof(process_t)); strncpy(process->name, name, NAME_MAX_LEN); process->pid = next_free_free_pid++; process->process_status = READY; process->context.iret_ss = KERNEL_DS; // from the GDT chapter process->context.iret_rsp = alloc_stack(); process->context.iret_flags = 0x202; process->context.iret_cs = KERNEL_CS; // from the GDT chapter process->context.iret_rip = (uint64_t)function; process->context.rdi = (uint64_t)arg; process->context.rbp = 0; add_process(process); return process; } ``` -------------------------------- ### x86 ELF Kernel Linker Script Example Source: https://github.com/dreamportdev/osdev-notes/blob/master/01_Build_Process/04_Linker_Scripts.md This script configures essential sections for an x86 ELF kernel, defines symbols for runtime access to section boundaries, and calculates the total kernel size. It assumes sections can be loaded at their requested Virtual Memory Addresses (VMAs). ```linker-script OUTPUT_FORMAT(elf64-x86-64) ENTRY(kernel_entry_func) PHDRS { /* bare minimum: code, data and rodata phdrs. */ text PT_LOAD FLAGS((1 << 0) | (1 << 2)); rodata PT_LOAD FLAGS((1 << 2)); data PT_LOAD FLAGS((1 << 1) | (1 << 2)); } SECTIONS { /* start linking at the -2GB address. */ . = 0xFFFFFFFF80000000; /* text output section, to go in 'text' phdr */ .text : { /* we can use these symbols to work out where */ /* the .text section ends up at runtime. */ /* Then we can map those pages appropriately. */ TEXT_BEGIN = .; *(.text*) TEXT_END = .; } :text /* a trick to ensure the section next is on the next physical */ /* page so we can use different page protection flags (r/w/x). */ . += CONSTANT(MAXPAGESIZE); .rodata : { RODATA_BEGIN = .; *(.rodata*) RODATA_END = .; } :rodata . += CONSTANT(MAXPAGESIZE); .data : { DATA_BEGIN = .; *(.data*) } :data .bss : { /* COMMON is where the compiler places its internal symbols */ *(COMMON) *(.bss*) DATA_END = .; } :data /* we can use the '.' to determine how large the kernel is. */ KERNEL_SIZE = . - 0xFFFFFFFF80000000; } ``` -------------------------------- ### Boot Stack Base Definition Source: https://github.com/dreamportdev/osdev-notes/blob/master/01_Build_Process/02_Boot_Protocols.md This assembly snippet defines the base address for the boot stack, setting it to 0x1000. This is typically part of the boot shim setup. ```x86asm .section .data boot_stack_base: .byte 0x1000 ``` -------------------------------- ### Assemble an assembly file Source: https://github.com/dreamportdev/osdev-notes/blob/master/09_Loading_Elf/02_Loading_And_Running.md Compile the assembly source into an ELF64 object file with DWARF debug symbols. ```sh nasm -g -f elf64 -F dwarf example_file.s -o example_file.o ``` -------------------------------- ### Read APIC Base Address MSR Source: https://github.com/dreamportdev/osdev-notes/blob/master/02_Architecture/07_APIC.md Reads the IA32_APIC_BASE MSR (0x1B) to get the local APIC's base address. The result is in EAX and EDX. ```Assembly mov ecx, 0x1B rdmsr ; EAX and EDX now contain the APIC base address ``` -------------------------------- ### Opening a File and Assigning Resource ID Source: https://github.com/dreamportdev/osdev-notes/blob/master/05_Scheduling/03_Processes_And_Threads.md Illustrates how a process opens a file, obtains a system-wide ID for it, and then assigns a process-specific resource ID by finding an available slot in the process's resource table. Assumes vfs_open_file is a valid function. ```c size_t open_file(process_t* proc, char* name) { size_t system_id = vfs_open_file(name); for (size_t i = 0; i < MAX_RESOURCE_IDS; i++) { if (proc->resources[i] != 0) continue; proc->resources[i] = system_id; return i; } } ``` -------------------------------- ### Standard C File Opening and Reading Source: https://github.com/dreamportdev/osdev-notes/blob/master/08_VirtualFileSystem/02_VirtualFileSystem.md Demonstrates the typical C standard library approach to opening a file in read-only mode, reading its content into a buffer, and closing the file descriptor. This pattern is abstracted by the VFS layer. ```C int file_descriptor; char *buffer = calloc(11, sizeof(char)); if (buffer == NULL) { return -1; } int file_descriptor = open("/path/to/file/to_open", O_RDONLY); int sz = read(file_descriptor, buffer, 10); buffer[sz] = '\0'; printf("%s", buffer); close(file_descriptor); ``` -------------------------------- ### Clearing a Modifier Key Bit Source: https://github.com/dreamportdev/osdev-notes/blob/master/02_Architecture/11_Keyboard_Driver_Implementation.md Example of updating the current modifier state when a control key is released. Uses bitwise AND with a negated mask to clear the corresponding bit. ```c current_modifiers &= ~(1 << CTRL_MASK); ``` -------------------------------- ### Configure GCC Build Source: https://github.com/dreamportdev/osdev-notes/blob/master/99_Appendices/E_Cross_Compilers.md Configures the GCC build for cross-compilation. This command includes flags to specify target, installation prefix, enabled languages, and to disable host headers. ```bash /path/to/gcc_sources/configure --target=$TARGET --prefix=$PREFIX --disable-nls --enable-languages=c,c++ --without-headers ``` -------------------------------- ### GDT Selector Macros Source: https://github.com/dreamportdev/osdev-notes/blob/master/02_Architecture/04_GDT.md Define macros for common GDT selectors used in a 64-bit long mode setup. These are essential for referencing kernel and user space segments. ```c #define NULL_SELECTOR 0x00 #define KERNEL_CS 0x08 #define KERNEL_DS 0x10 #define USER_CS 0x18 #define USER_DS 0x20 ``` -------------------------------- ### Link the assembly object Source: https://github.com/dreamportdev/osdev-notes/blob/master/09_Loading_Elf/02_Loading_And_Running.md Link the object file into an executable, specifying the entry point symbol. ```sh ld -g example_file.o -o example_file.elf -e loop ``` -------------------------------- ### Configure GRUB for Tar Module Source: https://github.com/dreamportdev/osdev-notes/blob/master/08_VirtualFileSystem/03_TarFileSystem.md Update the GRUB menu entry to include the tar file as a module using the `module2` keyword. Ensure the `module2` command follows the `multiboot2` line. ```grub menuentry "My Os" { multiboot2 /boot/kernel.bin // Path to the loader executable module2 /examplefs.tar boot // More modules may be added here // in the form 'module ""' } ``` -------------------------------- ### C Function Signature for Get Mountpoint by ID Source: https://github.com/dreamportdev/osdev-notes/blob/master/08_VirtualFileSystem/02_VirtualFileSystem.md Defines the function signature for retrieving a mountpoint structure using its unique ID. This is a helper function for VFS operations. ```c mountpoint_t *get_mountpoint_by_id(size_t mountpoint_id); ```