From dfd8474b998ef1dc1ee0732ee3fb08b61b3764b7 Mon Sep 17 00:00:00 2001 From: arsenez Date: Tue, 10 Sep 2024 13:15:54 +0300 Subject: [PATCH 01/13] Remove source and build files --- .github/dependabot.yml | 10 - .github/workflows/main.yml | 107 ----- CMakeLists.txt | 33 -- README.md | 49 --- bootloader/CMakeLists.txt | 34 -- bootloader/MBR/CMakeLists.txt | 42 -- bootloader/MBR/mbr.asm | 266 ------------ bootloader/MBR/mbr.ld | 20 - bootloader/SSL/CMakeLists.txt | 74 ---- bootloader/SSL/SSL.ld | 32 -- bootloader/SSL/include/bl/bios.h | 156 ------- bootloader/SSL/include/bl/defines.h | 16 - bootloader/SSL/include/bl/io.h | 70 ---- bootloader/SSL/include/bl/mem.h | 54 --- bootloader/SSL/include/bl/string.h | 50 --- bootloader/SSL/include/bl/types.h | 537 ------------------------ bootloader/SSL/include/bl/utils.h | 151 ------- bootloader/SSL/src/bios.c | 92 ----- bootloader/SSL/src/bootstrap.asm | 58 --- bootloader/SSL/src/gcc_arithmetics64.c | 106 ----- bootloader/SSL/src/io.c | 550 ------------------------- bootloader/SSL/src/mem.c | 309 -------------- bootloader/SSL/src/ssl_entry.c | 293 ------------- bootloader/SSL/src/string.c | 37 -- bootloader/SSL/src/utils.c | 550 ------------------------- bootloader/TSL/CMakeLists.txt | 73 ---- bootloader/TSL/TSL.ld | 32 -- bootloader/TSL/include/bl/defines.h | 12 - bootloader/TSL/include/bl/io.h | 60 --- bootloader/TSL/include/bl/pe.h | 42 -- bootloader/TSL/include/bl/ramfs.h | 37 -- bootloader/TSL/include/bl/string.h | 50 --- bootloader/TSL/include/bl/types.h | 140 ------- bootloader/TSL/include/bl/utils.h | 123 ------ bootloader/TSL/src/bootstrap.asm | 32 -- bootloader/TSL/src/gcc_arithmetics64.c | 106 ----- bootloader/TSL/src/io.c | 524 ----------------------- bootloader/TSL/src/pe.c | 309 -------------- bootloader/TSL/src/ramfs.c | 65 --- bootloader/TSL/src/string.c | 37 -- bootloader/TSL/src/tsl_entry.c | 145 ------- bootloader/TSL/src/utils.c | 231 ----------- cmake/dependencies.cmake | 7 - cmake/flags.cmake | 57 --- cmake/options.cmake | 4 - cmake/toolchain.cmake | 12 - import.cmake | 27 -- 47 files changed, 5821 deletions(-) delete mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/main.yml delete mode 100644 CMakeLists.txt delete mode 100644 README.md delete mode 100644 bootloader/CMakeLists.txt delete mode 100644 bootloader/MBR/CMakeLists.txt delete mode 100644 bootloader/MBR/mbr.asm delete mode 100644 bootloader/MBR/mbr.ld delete mode 100644 bootloader/SSL/CMakeLists.txt delete mode 100644 bootloader/SSL/SSL.ld delete mode 100644 bootloader/SSL/include/bl/bios.h delete mode 100644 bootloader/SSL/include/bl/defines.h delete mode 100644 bootloader/SSL/include/bl/io.h delete mode 100644 bootloader/SSL/include/bl/mem.h delete mode 100644 bootloader/SSL/include/bl/string.h delete mode 100644 bootloader/SSL/include/bl/types.h delete mode 100644 bootloader/SSL/include/bl/utils.h delete mode 100644 bootloader/SSL/src/bios.c delete mode 100644 bootloader/SSL/src/bootstrap.asm delete mode 100644 bootloader/SSL/src/gcc_arithmetics64.c delete mode 100644 bootloader/SSL/src/io.c delete mode 100644 bootloader/SSL/src/mem.c delete mode 100644 bootloader/SSL/src/ssl_entry.c delete mode 100644 bootloader/SSL/src/string.c delete mode 100644 bootloader/SSL/src/utils.c delete mode 100644 bootloader/TSL/CMakeLists.txt delete mode 100644 bootloader/TSL/TSL.ld delete mode 100644 bootloader/TSL/include/bl/defines.h delete mode 100644 bootloader/TSL/include/bl/io.h delete mode 100644 bootloader/TSL/include/bl/pe.h delete mode 100644 bootloader/TSL/include/bl/ramfs.h delete mode 100644 bootloader/TSL/include/bl/string.h delete mode 100644 bootloader/TSL/include/bl/types.h delete mode 100644 bootloader/TSL/include/bl/utils.h delete mode 100644 bootloader/TSL/src/bootstrap.asm delete mode 100644 bootloader/TSL/src/gcc_arithmetics64.c delete mode 100644 bootloader/TSL/src/io.c delete mode 100644 bootloader/TSL/src/pe.c delete mode 100644 bootloader/TSL/src/ramfs.c delete mode 100644 bootloader/TSL/src/string.c delete mode 100644 bootloader/TSL/src/tsl_entry.c delete mode 100644 bootloader/TSL/src/utils.c delete mode 100644 cmake/dependencies.cmake delete mode 100644 cmake/flags.cmake delete mode 100644 cmake/options.cmake delete mode 100644 cmake/toolchain.cmake delete mode 100644 import.cmake diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 327cd5a..0000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,10 +0,0 @@ -version: 2 -updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" - target-branch: "dev" - labels: - - "workflow" - - "dependencies" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 0697009..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,107 +0,0 @@ -name: Main workflow -on: - push -jobs: - build: - name: Build CMake project - runs-on: ubuntu-latest - env: - SRC_DIR: ${{ github.workspace }}/src - BUILD_DIR: ${{ github.workspace }}/build - INSTALL_DIR: ${{ github.workspace }}/install - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - ref: ${{ github.head_ref }} - path: src - - - name: Install dependencies - uses: arsenez2006/depend@v1.1.1 - with: - cache: true - doxygen: true - nasm: true - - - name: Configure CMake - run: | - mkdir -p ${{ env.BUILD_DIR }} - cmake ${{ env.SRC_DIR }} -B ${{ env.BUILD_DIR }} -DOUTPUT=${{ env.INSTALL_DIR }} -DBUILD_DOCS=ON -DCMAKE_BUILD_TYPE=Release - - - name: Build CMake project - run: | - cmake --build ${{ env.BUILD_DIR }} --config Release - - - name: Create build artifact - uses: actions/upload-artifact@v4 - with: - name: cmake-build - path: ${{ env.INSTALL_DIR }} - - version: - name: Create version - runs-on: ubuntu-latest - permissions: - contents: write - outputs: - tag: ${{ steps.version.outputs.version }} - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - ref: ${{ github.head_ref }} - fetch-depth: 0 - - - name: Run Git Version - id: version - uses: codacy/git-version@2.8.0 - with: - prefix: v - - - name: Create tag - if: ${{ steps.version.outputs.version != steps.version.outputs.previous-version }} - run: | - git tag ${{ steps.version.outputs.version }} - git push origin ${{ steps.version.outputs.version }} - - release: - name: Create release - if: ${{ github.ref_name == 'master' }} - runs-on: ubuntu-latest - env: - CMAKE_ARTIFACT: ${{ github.workspace }}/cmake - needs: - - version - - build - permissions: - contents: write - steps: - - name: Download CMake artifacts - id: cmake - uses: actions/download-artifact@v4 - with: - name: cmake-build - path: ${{ env.CMAKE_ARTIFACT }} - - - name: Format paths - id: paths - env: - CMAKE_ARTIFACT_PATH: ${{ steps.cmake.outputs.download-path }} - CMAKE_ARTIFACTS: ${{ vars.CMAKE_BUILD_RELEASE }} - run: | - while IFS= read -r line || [[ -n $line ]]; do - curr_path=$CMAKE_ARTIFACT_PATH/$line - paths=$paths$curr_path$'\n' - done < <(printf '%s' "$CMAKE_ARTIFACTS") - echo 'full<> $GITHUB_OUTPUT - echo "$paths" >> $GITHUB_OUTPUT - echo 'EOF' >> $GITHUB_OUTPUT - - - name: Create Release - uses: softprops/action-gh-release@v1 - with: - draft: false - prerelease: false - name: ${{ vars.RELEASE_NAME }} ${{ needs.version.outputs.tag }} - tag_name: ${{ needs.version.outputs.tag }} - files: ${{ steps.paths.outputs.full }} diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 4a3b049..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -cmake_minimum_required(VERSION 3.20) - -# Include CMake scripts -include(cmake/options.cmake) -include(cmake/dependencies.cmake) -include(cmake/flags.cmake) -include(cmake/toolchain.cmake) - -project(VolgaBL - DESCRIPTION "VolgaOS legacy bootloader" - HOMEPAGE_URL "https://github.com/arsenez2006/VolgaBL" - LANGUAGES C ASM_NASM -) - -# Find dependencies -find_dependencies() - -# Compile bootloader -add_subdirectory(bootloader) - -if(BUILD_DOCS) - set(DEPS bootloader bootloader_docs) -else() - set(DEPS bootloader) -endif() - -# Copy target files -add_custom_target(${PROJECT_NAME} ALL - COMMAND ${CMAKE_COMMAND} -E copy $ ${OUTPUT}/${MBR_TARGET} - COMMAND ${CMAKE_COMMAND} -E copy $ ${OUTPUT}/${SSL_TARGET} - COMMAND ${CMAKE_COMMAND} -E copy $ ${OUTPUT}/${TSL_TARGET} - DEPENDS ${DEPS} -) diff --git a/README.md b/README.md deleted file mode 100644 index 1b2102f..0000000 --- a/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# VolgaOS legacy bootloader - -## GPT Partition types -* `C586E653-7991-4947-AC24-75F8CFF9945C` - VolgaBL second stage bootloader (SSL) -* `876D0DC7-CF66-4C63-BCEE-BD79EE10F593` - VolgaBL third stage bootloader (TSL) -* `78A9E598-3638-4D67-B2EB-0123D0AFBDBD` - VolgaOS kernel - -## Building -### Dependencies -* CMake 3.20+ -* GCC -* NASM -* Doxygen (optional) - -### Options -* `-DOUTPUT=` path to the directory where bootloader images will be placed. Default: `${CMAKE_BINARY_DIR}/out` -* `-DBUILD_DOCS=` build docs. Requires Doxygen. Default: `OFF` -* `-DOUTPUT_DOCS=` path to the directory where docs will be placed. Default: `${OUTPUT}/docs` - -### Steps -1. Create build directory -``` -mkdir build -``` -2. Configure CMake -``` -cd build -cmake .. -DCMAKE_BUILD_TYPE=Release -DOUTPUT=../out -``` -3. Run make to build everything -``` -cd build -make -``` -You can also build only bootloader, without docs -``` -cd build -make bootloader -``` - -### Manual installation -#### Drive mapping -1. Map your drive using GPT (e.g. using `fdisk`) -2. Create 2 partitions for SSL and TSL loaders, each 64KB -3. Assign GPT partition types for each partition -#### Writing images -1. Write `bootloader_mbr` to the first sector of your bootdrive (WARNING: this will erase your current MBR and other OS's won't boot!) -2. Write `bootloader_ssl` to SSL partition -3. Write `bootloader_tsl` to TSL partition diff --git a/bootloader/CMakeLists.txt b/bootloader/CMakeLists.txt deleted file mode 100644 index 0d0631a..0000000 --- a/bootloader/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -cmake_minimum_required(VERSION 3.20) -project(bootloader) - -# Targets -set(MBR_TARGET ${PROJECT_NAME}_mbr) -set(SSL_TARGET ${PROJECT_NAME}_ssl) -set(TSL_TARGET ${PROJECT_NAME}_tsl) - -# Docs targets -set(SSL_DOCS ${SSL_TARGET}_docs) -set(TSL_DOCS ${TSL_TARGET}_docs) - -# Compile MBR -add_subdirectory(MBR) - -# Compile SSL -add_subdirectory(SSL) - -# Compile TSL -add_subdirectory(TSL) - -add_custom_target(${PROJECT_NAME} - DEPENDS ${MBR_TARGET} ${SSL_TARGET} ${TSL_TARGET} -) - -if(BUILD_DOCS) - add_custom_target(${PROJECT_NAME}_docs - DEPENDS ${SSL_DOCS} ${TSL_DOCS} - ) -endif() - -set(MBR_TARGET ${MBR_TARGET} PARENT_SCOPE) -set(SSL_TARGET ${SSL_TARGET} PARENT_SCOPE) -set(TSL_TARGET ${TSL_TARGET} PARENT_SCOPE) diff --git a/bootloader/MBR/CMakeLists.txt b/bootloader/MBR/CMakeLists.txt deleted file mode 100644 index 2d049d1..0000000 --- a/bootloader/MBR/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -cmake_minimum_required(VERSION 3.20) -project(${MBR_TARGET} - DESCRIPTION "Main Boot Record" - LANGUAGES ASM_NASM -) - -# MBR sources -set(SRCS "${PROJECT_SOURCE_DIR}/mbr.asm") - -# LD Script -set(LD_SCRIPT "${PROJECT_SOURCE_DIR}/mbr.ld") - -# Output symbols map -set(SYM_MAP "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.map") - -# Compile options -list(APPEND ASM_OPTIONS - ${ASM_OPTIMIZATION} - ${ASM_GENERATION} -) - -# Link options -list(APPEND LINK_OPTIONS - ${LINK_FLAGS} - "-m16" -) - -# Configure Sources -set_source_files_properties(${SRCS} PROPERTIES - LANGUAGE ASM_NASM - COMPILE_OPTIONS "${ASM_OPTIONS}" -) - -# Add MBR target -add_executable(${PROJECT_NAME} EXCLUDE_FROM_ALL ${SRCS}) - -# Configure linking -target_link_options(${PROJECT_NAME} PRIVATE ${LINK_OPTIONS}) -set_target_properties(${PROJECT_NAME} PROPERTIES - LINK_DEPENDS ${LD_SCRIPT} - LINK_FLAGS "-Xlinker --oformat=binary -Xlinker -Map=${SYM_MAP} -T ${LD_SCRIPT}" -) diff --git a/bootloader/MBR/mbr.asm b/bootloader/MBR/mbr.asm deleted file mode 100644 index 9895f3d..0000000 --- a/bootloader/MBR/mbr.asm +++ /dev/null @@ -1,266 +0,0 @@ -cpu 386 -bits 16 -global __bootstrap - -; ------------------------------------------------------------------------------------------------- -; DEFINES -; ------------------------------------------------------------------------------------------------- -%define MBR_ADDR 0x7C00 -%define MBR_SEG MBR_ADDR >> 4 - -%define SSL_ADDR 0x10000 -%define SSL_SIZE 64 * 1024 -%define SSL_SEG SSL_ADDR >> 4 -%define SSL_SECTORS SSL_SIZE / 512 - 1 ; FIXME: Some BIOSes can't read more than 127 sectors - -%define BUFF_ADDR SSL_ADDR -%define BUFF_SEG BUFF_ADDR >> 4 - -%define STACK_BOT_ADDR 0x500 -%define STACK_TOP_ADDR MBR_ADDR - 16 -%define STACK_SEG STACK_BOT_ADDR >> 4 -%define STACK_INIT STACK_TOP_ADDR - STACK_BOT_ADDR - -%define SECTOR_SIZE 512 - -; ------------------------------------------------------------------------------------------------- -; MBR ERROR CODES: -; 1 - BIOS does not suppport int 13h extensions -; 2 - Boot drive has invalid sector size -; 3 - Failed to read GPT header -; 4 - Drive is not GPT -; 5 - Failed to read partition table -; 6 - Failed to find Second Stage Loader -; 7 - Failed to load Second Stage Loader -; ------------------------------------------------------------------------------------------------- - -; ------------------------------------------------------------------------------------------------- -; MBR ENTRY -; ------------------------------------------------------------------------------------------------- -section .text -__bootstrap: - ; Initialize segments - cli - cld - jmp MBR_SEG:.cs -.cs: - mov ax, MBR_SEG - mov ds, ax - mov ax, BUFF_SEG - mov es, ax - mov ax, STACK_SEG - mov ss, ax - mov sp, STACK_INIT - mov byte [drive_number], dl ; Save drive number - sti - -start: - ; Print loading message - mov si, msg_loading - call print - - ; Check int 13h extensions - mov ah, 0x41 - mov bx, 0x55AA - int 0x13 - mov al, '1' - jc near .fail - cmp bx, 0xAA55 - jne near .fail - - ; Check sector size - mov byte [es:0x00], 26 ; Result buffer size (Excludes EDD) - push ds - mov ax, es - mov ds, ax - xor si, si ; DS:SI = Result buffer - mov ah, 0x48 - int 0x13 - pop ds - mov al, '2' - jc near .fail - cmp word [es:0x18], SECTOR_SIZE - jne near .fail - - ; Read GPT Header - call read_drive - mov al, '3' - jc near .fail - - ; Check GPT Signature - mov si, gpt_sig - xor di, di - mov cx, 8 - call memcmp - mov al, '4' - jc near .fail - - ; Get Number of Partition Entries - mov eax, dword [es:0x50] - push eax - ; Get Size of each entry - mov ebx, dword [es:0x54] - push ebx - ; Calculate size of Partition table - mul ebx - - ; Calculate size of Partition table in sectors - mov ebx, SECTOR_SIZE - div ebx - or edx, edx - jz short .skip_inc - inc eax -.skip_inc: - - ; Update DAP - mov word [DAP.sectors], ax - mov eax, dword [es:(0x48 + 0)] - mov dword [DAP.lba_low], eax - mov eax, dword [es:(0x48 + 4)] - mov dword [DAP.lba_high], eax - - ; Read Partition table - call read_drive - mov al, '5' - jc short .fail - - ; Find SSL Partition header - pop ebp ; Entry size - pop ecx ; Entries count - mov edx, 0x00 ; Start offset -.loop: - ; Check partiotion type - push cx - mov si, ssl_part_type - mov di, dx - mov cx, 16 - call memcmp - pop cx - jnc short .found - -.next: - add edx, ebp - loop .loop - mov al, '6' - jmp short .fail -.found: - - mov ebp, edx - - ; Get SSL Start LBA (EBX:EAX) - mov eax, dword [es:(ebp + 0x20 + 0)] - mov ebx, dword [es:(ebp + 0x20 + 4)] - - ; Update DAP - mov dword [DAP.lba_low], eax - mov dword [DAP.lba_high], ebx - mov word [DAP.sectors], SSL_SECTORS - - ; Load SSL to memory - call read_drive - mov al, '7' - jc short .fail - - ; Far jump to SSL - jmp SSL_SEG:0x0000 - -.halt: - hlt - jmp short .halt -.fail: - xor bx, bx - mov ah, 0x0E - int 0x10 - mov si, msg_fail - call print - jmp short .halt - -; ------------------------------------------------------------------------------------------------- -; PROCEDURES -; ------------------------------------------------------------------------------------------------- - -; print -; Prints string to terminal, using BIOS -; INPUT: DS:SI - Pointer to null-terminated string -print: - xor bx, bx - mov ah, 0x0E -.loop: - lodsb - or al, al - jz short .ret - int 0x10 - jmp short .loop -.ret: - ret - -; read_drive -; Reads sectors from saved drive, using DAP -; INPUT: Filled DAP -; OUTPUT: CF is set on error, clear on success -; LIMITATIONS: -; - Maximum buffer size is 64KB (1 real mode segment) -; - Some BIOSes can't read more than 127 sectors -read_drive: - mov ah, 0x42 - mov dl, byte [drive_number] - mov si, DAP - int 0x13 - ret - -; memcmp -; Compares data -; INPUT: -; - DS:SI - pointer to the first block of data -; - ES:DI - pointer to the second block of data -; - CX - number of bytes to compare -; OUTPUT: CF is set on mismatch, clear if equal -; Saves all registers, except FLAGS -memcmp: - pusha -.loop: - lodsb - cmp al, byte [es:di] - jne short .fail - inc di - loop .loop -.success: - clc - jmp short .ret -.fail: - stc -.ret: - popa - ret - -; ------------------------------------------------------------------------------------------------- -; DATA -; ------------------------------------------------------------------------------------------------- -section .data - -; Messages -msg_loading db"Loading VolgaOS...",13,10,0 -msg_fail db" - MBR fail.",0 - -; GPT signature -gpt_sig db"EFI PART" - -; Second Stage Loader GPT partition type (C586E653-7991-4947-AC24-75F8CFF9945C) -ssl_part_type db 0x53,0xE6,0x86,0xC5,0x91,0x79,0x47,0x49,0xAC,0x24,0x75,0xF8,0xCF,0xF9,0x94,0x5C - -; Disk Address Packet used for read_drive procedure -DAP: -.size: db 0x10 ; Always 16 -.rsv: db 0x00 ; Always 0 -.sectors: dw 0x0001 ; first 8 bits - number of sectors to read, 9 - 16 must be zeroed -.offset: dw 0x0000 ; Buffer offset -.segment: dw 0x1000 ; Buffer segment -.lba_low: dd 0x00000001 ; LBA of the disk (low 32 bits) -.lba_high: dd 0x00000000 ; LBA of the disk (high 32 bits) - -; ------------------------------------------------------------------------------------------------- -; BSS -; ------------------------------------------------------------------------------------------------- -section .bss -; Saved drive number -drive_number resb 0x00 diff --git a/bootloader/MBR/mbr.ld b/bootloader/MBR/mbr.ld deleted file mode 100644 index 8f57455..0000000 --- a/bootloader/MBR/mbr.ld +++ /dev/null @@ -1,20 +0,0 @@ -OUTPUT(binary) -ENTRY(__bootstrap) -MEMORY -{ - MBR_code (rwx) : ORIGIN = 0x00000000, LENGTH = 0x000001BE - MBR_bss (rw) : ORIGIN = 0x000001BE, LENGTH = 0x00000042 -} - -SECTIONS -{ - .text : - { - *(.text) - *(.data) - } > MBR_code - .bss (NOLOAD) : - { - *(.bss) - } > MBR_bss -} diff --git a/bootloader/SSL/CMakeLists.txt b/bootloader/SSL/CMakeLists.txt deleted file mode 100644 index afd775d..0000000 --- a/bootloader/SSL/CMakeLists.txt +++ /dev/null @@ -1,74 +0,0 @@ -cmake_minimum_required(VERSION 3.20) -project(${SSL_TARGET} - DESCRIPTION "Second Stage Loader" - LANGUAGES C ASM_NASM -) - -# SSL Sources -file(GLOB_RECURSE C_SRCS "src/*.c") -file(GLOB_RECURSE ASM_SRCS "src/*.asm") -file(GLOB_RECURSE HDRS "include/*.h") -list(APPEND SRCS ${C_SRCS} ${ASM_SRCS}) - -# LD Script -set(LD_SCRIPT "${PROJECT_SOURCE_DIR}/SSL.ld") - -# Output symbols map -set(SYM_MAP "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.map") - -# Compile options -set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG") -list(APPEND C_OPTIONS - ${C_DIALECT} - ${C_OPTIMIZATION} - ${C_INSTRUMENTATION} - ${C_GENERATION} - ${C_x86_16} -) -list(APPEND ASM_OPTIONS - ${ASM_OPTIMIZATION} - ${ASM_GENERATION} -) - -# Link options -list(APPEND LINK_OPTIONS - ${LINK_FLAGS} - "-m16" -) - -# Configure Sources -set_source_files_properties(${C_SRCS} PROPERTIES - LANGUAGE C - COMPILE_OPTIONS "${C_OPTIONS}" -) -set_source_files_properties(${ASM_SRCS} PROPERTIES - LANGUAGE ASM_NASM - COMPILE_OPTIONS "${ASM_OPTIONS}" -) - -# Add SSL target -add_executable(${PROJECT_NAME} EXCLUDE_FROM_ALL ${SRCS} ${HDRS}) -target_include_directories(${PROJECT_NAME} PRIVATE "include") - -# Configure linking -target_link_options(${PROJECT_NAME} PRIVATE ${LINK_OPTIONS}) -set_target_properties(${PROJECT_NAME} PROPERTIES - LINK_DEPENDS ${LD_SCRIPT} - LINK_FLAGS "-Xlinker --oformat=binary -Xlinker -Map=${SYM_MAP} -T ${LD_SCRIPT}" -) - -# Generate docs -if(BUILD_DOCS) - set(DOXYGEN_OUTPUT_DIRECTORY ${OUTPUT_DOCS}/VolgaBL/SSL) - set(DOXYGEN_PROJECT_NAME "SSL") - set(DOXYGEN_PROJECT_BRIEF "Second Stage Loader") - #set(DOXYGEN_PROJECT_NUMBER ${VLGBL_VERSION}) - set(DOXYGEN_MACRO_EXPANSION YES) - set(DOXYGEN_EXPAND_ONLY_PREDEF NO) - list(APPEND DOXYGEN_PREDEFINED - "__attribute__(x)=" - "__bool_true_false_are_defined" - "DOX_SKIP" - ) - doxygen_add_docs(${SSL_DOCS}) -endif(BUILD_DOCS) \ No newline at end of file diff --git a/bootloader/SSL/SSL.ld b/bootloader/SSL/SSL.ld deleted file mode 100644 index 99d6494..0000000 --- a/bootloader/SSL/SSL.ld +++ /dev/null @@ -1,32 +0,0 @@ -OUTPUT(binary) -ENTRY(__bootstrap) -MEMORY -{ - SSL_segment (rwx) : ORIGIN = 0x00000000, LENGTH = 0x00010000 -} -SECTIONS -{ - .text : - { - BYTE(0xE9); - SHORT(__bootstrap - 3); - *(.text) - } > SSL_segment - .rodata : - { - *(.rodata*) - } > SSL_segment - .data : - { - *(.data) - } > SSL_segment - .bss (NOLOAD) : - { - *(.bss) - } > SSL_segment - /DISCARD/ : - { - *(.note*) - *(.comment*) - } -} diff --git a/bootloader/SSL/include/bl/bios.h b/bootloader/SSL/include/bl/bios.h deleted file mode 100644 index 94b2bd8..0000000 --- a/bootloader/SSL/include/bl/bios.h +++ /dev/null @@ -1,156 +0,0 @@ -/** - * @file bios.h - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Useful BIOS call wrappers for C - * - */ -#ifndef BL_BIOS_H -#define BL_BIOS_H - -#include "types.h" - -/** - * @struct DAP - * @brief Disk Address Packet - * @details Used by BIOS int 13h for reading/writing drive - * - * @typedef DAP - * @brief DAP type - * - */ -typedef struct __packed DAP { - /** - * @brief Size of the DAP. Must be 16 or sizeof(DAP) - * - */ - byte_t size; - /** - * @brief Reserved. Always 0 - * - */ - byte_t rsv; - /** - * @brief Number of sectors to read/write. Maximum value is 128 - * - */ - word_t sectors; - /** - * @brief Read/Write buffer offset in the segment - * - */ - word_t offset; - /** - * @brief Read/Write buffer segment - * - */ - word_t segment; - /** - * @brief LBA of the drive - * - */ - qword_t lba; -} DAP; - -/** - * @struct drive_parameteres - * @brief Parameteres of the drive - * @details Used by BIOS int 13h to get drive parameteres - * - * @typedef drive_parameteres - * @brief drive_parameteres type - * - */ -typedef struct __packed drive_parameteres { - /** - * @brief Size of the result buffer. Must be 26 or sizeof(drive_parameteres) - * - */ - word_t size; - /** - * @brief Information flags - * - */ - word_t flags; - /** - * @brief Physical number of cylinders - * - */ - dword_t cylinders; - /** - * @brief Physical number of heads - * - */ - dword_t heads; - /** - * @brief Physical number of sectors per track - * - */ - dword_t sectors; - /** - * @brief Absolute number of sectors - * - */ - qword_t count_of_sectors; - /** - * @brief Bytes per sector - * - */ - word_t sector_size; -} drive_parameteres; - -/** - * @brief Print char to terminal, using BIOS int 10h - * - * @param [in] ch ASCII character to print - */ -void bios_putch(byte_t ch); - -/** - * @brief Read drive using BIOS int 13h - * @details Can read 128 sectors on all BIOSes - * - * @param [in] read_context Pointer to DAP - * @return true on success - * @return false on failure - */ -bool __check_ret bios_read_drive(const DAP* read_context); - -/** - * @brief Get drive parameteres, using BIOS int 13h - * - * @param [out] buffer Pointer to resulting drive_parameteres - * @return true on success - * @return false on failure - */ -bool __check_ret bios_get_drive_parameteres(drive_parameteres* buffer); - -/** - * @brief Get E820 memory map entry, using BIOS int 15h - * - * @param [in out] offset - * On call: offset from the beggining of the memory card (0 - - * start over)\n On return: Next offset from the beggining of the memory card (0 - * - the whole map has been transferred) - * @param [in] buf_size Buffer size. Should be sizeof(memory_map_entry) - * @param [in] buffer Pointer to buffer - * @return true on success - * @return false on failure - */ -bool __check_ret bios_get_e820(dword_t* offset, dword_t buf_size, void* buffer); - -/** - * @brief Initialize COM port, using BIOS int 14h - * - * @return true on success - * @return false on failure - */ -bool bios_serial_init(void); - -/** - * @brief Print character to COM port, using BIOS int 14h - * - * @param [in] ch ASCII character to print - */ -void bios_serial_putch(byte_t ch); - -#endif /* BL_BIOS_H */ diff --git a/bootloader/SSL/include/bl/defines.h b/bootloader/SSL/include/bl/defines.h deleted file mode 100644 index a1251cd..0000000 --- a/bootloader/SSL/include/bl/defines.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef BL_DEFINES_H -#define BL_DEFINES_H - -#define __noreturn __attribute__((noreturn)) -#define __packed __attribute__((packed)) -#define __unused __attribute__((unused)) -#define __print_fmt(fmt, va) __attribute__((format(printf, fmt, va))) -#define __check_ret __attribute__((warn_unused_result)) -#define __align(n) __attribute__((aligned(n))) - -#define SECTOR_SIZE 512 - -#define TSL_ADDR 0x20000 -#define TSL_SEG TSL_ADDR >> 4 - -#endif /* BL_DEFINES_H */ diff --git a/bootloader/SSL/include/bl/io.h b/bootloader/SSL/include/bl/io.h deleted file mode 100644 index 3837607..0000000 --- a/bootloader/SSL/include/bl/io.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file io.h - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Implements printf - * - */ -#ifndef BL_IO_H -#define BL_IO_H - -#include "types.h" - -#include - -/** - * @brief Write formatted data from variable argument list to sized buffer - * - * @param [out] s Pointer to a buffer where the resulting C-string is stored - * @param [in] n Maximum number of bytes to be used in the buffer - * @param [in] format C-string that contains a format string - * @param [in] arg A value identifying a variable arguments list initialized - * with va_start - * @return The number of characters that would have been written if n had been - * sufficiently large, not counting the terminating null character - */ -int vsnprintf(char* s, size_t n, char const* format, va_list arg); - -/** - * @brief Write formatted output to sized buffer - * - * @param [out] s Pointer to a buffer where the resulting C-string is stored - * @param [in] n Maximum number of bytes to be used in the buffer - * @param [in] format C-string that contains a format string - * @param [in out] ... Additional args - * @return The number of characters that would have been written if n had been - * sufficiently large, not counting the terminating null character - */ -int __print_fmt(3, 4) snprintf(char* s, size_t n, char const* format, ...); - -/** - * @brief Write formatted data to string - * - * @param [out] s Pointer to a buffer where the resulting C-string is stored - * @param [in] format C-string that contains a format string - * @param [in] ... Additional args - * @return The number of characters that would have been written if n had been - * sufficiently large, not counting the terminating null character - */ -int __print_fmt(2, 3) sprintf(char* s, char const* format, ...); - -/** - * @brief Print formatted data to terminal - * - * @param [in] format C-string that contains a format string - * @param [in] ... Additional args - * @return The number of characters that would have been written if n had been - * sufficiently large, not counting the terminating null character - */ -int __print_fmt(1, 2) printf(char const* format, ...); - -/** - * @brief Print formatted data to COM port - * - * @param [in] format C-string that contains a format string - * @param [in] ... Additional args - * @return The number of characters that would have been written if n had been - * sufficiently large, not counting the terminating null character - */ -int __print_fmt(1, 2) serial_printf(char const* format, ...); - -#endif /* BL_IO_H */ diff --git a/bootloader/SSL/include/bl/mem.h b/bootloader/SSL/include/bl/mem.h deleted file mode 100644 index 9f193f0..0000000 --- a/bootloader/SSL/include/bl/mem.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @file mem.h - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Memory allocator - * - */ -#ifndef BL_MEM_H -#define BL_MEM_H - -#include "types.h" - -/** - * @brief Initialize memory allocator - * - * @return true on success - * @return false on failure - */ -bool __check_ret mem_init(void); - -/** - * @brief Allocate memory - * - * @param [in] count Number of bytes to allocate - * @return Pointer to allocated block\n - * NULL on failure - */ -void* __check_ret malloc(size_t count); - -/** - * @brief Reallocate memory - * - * @param [in] mem Pointer to block to reallocate - * @param [in] new_size New size of the block - * @return Pointer to the reallocated block - * NULL on failure - */ -void* __check_ret realloc(void* mem, size_t new_size); - -/** - * @brief Free memory block - * - * @param [in] mem Pointer to the block - */ -void free(void* mem); - -/** - * @brief Get the \ref memory_map "memory map" object - * - * @return Pointer to the \ref memory_map "memory map" object - * NULL on failure - */ -memory_map* get_memory_map(void); - -#endif /* BL_MEM_H */ diff --git a/bootloader/SSL/include/bl/string.h b/bootloader/SSL/include/bl/string.h deleted file mode 100644 index 2ef5cd2..0000000 --- a/bootloader/SSL/include/bl/string.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @file string.h - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Functions for manipulating c-strings and buffers - * - */ -#ifndef BL_STRING_H -#define BL_STRING_H - -#include "types.h" - -/** - * @brief Returns the length of a given string - * - * @param [in] str Pointer to the null-terminated byte string to be examined - * @return The length of the null-terminated byte string str. - */ -size_t __check_ret strlen(char const* str); - -/** - * @brief Compares two buffers - * - * @param [in] lhs Pointer to the first buffer - * @param [in] rhs Pointer to the second buffer - * @param [in] count Number of bytes to examine - * @return Zero if lhs and rhs compare equal, or if count is zero. - */ -int __check_ret memcmp(void const* lhs, void const* rhs, size_t count); - -/** - * @brief Copies one buffer to another - * - * @param [out] dest Pointer to the object to copy to - * @param [in] src Pointer to the object to copy from - * @param [in] count Number of bytes to copy - * @return dest - */ -void* memcpy(void* dest, void const* src, size_t count); - -/** - * @brief Fills a buffer with a character - * - * @param [out] ptr Pointer to the object to fill - * @param [in] val Fill byte - * @param [in] count Number of bytes to fill - * @return ptr - */ -void* memset(void* ptr, int val, size_t count); - -#endif /* BL_STRING_H */ diff --git a/bootloader/SSL/include/bl/types.h b/bootloader/SSL/include/bl/types.h deleted file mode 100644 index a7c3d96..0000000 --- a/bootloader/SSL/include/bl/types.h +++ /dev/null @@ -1,537 +0,0 @@ -/** - * @file types.h - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Typedefs, data structers and enums used in Second Stage Loader - * - */ -#ifndef BL_TYPES_H -#define BL_TYPES_H - -#include "defines.h" - -#include -#include - -/** - * @typedef byte_t - * @brief Byte type - * - */ -typedef uint8_t byte_t; - -/** - * @typedef word_t - * @brief Word type - * - */ -typedef uint16_t word_t; - -/** - * @typedef dword_t - * @brief Double word type - * - */ -typedef uint32_t dword_t; - -/** - * @typedef qword_t - * @brief Quad word type - * - */ -typedef uint64_t qword_t; - -#ifndef __bool_true_false_are_defined -# define __bool_true_false_are_defined - -typedef enum { false, true } bool; -#endif /* __bool_true_false_are_defined */ - -/** - * @struct memory_map_entry - * @brief Memory map entry - * @details Describes a memory region - * - * @typedef memory_map_entry - * @brief memory_map_entry type - * - */ -typedef struct __packed memory_map_entry { - /** - * @brief Start of memory region - * - */ - qword_t base; - /** - * @brief Size of memory region - * - */ - qword_t limit; - /** - * @brief Type of memory region - * - */ - dword_t type; - /** - * @brief ACPI info - * - */ - dword_t ACPI; -} memory_map_entry; - -/** - * @struct memory_map_node - * @brief Memory map node - * @details Describes a single node of memory map list - * - * @typedef memory_map_node - * @brief memory_map_node type - * - */ -typedef struct memory_map_node { - /** - * @brief Pointer to next node - * - */ - struct memory_map_node* next; - /** - * @brief Pointer to previous node - * - */ - struct memory_map_node* prev; - /** - * @brief Memory map entry - * - */ - memory_map_entry entry; -} memory_map_node; - -/** - * @struct memory_map - * @brief Memory map - * @details Holds a pointer to the memory map list and count of entries - * - * @typedef memory_map - * @brief memory_map type - * - */ -typedef struct memory_map { - /** - * @brief Count of entries - * - */ - size_t count; - /** - * @brief Pointer to the memory map list - * - */ - memory_map_node* list; -} memory_map; - -/** - * @struct GPT_header - * @brief GPT header - * - * @typedef GPT_header - * @brief GPT_header type - * - */ -typedef struct __packed GPT_header { - /** - * @brief GPT Signature - * @details Must be "EFI PART" - * - */ - byte_t magic[8]; - /** - * @brief GPT Revision - * - */ - dword_t revision; - /** - * @brief GPT Header size - * - */ - dword_t hdr_size; - /** - * @brief CRC32 Checksum of GPT header - * @details Calculated with \ref GPT_header::crc32 "CRC32 field" equal 0 - * - */ - dword_t crc32; - /** - * @brief Reserved - * - */ - byte_t rsv0[4]; - /** - * @brief LBA of the primary \ref GPT_header "GPT header" - * - */ - qword_t hdr_lba; - /** - * @brief LBA of the alternate \ref GPT_header "GPT header" - * - */ - qword_t alt_hdr_lba; - /** - * @brief First usable LBA - * - */ - qword_t first_usable; - /** - * @brief Last usable LBA - * - */ - qword_t last_usable; - /** - * @brief GUID of the drive - * - */ - byte_t guid[16]; - /** - * @brief Starting LBA of \ref GPT_partition_entry "GPT partition array" - * - */ - qword_t partition_array; - /** - * @brief Count of entries in \ref GPT_partition_entry "GPT partition array" - * - */ - dword_t entries_count; - /** - * @brief Size of \ref GPT_partition_entry "GPT partition entry" - * - */ - dword_t entry_size; - /** - * @brief \ref GPT_partition_entry "GPT partition array" CRC32 Checksum - * - */ - dword_t partition_array_crc32; -} GPT_header; - -/** - * @struct GPT_partition_entry - * @brief GPT partiion entry - * @warning sizeof(\ref GPT_partition_entry) is not an actual size of entry. - * Refer \ref GPT_header::entry_size "GPT Header" or \ref - * GPT_partition_array::entry_size "GPT Partition array" - * - * @typedef GPT_partition_entry - * @brief GPT_partition_entry type - * - */ -typedef struct __packed GPT_partition_entry { - /** - * @brief Parition type - * - */ - byte_t type[16]; - /** - * @brief Partition UUID - * - */ - byte_t uuid[16]; - /** - * @brief Starting LBA of the partition - * - */ - qword_t start_lba; - /** - * @brief Ending LBA of the partition - * - */ - qword_t end_lba; - /** - * @brief Partition attributes - * - */ - qword_t attrs; -} GPT_partition_entry; - -/** - * @struct GPT_partition_array - * @brief GPT partition array - * @details Holds a pointer to the array, count of enries and size of each entry - * - * @typedef GPT_partition_array - * @brief GPT_partition_array type - * - */ -typedef struct GPT_partition_array { - /** - * @brief Count of entries - * - */ - size_t count; - /** - * @brief Size of single entry - * - */ - size_t entry_size; - /** - * @brief Pointer to the array - * - */ - GPT_partition_entry* array; -} GPT_partition_array; - -/** - * @enum GDT_access - * @brief Access flags for GDT entry - * - */ -typedef enum { - /** - * @brief Defines a valid segment - * - */ - GDT_ACCESS_PRESENT = (1 << 7), - /** - * @brief Set DPL = 0 - * - */ - GDT_ACCESS_DPL0 = (0 << 5), - /** - * @brief Set DPL = 1 - * - */ - GDT_ACCESS_DPL1 = (1 << 5), - /** - * @brief Set DPL = 2 - * - */ - GDT_ACCESS_DPL2 = (2 << 5), - /** - * @brief Set DPL = 3 - * - */ - GDT_ACCESS_DPL3 = (3 << 5), - /** - * @brief Defines normal, non-TSS segment - * - */ - GDT_ACCESS_SEGMENT = (1 << 4), - /** - * @brief Defines executable segment - * - */ - GDT_ACCESS_EXECUTABLE = (1 << 3), - /** - * @brief Defines a data segment, which grows down - * - */ - GDT_ACCESS_DIRECTION = (1 << 2), - /** - * @brief Defines a code segment, which can be executed from an equal or - * lower privilege level - * - */ - GDT_ACCESS_CONFORMING = (1 << 2), - /** - * @brief Defines a readable code segment - * - */ - GDT_ACCESS_READABLE = (1 << 1), - /** - * @brief Defines a writeable data segment - * - */ - GDT_ACCESS_WRITEABLE = (1 << 1) -} GDT_access; - -/** - * @enum GDT_flags - * @brief Flags for GDT entry - * - */ -typedef enum { - /** - * @brief Granularity flag - * @details Scales limit with page granularity (4KB) - */ - GDT_FLAG_GRANULARITY = (1 << 3), - /** - * @brief Size flag - * @details Defines 32bit segment - */ - GDT_FLAG_SIZE = (1 << 2), - /** - * @brief Long mode code flag - * @details Defines 64bit code segment. - * @warning Don't use with \ref GDT_flags::GDT_FLAG_SIZE "Size flag" - */ - GDT_FLAG_LONG = (1 << 1) -} GDT_flags; - -/** - * @struct GDT32_entry - * @brief Protected mode GDT entry - * - * @typedef GDT32_entry - * @brief GDT32_entry type - * - */ -typedef struct __packed GDT32_entry { - /** - * @warning Should be filled with \ref set_GDT32_entry - * - */ - byte_t data[8]; -} GDT32_entry; - -/** - * @struct GDTR32 - * @brief Protected mode GDTR - * - * @typedef GDTR32 - * @brief GDTR32 type - * - */ -typedef struct __packed GDTR32 { - /** - * @warning Should be filled with \ref set_GDTR32 - * - */ - byte_t data[6]; -} GDTR32; - -/** - * @struct video_lintext - * @brief Linear text video driver info - * - * @typedef video_lintext - * @brief video_lintext type - * - */ -typedef struct __packed video_lintext { - /** - * @brief Mode number reported by BIOS - * - */ - dword_t mode; - /** - * @brief Real mode segment of framebuffer - * - */ - dword_t seg; - /** - * @brief Number of columns - * - */ - dword_t cols; - /** - * @brief Number of rows - * - */ - dword_t rows; -} video_lintext; - -enum { - BOOT_VIDEO_NOVIDEO, - -/** - * @brief No video driver was found during boot - * - */ -#define BOOT_VIDEO_NOVIDEO BOOT_VIDEO_NOVIDEO - BOOT_VIDEO_LINTEXT -/** - * @brief Linear text video driver - * - */ -#define BOOT_VIDEO_LINTEXT BOOT_VIDEO_LINTEXT -}; - -/** - * @struct boot_info_t - * @brief Boot info, passed to TSL and kernel - * - * @typedef boot_info_t - * @brief boot_info_t type - * - */ -typedef struct __packed boot_info_t { - /** - * @brief Size of this structure - * - */ - dword_t size; - - /** - * @brief Booted drive info - * - */ - struct { - /** - * @brief Booted drive GUID - * - */ - byte_t GUID[16]; - } boot_drive; - - /** - * @brief Memory map info - * - */ - struct { - /** - * @brief Count of memory map entries - * - */ - dword_t count; - /** - * @brief Size of each memory map entry - * - */ - dword_t entry_size; - /** - * @brief Physical address to memory map array - * - */ - qword_t address; - } memory_map; - - /** - * @brief Video info - * - */ - struct { - /** - * @brief Driver type - * - */ - dword_t type; - /** - * @brief Physical address to driver info - * - */ - qword_t address; - } video_info; - - /** - * @brief ACPI tables - * - */ - struct { - /** - * @brief Address of RSDP - * - */ - qword_t rsdp; - } ACPI; - - /** - * @brief RAMFS info - * - */ - struct { - /** - * @brief Physical address of RAMFS - * - */ - qword_t address; - } RAMFS; -} boot_info_t; - -#endif /* BL_TYPES_H */ diff --git a/bootloader/SSL/include/bl/utils.h b/bootloader/SSL/include/bl/utils.h deleted file mode 100644 index 7a3782b..0000000 --- a/bootloader/SSL/include/bl/utils.h +++ /dev/null @@ -1,151 +0,0 @@ -/** - * @file utils.h - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Utility functions used for Second Stage Loader - * - */ -#ifndef BL_UTILS_H -#define BL_UTILS_H - -#include "types.h" - -/** - * @brief Get value of DS register - * - * @return DS - */ -word_t get_ds(void); - -/** - * @brief Calculate CRC32 checksum - * - * @param [in] buf Pointer to a buffer to be examined - * @param [in] len Length of the buffer - * @return CRC32 checksum - */ -uint32_t __check_ret crc32(byte_t const* buf, size_t len); - -/** - * @brief Enable A20 line - * - * @return true on success - * @return false on failure - */ -bool __check_ret enable_A20(void); - -/** - * @brief Set the \ref GDT32_entry "GDT32 entry" object - * - * @param [out] entry Pointer to the \ref GDT32_entry "GDT32 entry" object to be - * filled - * @param [in] base Base address of the descriptor's segment - * @param [in] limit Size of the descriptor's segment - * @param [in] flags Flags of the descriptor - * @param [in] access Access flags of the descriptor - */ -void set_GDT32_entry( - GDT32_entry* entry, - dword_t base, - dword_t limit, - GDT_flags flags, - GDT_access access - ); - -/** - * @brief Set the \ref GDTR32 "GDTR32" object - * - * @param [out] gdtr Pointer to \ref GDTR32 "GDTR32" object to be filled - * @param [in] gdt32_table Pointer to the \ref GDT32_entry "GDT32" - * @param [in] count Count of descriptor in gdt32_table - */ -void set_GDTR32(GDTR32* gdtr, GDT32_entry const* gdt32_table, size_t count); - -/** - * @brief Load \ref GDTR32 "GDTR32" object - * - * @param [in] gdtr \ref GDTR32 "GDTR32" object - */ -void load_GDT32(GDTR32 gdtr); - -/** - * @brief Turn on Unreal mode - * - * @param [in] data_segment_offset Offset to the data segment in loaded GDT - */ -void enter_unreal(word_t data_segment_offset); - -/** - * @brief Get the partition array object - * - * @param [in] gpt_hdr Pointer to the \ref GPT_header "GPT header" object - * @return Pointer to the \ref GPT_partition_array "GPT Partition array" - * object\n NULL on failure - */ -GPT_partition_array* __check_ret get_partition_array(GPT_header const* gpt_hdr); - -/** - * @brief Find partition by GUID - * - * @param [in] partition_array - * Pointer to the \ref GPT_partition_array "GPT Partition array" object - * @param [in] GUID GUID of needed partition - * @return \ref GPT_partition_entry "GPT Partition entry" object\n - * NULL on failure - */ -GPT_partition_entry* -find_partition(GPT_partition_array const* partition_array, byte_t const* GUID); - -/** - * @brief Loads kernel partition from drive - * - * @param partition Kernel partition - * @param address Where to load kernel - * @return true on success - * @return false on failure - */ -bool load_kernel(GPT_partition_entry const* partition, dword_t address); - -/** - * @brief Create a boot info object - * - * @param drive_GUID GUID of the booted drive - * @param mem_map Memory map, returned by \ref get_memory_map - * @param ramfs_addr Physical address of RAMFS - * @return Boot info object - */ -boot_info_t* create_boot_info( - byte_t const* drive_GUID, memory_map* mem_map, qword_t ramfs_addr -); - -/** - * @brief Checks if CPUID available - * - * @return true - CPUID is available - * @return false - CPUID is not available - */ -bool check_cpuid(void); - -/** - * @brief Checks CPU extensions - * - * @return true - all required extensions are present - * @return false - some of the extensions are not implemented - */ -bool check_cpu_compat(void); - -/* Leave this undocumented */ -#ifndef DOX_SKIP -# ifndef NDEBUG -extern void _dump_heap(void); -extern void _dump_memory_map(memory_map* mem_map); -# define dump_heap() _dump_heap() -# define dump_memory_map(mem_map) _dump_memory_map(mem_map) -# else -# define dump_heap() \ - do { continue; } while (0) -# define dump_memory_map(mem_map) \ - do { continue; } while (0) -# endif /* NDEBUG */ -#endif /* DOX_SKIP */ - -#endif /* BL_UTILS_H */ diff --git a/bootloader/SSL/src/bios.c b/bootloader/SSL/src/bios.c deleted file mode 100644 index db2b24f..0000000 --- a/bootloader/SSL/src/bios.c +++ /dev/null @@ -1,92 +0,0 @@ -/** - * @file bios.c - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Useful BIOS call wrappers for C - * - */ -#include - -/* Leave this undocument */ -#ifndef DOX_SKIP - -/* From bootstrap.asm */ -extern byte_t _drive_number; - -#endif /* DOX_SKIP */ - -bool bios_serial_init(void) { - bool ret; - __asm__ volatile("int $0x14" - : "=@ccc"(ret) - : "a"((word_t)0x00E3), "d"((word_t)0x0000)); - return !ret; -} - -void bios_serial_putch(byte_t ch) { - __asm__ volatile("int $0x14" - : - : "a"((word_t)0x0100 | (word_t)ch), "d"((word_t)0x0000)); -} - -void bios_putch(byte_t ch) { - __asm__ volatile("int $0x10" - : - : "a"((word_t)0x0E00 | (word_t)ch), "b"((word_t)0x0000)); -} - -bool bios_get_e820(dword_t* offset, dword_t buf_size, void* buffer) { - dword_t SMAP_sig; - __asm__ volatile("int $0x15" - : "=a"(SMAP_sig), "=b"(*offset) - : "a"((word_t)0xE820), - "d"((dword_t)0x534D4150), - "b"(*offset), - "c"(buf_size), - "D"((word_t)((uintptr_t)buffer & 0xFFFF))); - if (SMAP_sig != 0x534D4150) { - return false; - } else { - return true; - } -} - -bool bios_get_drive_parameteres(drive_parameteres* buffer) { - bool ret; - __asm__ volatile("int $0x13" - : "=@ccc"(ret) - : "a"((word_t)0x4800), - "d"(_drive_number), - "S"((word_t)((uintptr_t)buffer & 0xFFFF))); - return !ret; -} - -bool bios_read_drive(const DAP* read_context) { - bool ret; - __asm__ volatile("int $0x13" - : "=@ccc"(ret) - : "a"((word_t)0x4200), - "d"(_drive_number), - "S"((word_t)((uintptr_t)read_context & 0xFFFF))); - - /* Some BIOSes can't read more than 127 sectors */ - if (ret && read_context->sectors == 128) { - DAP tmp_read_context; - tmp_read_context = *read_context; - - /* Read first 127 sectors */ - tmp_read_context.sectors = 127; - if (!bios_read_drive(&tmp_read_context)) { - return false; - } - - /* Read last sector */ - tmp_read_context.sectors = 1; - tmp_read_context.offset += 127 * SECTOR_SIZE; - if (!bios_read_drive(&tmp_read_context)) { - return false; - } else { - return true; - } - } - return !ret; -} diff --git a/bootloader/SSL/src/bootstrap.asm b/bootloader/SSL/src/bootstrap.asm deleted file mode 100644 index 2574411..0000000 --- a/bootloader/SSL/src/bootstrap.asm +++ /dev/null @@ -1,58 +0,0 @@ -cpu 386 -bits 16 - -global __bootstrap -global __drive_number -global __heap -global __heap_size - -extern _ssl_entry - -; ------------------------------------------------------------------------------------------------- -; BSS -; ------------------------------------------------------------------------------------------------- -section .bss -; Allocate stack -stack: -align 16 -.bot: - resb 2 * 1024 -.top: - -; Allocate heap -__heap: -align 16 -.begin: - resb 1024 * 32 -.end: - - -; Saved drive number -__drive_number resb 1 - -; ------------------------------------------------------------------------------------------------- -; TEXT -; ------------------------------------------------------------------------------------------------- -section .text -__bootstrap: - ; Initialize segments and stack - cli - cld - mov ax, cs - mov ds, ax - mov es, ax - mov ss, ax - mov sp, stack.top - mov byte [__drive_number], dl ; Save drive number - sti - - ; Call C Code - jmp near _ssl_entry - -; ------------------------------------------------------------------------------------------------- -; RODATA -; ------------------------------------------------------------------------------------------------- -section .rodata -; Heap size -__heap_size: - dw __heap.end - __heap.begin diff --git a/bootloader/SSL/src/gcc_arithmetics64.c b/bootloader/SSL/src/gcc_arithmetics64.c deleted file mode 100644 index 3717be1..0000000 --- a/bootloader/SSL/src/gcc_arithmetics64.c +++ /dev/null @@ -1,106 +0,0 @@ -/** - * @file gcc_arithmetics64.c - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief 64bit arithmetics function for GCC - * - */ -#include - -/** - * @union gcc64 - * @brief Union for cutting 64bit integer - * - * @typedef gcc64 - * @brief gcc64 type - * - */ -typedef union gcc64 { - /** - * @brief Unsigned 64bit integer - * - */ - uint64_t u64; - /** - * @brief Signed 64bit integer - * - */ - int64_t s64; - - /** - * @brief Cutted unsigned 64bit integer - * - */ - struct { - uint32_t hi; - uint32_t lo; - } u32; - - /** - * @brief Cutted signed 64bit integer - * - */ - struct { - int32_t hi; - int32_t lo; - } s32; -} gcc64; - -/** - * @brief Divide unsigned 64bit divdend by unsigned 64bit divisor - * - * @param [in] dividend The dividend - * @param [in] divisor The divisor - * @param [out] quotient Pointer to the output quotient or NULL - * @param [out] remainder Pointer to the output remainder or NULL - */ -void unsigned_division64( - qword_t dividend, qword_t divisor, qword_t* quotient, qword_t* remainder -) { - /* Based on "Long division" algorithm - * https://en.wikipedia.org/wiki/Division_algorithm#Integer_division_(unsigned)_with_remainder - */ - - int i; - gcc64 N, D, Q, R; - N.u64 = dividend; - D.u64 = divisor; - - /* If divisor is zero cause divide exception */ - if (D.u64 == 0) { - __asm__ volatile("div %[reg]" - : - : [reg] "r"(0)); - } - Q.u64 = 0; - R.u64 = 0; - for (i = 64 - 1; i >= 0; --i) { - R.u64 = R.u64 << 1; - /* Set the least-significant bit of R equal to bit i of the numerator */ - R.u64 |= !!(N.u64 & (1ULL << i)); - if (R.u64 >= D.u64) { - R.u64 = R.u64 - D.u64; - Q.u64 |= 1ULL << i; - } - } - - if (quotient) { - *quotient = Q.u64; - } - if (remainder) { - *remainder = R.u64; - } -} - -/** - * @brief GCC interface for \ref unsigned_division64 "unsigned_division64" - * - * @param [in] a The dividend - * @param [in] b The divisor - * @param [out] c Pointer to the output remainder or NULL - * @return Quotient - */ -qword_t __udivmoddi4(qword_t a, qword_t b, qword_t* c) { - qword_t ret; - unsigned_division64(a, b, &ret, c); - return ret; -} diff --git a/bootloader/SSL/src/io.c b/bootloader/SSL/src/io.c deleted file mode 100644 index e10f459..0000000 --- a/bootloader/SSL/src/io.c +++ /dev/null @@ -1,550 +0,0 @@ -/** - * @file io.c - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Implements printf - * - */ -#include -#include -#include - -/* Leave this undocumented */ -#ifndef DOX_SKIP - -/* Write function prototype */ -typedef void (*buffer_fcn)( - void* buffer, size_t max_size, size_t index, char ch -); - -/* Write to memory buffer */ -static void _buffer_mem(void* buffer, size_t max_size, size_t index, char ch) { - if (index < max_size) { - ((char*)buffer)[index] = ch; - } -} - -/* Write to terminal */ -static void _buffer_out(void* buffer, size_t max_size, size_t index, char ch) { - (void)buffer; - (void)max_size; - (void)index; - - if (ch == '\n') { - bios_putch('\r'); - bios_putch('\n'); - } else if (ch != '\0') { - bios_putch(ch); - } -} - -/* Write to COM port */ -static void -_buffer_serial(void* buffer, size_t max_size, size_t index, char ch) { - (void)buffer; - (void)max_size; - (void)index; - - if (ch == '\n') { - bios_serial_putch('\r'); - bios_serial_putch('\n'); - } else { - bios_serial_putch(ch); - } -} - -/* Don't write */ -static void _buffer_null(void* buffer, size_t max_size, size_t index, char ch) { - (void)buffer; - (void)max_size; - (void)index; - (void)ch; -} - -/* Format flags */ -# define FLAG_LEFT (1U << 0) -# define FLAG_SIGN (1U << 1) -# define FLAG_SPACE (1U << 2) -# define FLAG_HASH (1U << 3) -# define FLAG_ZERO (1U << 4) - -/* Precision flag */ -# define FLAG_PRECISION (1U << 5) - -/* Size flags */ -# define FLAG_CHAR (1U << 6) -# define FLAG_SHORT (1U << 7) -# define FLAG_LONG (1U << 8) -# define FLAG_LONG_LONG (1U << 9) -# define FLAG_SIZE (1U << 10) -# define FLAG_PTRDIFF (1U << 11) -# define FLAG_INTMAX (1U << 12) - -/* Writes formatted output */ -static size_t _format_output( - buffer_fcn write, - void* buffer, - size_t max_size, - size_t index, - char const* output, - size_t output_size, - uint16_t flags, - uint16_t width -) { - size_t i; - char fill = flags & FLAG_ZERO ? '0' : ' '; - - if (flags & FLAG_LEFT) { - /* Left-Justification*/ - - /* Write output string first */ - for (i = 0U; i < output_size; ++i) { - write(buffer, max_size, index++, *output++); - } - - /* Pad if output_size < width */ - for (; i < width; ++i) { write(buffer, max_size, index++, fill); } - } else { - /* Right-Justification */ - - /* Calculate fill size, assuming width is unsigned (if output_size > - * width then output_size - * - width will be incorrect) */ - width = width < output_size ? 0 : width - output_size; - - /* Pad if calculated fill size > 0 */ - for (i = 0U; i < width; ++i) { write(buffer, max_size, index++, fill); } - - /* Write output string */ - for (i = 0U; i < output_size; ++i) { - write(buffer, max_size, index++, *output++); - } - } - - return index; -} - -/* Reverse string */ -static void _reverse(char* buff, size_t buff_size) { - size_t i, j; - char c; - - for (i = 0, j = buff_size - 1; i < j; ++i, --j) { - c = buff[i]; - buff[i] = buff[j]; - buff[j] = c; - } -} - -/* Hexademical ASCII alphabet */ -static char hcase_alphabet[] = "0123456789ABCDEF"; -static char lcase_alphabet[] = "0123456789abcdef"; - -/* Converts number to formatted string */ -static size_t _ntoa( - uintmax_t num, - bool negative, - uint8_t radix, - char* num_buffer, - uint16_t flags, - uint16_t precision, - bool hcase -) { - size_t index = 0U; - - /* Write digits in reverse sequence */ - do { - num_buffer[index++] = - (hcase ? hcase_alphabet : lcase_alphabet)[num % radix]; - } while ((num /= radix) > 0); - - /* Pad number if precision > index */ - if (flags & FLAG_PRECISION) { - while (index < precision) { num_buffer[index++] = '0'; } - } - - /* Add prefix */ - if (flags & FLAG_HASH) { - if (radix == 16) { - num_buffer[index++] = hcase ? 'X' : 'x'; - } - if (radix % 8 == 0) { - num_buffer[index++] = '0'; - } - } - - /* Write sign */ - if (negative) { - num_buffer[index++] = '-'; - } else if (flags & FLAG_SIGN) { - num_buffer[index++] = '+'; - } else if (flags & FLAG_SPACE) { - num_buffer[index++] = ' '; - } - - /* Reverse buffer */ - _reverse(num_buffer, index); - - return index; -} - -/* Internal vsnprintf */ -static int _vsnprintf( - void* buffer, - size_t max_size, - char const* format, - va_list va, - buffer_fcn write -) { - size_t index = 0U, num_size; - uint16_t flags, width, precision; - bool flags_loop; - uint8_t radix; - char num_buffer[32]; - - union { - char char_type; - unsigned char uchar_type; - short short_type; - unsigned short ushort_type; - int int_type; - unsigned int uint_type; - long long_type; - unsigned long ulong_type; - long long long_long_type; - unsigned long long ulong_long_type; - size_t size_type; - ptrdiff_t ptrdiff_type; - intmax_t intmax_type; - uintmax_t uintmax_type; - uintptr_t ptr_type; - } arg; - - if (!buffer) { - write = _buffer_null; - } - - while (*format) { - if (*format != '%') { - write(buffer, max_size, index++, *format++); - } else { - format++; - - /* Parse flags */ - flags = 0U; - flags_loop = true; - while (flags_loop) { - switch (*format) { - case '-': - flags |= FLAG_LEFT; - format++; - break; - case '+': - flags |= FLAG_SIGN; - format++; - break; - case ' ': - flags |= FLAG_SPACE; - format++; - break; - case '#': - flags |= FLAG_HASH; - format++; - break; - case '0': - flags |= FLAG_ZERO; - format++; - break; - default: flags_loop = false; - } - } - - /* Parse width */ - width = 0U; - if (*format == '*') { - arg.int_type = va_arg(va, int); - if (arg.int_type < 0) { - flags |= FLAG_LEFT; - width = -arg.int_type; - } else { - width = arg.int_type; - } - format++; - } else { - while ('0' <= *format && *format <= '9') { - width = (width * 10) + (*format++ - '0'); - } - } - - /* Parse precision */ - precision = 0U; - if (*format == '.') { - flags |= FLAG_PRECISION; - format++; - if (*format == '*') { - arg.int_type = va_arg(va, int); - precision = arg.int_type < 0 ? 0 : arg.int_type; - format++; - } else { - while ('0' <= *format && *format <= '9') { - precision = (precision * 10) + (*format++ - '0'); - } - } - } - - /* Parse length */ - switch (*format) { - case 'h': - flags |= FLAG_SHORT; - format++; - if (*format == 'h') { - flags |= FLAG_CHAR; - format++; - } - break; - case 'l': - flags |= FLAG_LONG; - format++; - if (*format == 'l') { - flags |= FLAG_LONG_LONG; - format++; - } - break; - case 'j': - flags |= FLAG_INTMAX; - format++; - break; - case 'z': - flags |= FLAG_SIZE; - format++; - break; - case 't': - flags |= FLAG_PTRDIFF; - format++; - break; - } - - /* Parse specifier and format output */ - switch (*format) { - case 'i': - case 'd': { - arg.intmax_type = 0U; - if (flags & FLAG_CHAR) { - arg.char_type = (char)va_arg(va, int); - } else if (flags & FLAG_SHORT) { - arg.short_type = (short)va_arg(va, int); - } else if (flags & FLAG_LONG_LONG) { - arg.long_long_type = va_arg(va, long long); - } else if (flags & FLAG_LONG) { - arg.long_type = va_arg(va, long); - } else if (flags & FLAG_INTMAX) { - arg.intmax_type = va_arg(va, intmax_t); - } else if (flags & FLAG_SIZE) { - arg.size_type = va_arg(va, size_t); - } else if (flags & FLAG_PTRDIFF) { - arg.ptrdiff_type = va_arg(va, ptrdiff_t); - } else { - arg.int_type = va_arg(va, int); - } - - num_size = _ntoa( - arg.intmax_type < 0 ? -arg.intmax_type : arg.intmax_type, - arg.intmax_type < 0, - 10, - num_buffer, - flags, - precision, - false - ); - index = _format_output( - write, buffer, max_size, index, num_buffer, num_size, flags, width - ); - - format++; - } break; - case 'u': - case 'o': - case 'x': - case 'X': { - arg.uintmax_type = 0U; - if (flags & FLAG_CHAR) { - arg.uchar_type = (unsigned char)va_arg(va, unsigned int); - } else if (flags & FLAG_SHORT) { - arg.ushort_type = (unsigned short)va_arg(va, unsigned int); - } else if (flags & FLAG_LONG_LONG) { - arg.ulong_long_type = va_arg(va, unsigned long long); - } else if (flags & FLAG_LONG) { - arg.ulong_type = va_arg(va, unsigned long); - } else if (flags & FLAG_INTMAX) { - arg.uintmax_type = va_arg(va, uintmax_t); - } else if (flags & FLAG_SIZE) { - arg.size_type = va_arg(va, size_t); - } else if (flags & FLAG_PTRDIFF) { - arg.ptrdiff_type = va_arg(va, ptrdiff_t); - } else { - arg.uint_type = va_arg(va, unsigned int); - } - - switch (*format) { - case 'u': radix = 10; break; - case 'o': radix = 8; break; - case 'x': - case 'X': radix = 16; break; - } - - num_size = _ntoa( - arg.uintmax_type, - false, - radix, - num_buffer, - flags, - precision, - *format == 'X' ? true : false - ); - index = _format_output( - write, buffer, max_size, index, num_buffer, num_size, flags, width - ); - - format++; - } break; - case 'c': { - arg.intmax_type = 0U; - if (flags & FLAG_LONG) - /* WINT_T won't be implemented */; - else { - arg.int_type = va_arg(va, int); - } - - index = _format_output( - write, - buffer, - max_size, - index, - (char const*)&arg.int_type, - 1, - flags, - width - ); - - format++; - } break; - case 's': { - arg.ptr_type = (uintptr_t)va_arg(va, void*); - if (flags & FLAG_LONG) - /* WCHAR_T won't be implemented */; - else { - index = _format_output( - write, - buffer, - max_size, - index, - (char const*)arg.ptr_type, - strlen((char const*)arg.ptr_type), - flags, - width - ); - } - - format++; - } break; - case 'p': { - arg.uintmax_type = 0U; - arg.ptr_type = (uintptr_t)va_arg(va, void*); - - flags |= FLAG_HASH; - num_size = _ntoa( - arg.uintmax_type, false, 16, num_buffer, flags, precision, false - ); - index = _format_output( - write, buffer, max_size, index, num_buffer, num_size, flags, width - ); - - format++; - } break; - case 'n': { - arg.ptr_type = (uintptr_t)va_arg(va, void*); - if (flags & FLAG_CHAR) { - *(char*)arg.ptr_type = index; - } else if (flags & FLAG_SHORT) { - *(short*)arg.ptr_type = index; - } else if (flags & FLAG_LONG_LONG) { - *(long long*)arg.ptr_type = index; - } else if (flags & FLAG_LONG) { - *(long*)arg.ptr_type = index; - } else if (flags & FLAG_INTMAX) { - *(intmax_t*)arg.ptr_type = index; - } else if (flags & FLAG_SIZE) { - *(size_t*)arg.ptr_type = index; - } else if (flags & FLAG_PTRDIFF) { - *(ptrdiff_t*)arg.ptr_type = index; - } else { - *(int*)arg.ptr_type = index; - } - - format++; - } break; - case '%': { - index = _format_output( - write, buffer, max_size, index, format++, 1, flags, width - ); - } break; - default: format++; - } - } - } - - /* Place null-terminator */ - write(buffer, max_size, index < max_size ? index : max_size - 1, '\0'); - return index; -} - -#endif /* DOX_SKIP */ - -int vsnprintf(char* s, size_t n, char const* format, va_list arg) { - return _vsnprintf(s, n, format, arg, _buffer_mem); -} - -int snprintf(char* s, size_t n, char const* format, ...) { - va_list va; - int ret; - - va_start(va, format); - ret = _vsnprintf(s, n, format, va, _buffer_mem); - va_end(va); - - return ret; -} - -int sprintf(char* s, char const* format, ...) { - va_list va; - int ret; - - va_start(va, format); - ret = _vsnprintf(s, SIZE_MAX, format, va, _buffer_mem); - va_end(va); - - return ret; -} - -int printf(char const* format, ...) { - va_list va; - char buffer[1]; - int ret; - - va_start(va, format); - ret = _vsnprintf(buffer, SIZE_MAX, format, va, _buffer_out); - va_end(va); - - return ret; -} - -int serial_printf(char const* format, ...) { - va_list va; - char buffer[1]; - int ret; - - va_start(va, format); - ret = _vsnprintf(buffer, SIZE_MAX, format, va, _buffer_serial); - va_end(va); - - return ret; -} diff --git a/bootloader/SSL/src/mem.c b/bootloader/SSL/src/mem.c deleted file mode 100644 index 740d2cc..0000000 --- a/bootloader/SSL/src/mem.c +++ /dev/null @@ -1,309 +0,0 @@ -/** - * @file mem.c - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Memory allocator - * - */ -#include -#include -#include -#include -#include - -/* Leave this undocument */ -#ifndef DOX_SKIP - -/* From bootstrap.asm */ -extern char _heap; -extern word_t _heap_size; - -/* Allocator info */ -static struct { - void* start; - size_t max_alloc; -} _mem_ctx; - -/* Block header */ -typedef struct __align(16) _block_hdr { - bool free; - size_t size; - struct _block_hdr* next; - struct _block_hdr* prev; -} - -_block_hdr; - -static size_t __inline__ _align16(size_t val) { return (val + 15) & -16; } - -static void _allocate_block(_block_hdr* after, size_t size) { - _block_hdr* new_block = - (_block_hdr*)((byte_t*)after + after->size + sizeof(_block_hdr)); - new_block->free = true; - new_block->size = size; - - new_block->prev = after; - new_block->next = after->next; - - new_block->prev->next = new_block; - if (new_block->next != NULL) { - new_block->next->prev = new_block; - } -} - -static void _find_max_block(void) { - _block_hdr* block; - - _mem_ctx.max_alloc = 0; - for (block = (_block_hdr*)_mem_ctx.start; block != NULL; - block = block->next) { - if (block->size > _mem_ctx.max_alloc) { - _mem_ctx.max_alloc = block->size; - } - } -} - -static _block_hdr* _merge_blocks(_block_hdr* up, _block_hdr* down) { - _block_hdr* next = down->next; - - up->size += sizeof(_block_hdr) + down->size; - - up->next = down->next; - if (next != NULL) { - next->prev = down->prev; - } - - return up; -} - -#endif /* DOX_SKIP */ - -bool mem_init(void) { - _block_hdr* initial_block; - - _mem_ctx.start = (void*)_align16((size_t)&_heap); - - initial_block = (_block_hdr*)_mem_ctx.start; - initial_block->free = true; - initial_block->size = _heap_size - - ((ptrdiff_t)_mem_ctx.start - (ptrdiff_t)&_heap) - - sizeof(_block_hdr); - initial_block->next = NULL; - initial_block->prev = NULL; - - _mem_ctx.max_alloc = initial_block->size; - - return true; -} - -void* malloc(size_t count) { - _block_hdr* free_block; - bool block_found; - size_t block_left; - - /* Align bytes count */ - count = _align16(count); - if (count > _mem_ctx.max_alloc) { - return NULL; - } - - /* Find suitable free block */ - block_found = false; - for (free_block = (_block_hdr*)_mem_ctx.start; free_block != NULL; - free_block = free_block->next) { - if (free_block->free && free_block->size >= count) { - block_found = true; - break; - } - } - if (!block_found) { - return NULL; - } - - /* Try to allocate new free block */ - block_left = free_block->size - count; - free_block->free = false; - free_block->size = count; - if (block_left < sizeof(_block_hdr) + 16) { - free_block->size += block_left; - } else { - _allocate_block(free_block, block_left - sizeof(_block_hdr)); - } - - /* Find new max block */ - _find_max_block(); - - return (byte_t*)free_block + sizeof(_block_hdr); -} - -void* realloc(void* mem, size_t new_size) { - _block_hdr* block = (_block_hdr*)((byte_t*)mem - sizeof(_block_hdr)); - new_size = _align16(new_size); - - if (block->size > new_size) { - /* Decrease block size */ - size_t block_left = block->size - new_size; - block->size = new_size; - if (block_left < sizeof(_block_hdr) + 16) { - /* Cannot decrease block size */ - block->size += block_left; - return mem; - } else { - /* Allocate new block from decreased size */ - _allocate_block(block, block_left - sizeof(_block_hdr)); - - /* Try to merge new block with it's next block */ - if (block->next->next && block->next->next->free) { - _merge_blocks(block->next, block->next->next); - } - - /* Find new max block */ - _find_max_block(); - return mem; - } - - } else if (block->size < new_size) { - /* Allocate new memory */ - void* new_mem; - if ((new_mem = malloc(new_size)) == NULL) { - /* Failed to allocate new memory */ - return NULL; - } - - /* Copy data to new memory */ - memcpy(new_mem, mem, block->size); - - /* Free old memory */ - free(mem); - - return new_mem; - } else { - /* No reallocation needed */ - return mem; - } -} - -void free(void* mem) { - _block_hdr* block = (_block_hdr*)((byte_t*)mem - sizeof(_block_hdr)); - - /* Mark block as free*/ - block->free = true; - - /* Try to merge free blocks */ - if (block->prev != NULL && block->prev->free) { - block = _merge_blocks(block->prev, block); - } - if (block->next != NULL && block->next->free) { - block = _merge_blocks(block, block->next); - } - - /* Update max alloc size */ - if (block->size > _mem_ctx.max_alloc) { - _mem_ctx.max_alloc = block->size; - } -} - -memory_map* get_memory_map(void) { - memory_map* mem_map; - memory_map_node* node; - dword_t offset; - - /* Allocate struct */ - if ((mem_map = malloc(sizeof(memory_map))) == NULL) { - return NULL; - } - - /* Allocate first node */ - if ((node = malloc(sizeof(memory_map_node))) == NULL) { - free(mem_map); - return NULL; - } - memset(node, 0, sizeof(memory_map_node)); - mem_map->list = node; - mem_map->count = 1; - - /* Get memory map */ - offset = 0; - do { - if (!bios_get_e820(&offset, sizeof(memory_map_entry), &node->entry)) { - while (node->prev) { - node = node->prev; - free(node->next); - } - free(node); - free(mem_map); - return NULL; - } - if (offset != 0) { - if ((node->next = malloc(sizeof(memory_map_node))) == NULL) { - while (node->prev) { - node = node->prev; - free(node->next); - } - free(node); - free(mem_map); - return NULL; - } - memset(node->next, 0, sizeof(memory_map_node)); - node->next->prev = node; - node = node->next; - ++mem_map->count; - } - } while (offset != 0); - - return mem_map; -} - -/* Leave this undocument */ -#ifndef DOX_SKIP -# ifndef NDEBUG -void _dump_heap(void) { - size_t block_index = 0; - _block_hdr* block; - - serial_printf( - "HEAP DUMP:\n" - "Start = %p\n" - "Max alloc = %zu bytes\n" - "Header size = %zu\n", - _mem_ctx.start, - _mem_ctx.max_alloc, - sizeof(_block_hdr) - ); - - for (block = (_block_hdr*)_mem_ctx.start; block != NULL; - block = block->next) { - serial_printf( - "Block %zu:\n" - " Free = %d\n" - " Block address = %p\n" - " Data address = %p\n" - " Size = %zu bytes\n" - " Prev = %p\n" - " Next = %p\n", - block_index++, - block->free, - (void*)block, - (void*)((byte_t*)block + sizeof(_block_hdr)), - block->size, - (void*)block->prev, - (void*)block->next - ); - } -} - -void _dump_memory_map(memory_map* mem_map) { - memory_map_node* node = mem_map->list; - while (node) { - serial_printf( - "Base address = %#.16llx, Limit = %#.16llx, Type = %d, ACPI = %d\n", - node->entry.base, - node->entry.limit, - node->entry.type, - node->entry.ACPI - ); - node = node->next; - } -} - -# endif /* NDEBUG */ -#endif /* DOX_SKIP */ diff --git a/bootloader/SSL/src/ssl_entry.c b/bootloader/SSL/src/ssl_entry.c deleted file mode 100644 index 7fc5652..0000000 --- a/bootloader/SSL/src/ssl_entry.c +++ /dev/null @@ -1,293 +0,0 @@ -/** - * @file ssl_entry.c - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Second Stage Loader entry - * - */ -#include -#include -#include -#include -#include -#include -#include - -/* GDT for Protected mode */ -static GDTR32 gdtr_pm; -static GDT32_entry gdt_pm[4]; - -/* GUID of booted drive */ -static byte_t drive_GUID[16]; - -/* VolgaOS partition types */ -static byte_t const kernel_partition_type[] = { - 0x98, 0xE5, 0xA9, 0x78, 0x38, 0x36, 0x67, 0x4D, - 0xB2, 0xEB, 0x01, 0x23, 0xD0, 0xAF, 0xBD, 0xBD -}; /* 78A9E598-3638-4D67-B2EB-0123D0AFBDBD */ -static byte_t const tsl_partition_type[] = { - 0xC7, 0x0D, 0x6D, 0x87, 0x66, 0xCF, 0x63, 0x4C, - 0xBC, 0xEE, 0xBD, 0x79, 0xEE, 0x10, 0xF5, 0x93 -}; /* 876D0DC7-CF66-4C63-BCEE-BD79EE10F593 */ - -/** - * @brief Print error message to screen - * - * @param error_str Error message - */ -static void print_error(char const* error_str) { - printf("VLGBL Error: %s\n", error_str); - serial_printf("VLGBL Error: %s\n", error_str); -} - -/** - * @brief Second Stage Loader entry - * - * @details `Second Stage Loader` (SSL) works in Real Mode, so it can use BIOS - * interface.\n SSL goals are:\n - * - Load `Third Stage Loader` and kernel partitions to memory - * - Get GUID of the booted drive - * - Get memory map - * - Get video modes - * - // TODO: Enable graphics mode - * - Enable A20 - * - Enable Protected Mode - * - Run `Third Stage Loader` - */ -void __noreturn ssl_entry(void) { - boot_info_t* boot_info; - - memory_map* mem_map; - - GPT_header* gpt_hdr; - GPT_partition_array* partition_array; - dword_t gpt_crc32, gpt_crc32_copy; - - GPT_partition_entry* tsl_partition; - GPT_partition_entry* kernel_partition; - - DAP read_context; - drive_parameteres drive_params; - - read_context.size = sizeof(DAP); - read_context.rsv = 0; - - /* Print loading message */ - (void)printf("Loading VLGBL...\n"); - - /* Initialize COM port */ - (void)bios_serial_init(); - - /* Check CPUID presence */ - if (!check_cpuid()) { - print_error("CPUID in not presented"); - goto halt; - } - - /* Query CPU compatibility */ - if (!check_cpu_compat()) { - print_error("CPU is not compatible"); - goto halt; - } - - /* Enable A20 line */ - if (!enable_A20()) { - print_error("Failed to enable A20"); - goto halt; - } - - /* Null descriptor */ - set_GDT32_entry(&gdt_pm[0], 0, 0, 0, 0); - - /* Protected mode 32bit code segment descriptor */ - set_GDT32_entry( - &gdt_pm[1], - 0x00000000, - 0xFFFFFFFF, - GDT_FLAG_GRANULARITY | GDT_FLAG_SIZE, - GDT_ACCESS_PRESENT | GDT_ACCESS_DPL0 | GDT_ACCESS_SEGMENT | - GDT_ACCESS_EXECUTABLE | GDT_ACCESS_READABLE - ); - - /* Protected mode 32bit data segment descriptor */ - set_GDT32_entry( - &gdt_pm[2], - 0x00000000, - 0xFFFFFFFF, - GDT_FLAG_GRANULARITY | GDT_FLAG_SIZE, - GDT_ACCESS_PRESENT | GDT_ACCESS_DPL0 | GDT_ACCESS_SEGMENT | - GDT_ACCESS_WRITEABLE - ); - - /* Long mode 64bit code segment descriptor */ - set_GDT32_entry( - &gdt_pm[3], - 0x00000000, - 0xFFFFFFFF, - GDT_FLAG_GRANULARITY | GDT_FLAG_LONG, - GDT_ACCESS_PRESENT | GDT_ACCESS_DPL0 | GDT_ACCESS_SEGMENT | - GDT_ACCESS_EXECUTABLE | GDT_ACCESS_READABLE - ); - - /* Fill Protected mode GDTR */ - set_GDTR32(&gdtr_pm, gdt_pm, 4); - - /* Load Protected mode GDT */ - load_GDT32(gdtr_pm); - - /* Enable Unreal Mode */ - enter_unreal(2 * sizeof(GDT32_entry)); - - /* Initialize allocator */ - if (!mem_init()) { - print_error("Failed to initialize allocator"); - goto halt; - } - - /* Get memory map */ - if ((mem_map = get_memory_map()) == NULL) { - print_error("Failed to get memory map"); - goto halt; - } - - /* Check drive logical sector size */ - drive_params.size = sizeof(drive_parameteres); - if (!bios_get_drive_parameteres(&drive_params)) { - print_error("Failed to get drive paramteres"); - goto halt; - } - if (drive_params.sector_size != SECTOR_SIZE) { - print_error("Wrong sector size, aborting"); - goto halt; - } - - /* Read GPT header */ - if ((gpt_hdr = malloc(SECTOR_SIZE)) == - NULL) { /* Allocate enough space for reading a sector */ - print_error("Failed to read GPT header."); - goto halt; - } - - read_context.sectors = 1; - read_context.segment = get_ds(); - read_context.offset = (word_t)((uintptr_t)gpt_hdr & 0xFFFF); - read_context.lba = 1; /* GPT header always located at LBA 1 */ - - if (!bios_read_drive(&read_context)) { - print_error("Failed to read GPT header."); - goto halt; - } - if ((gpt_hdr = realloc(gpt_hdr, sizeof(GPT_header))) == - NULL) { /* GPT header size is less than sector size, so we should - reallocate it to reduce use of memory */ - print_error("Failed to read GPT header."); - goto halt; - } - - /* Check GPT Signature */ - if (memcmp(gpt_hdr->magic, "EFI PART", 8) != 0) { - print_error("Drive is not GPT"); - goto halt; - } - - /* Compare GPT checksum */ - gpt_crc32_copy = gpt_hdr->crc32; - gpt_hdr->crc32 = - 0; /* GPT CRC32 checksum must be counted with CRC32 field being zero */ - gpt_crc32 = crc32((byte_t*)gpt_hdr, sizeof(GPT_header)); - if (gpt_crc32 != gpt_crc32_copy) { - print_error("GPT header is corrupted. CRC32 mismatch"); - goto halt; - } - - /* Save drive GUID */ - (void)memcpy(drive_GUID, gpt_hdr->guid, 16); - - /* Get partition table */ - if ((partition_array = get_partition_array(gpt_hdr)) == NULL) { - print_error("Failed to get partition table"); - goto halt; - } - - /* Find Third Stage Loader partition */ - if ((tsl_partition = find_partition(partition_array, tsl_partition_type)) == - NULL) { - print_error("Failed to find Third Stage Loader partition"); - goto halt; - } - - /* Find kernel partition */ - if ((kernel_partition = - find_partition(partition_array, kernel_partition_type)) == NULL) { - print_error("Failed to find kernel partition"); - goto halt; - } - - /* Load Third Stage Loader */ - read_context.segment = TSL_SEG; - read_context.offset = 0x0000; - read_context.sectors = tsl_partition->end_lba - tsl_partition->start_lba + 1; - read_context.lba = tsl_partition->start_lba; - if (!bios_read_drive(&read_context)) { - print_error("Failed to load Third Stage Loader"); - goto halt; - } - - /* Load Kernel */ - if (!load_kernel(kernel_partition, 0x100000)) { - print_error("Failed to load kernel"); - goto halt; - } - - /* Create boot info */ - if ((boot_info = create_boot_info(drive_GUID, mem_map, 0x100000)) == NULL) { - print_error("Failed to create boot info"); - goto halt; - } - - /* Used for debug */ - dump_heap(); - dump_memory_map(mem_map); - - /* Finalize Second Stage Loader */ - __asm__ volatile( - "cli\n" - "movb $0xFF, %%al\n" /* Disable PIC */ - "outb %%al, $0xA1\n" - "outb %%al, $0x21\n" - - "movl %%cr0, %%eax\n" /* Set CR0 PE bit */ - "orb $1, %%al\n" - "movl %%eax, %%cr0\n" - - "jmp .pm\n" /* Clear instruction pipeline */ - ".pm:\n" - - "movw %[data_seg], %%ax\n" /* Set 32bit segments */ - "movw %%ax, %%ds\n" - "movw %%ax, %%es\n" - "movw %%ax, %%ss\n" - "movw %%ax, %%fs\n" - "movw %%ax, %%gs\n" - - "xorl %%eax, %%eax\n" /* Fix stack pointer */ - "movw %%cs, %%ax\n" - "shll $4, %%eax\n" - "andl $0xFFFF, %%esp\n" - "addl %%eax, %%esp\n" - - "movb $0xE9, (0x0000)\n" /* Make jump stub */ - "movl %[jmp_addr], (0x0001)\n" - - "pushl %[boot_info]\n" - "ljmp %[code_seg],$0x0000" /* Jump to Third Stage Loader */ - : - : [data_seg] "rmN"((word_t)2 * sizeof(GDT32_entry)), - [jmp_addr] "rmN"((dword_t)TSL_ADDR - 5), - [code_seg] "N"((word_t)1 * sizeof(GDT32_entry)), - [boot_info] "rmN"((dword_t)boot_info + ((dword_t)get_ds() << 4)) - : "eax" - ); - -halt: - while (1) { __asm__ volatile("hlt"); } -} diff --git a/bootloader/SSL/src/string.c b/bootloader/SSL/src/string.c deleted file mode 100644 index f640001..0000000 --- a/bootloader/SSL/src/string.c +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @file string.c - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Functions for manipulating c-strings and buffers - * - */ -#include - -size_t strlen(char const* start) { - char const* end; - for (end = start; *end != '\0'; ++end) - ; - return end - start; -} - -int memcmp(void const* lhs, void const* rhs, size_t count) { - while (count--) { - if (*(byte_t*)lhs != *(byte_t*)rhs) { - return (uintptr_t)lhs - (uintptr_t)rhs; - } - lhs = (byte_t*)lhs + 1; - rhs = (byte_t*)rhs + 1; - } - return 0; -} - -void* memcpy(void* dest, void const* src, size_t count) { - size_t i; - for (i = 0; i < count; ++i) { ((byte_t*)dest)[i] = ((byte_t*)src)[i]; } - return dest; -} - -void* memset(void* ptr, int val, size_t count) { - byte_t* data = (byte_t*)ptr; - while (count--) { *data++ = (byte_t)val; } - return ptr; -} diff --git a/bootloader/SSL/src/utils.c b/bootloader/SSL/src/utils.c deleted file mode 100644 index 5a3824d..0000000 --- a/bootloader/SSL/src/utils.c +++ /dev/null @@ -1,550 +0,0 @@ -/** - * @file utils.c - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Utility functions used for Second Stage Loader - * - */ -#include -#include -#include -#include - -/* CRC32 polynom table */ -static uint32_t const crc32table[256] = { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, - 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, - 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, - 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, - 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, - 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, - 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, - 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, - 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, - 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, - 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, - 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, - 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, - 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, - 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, - 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, - 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, - 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, - 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, - 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, - 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, - 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -}; - -/* Null partition type GUID */ -static byte_t const null_partition_type[] = { 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }; - -word_t get_ds(void) { - word_t ds; - __asm__ volatile("movw %%ds, %[ds]" - : [ds] "=r"(ds)); - return ds; -} - -uint32_t crc32(byte_t const* buf, size_t len) { - uint32_t crc = 0xFFFFFFFF; - while (len--) { crc = (crc >> 8) ^ crc32table[(crc ^ *buf++) & 0xFF]; } - return crc ^ 0xFFFFFFFF; -} - -/* Check if A20 is enabled */ -static bool _check_A20(void) { - bool ret; - word_t const test_offset = 0x7C00; - word_t const failure_offset = (((dword_t)0xFFFF << 4) + test_offset) & 0xFFFF; - /* Try to access byte at address FFFF:7C00 - * Physical address of FFFF:7C00 is (0xFFFF << 4) + 0x7C00 = 0x107BF0 - * If A20 is disabled 0x107BF0 becomes 0x7BF0 - */ - __asm__ volatile( - "cli\n" - - "pushw %%es\n" /* Save ES and DS */ - "pushw %%ds\n" - - "xorw %%ax, %%ax\n" - "movw %%ax, %%es\n" /* ES = 0x0000 */ - - "notw %%ax\n" - "movw %%ax, %%ds\n" /* DS = 0xFFFF */ - - "movw %[test_offset], %%si\n" /* SI = test_offset, test address = DS:SI */ - "movw %[failure_offset], %%di\n" /* DI = failure_offset, failure address = - ES:DI */ - - "movb %%ds:(%%si), %%al\n" /* Save byte at test address */ - "pushw %%ax\n" - - "movb %%es:(%%di), %%al\n" /* Save byte at failure address */ - "pushw %%ax\n" - - "movb $0x00, %%es:(%%di)\n" /* Place 0x00 at failure address */ - "movb $0xFF, %%ds:(%%si)\n" /* Place 0xFF at test address */ - - "cmpb $0x00, %%es:(%%di)\n" /* Check if failure address is still 0x00 */ - - "popw %%ax\n" /* Restore value from failure address */ - "movb %%al, %%es:(%%di)\n" - - "popw %%ax\n" /* Restore value from test address */ - "movb %%al, %%ds:(%%si)\n" - - "popw %%ds\n" /* Restore ES and DS */ - "popw %%es\n" - - "sti" - : "=@ccz"(ret) - : [test_offset] "rm"(test_offset), [failure_offset] "rm"(failure_offset) - : "ax", "di", "si" - ); - return ret; -} - -static byte_t __inline__ _inb(word_t port) { - byte_t ret; - __asm__ volatile("inb %[port], %[ret]" - : [ret] "=a"(ret) - : [port] "Nd"(port)); - return ret; -} - -static void __inline__ _outb(word_t port, byte_t val) { - __asm__ volatile("outb %[val], %[port]" - : - : [val] "a"(val), [port] "Nd"(port)); -} - -bool enable_A20(void) { - bool CF; - byte_t kb_data; - - /* Check if A20 is already enabled */ - if (_check_A20()) { - return true; - } - - /* Try BIOS method */ - __asm__ volatile("int $0x15" - : "=@ccc"(CF) - : "a"((word_t)0x2401)); - if (!CF && _check_A20()) { - return true; - } - - /* Try keyboard controller method */ - while (_inb(0x64) & 2) { continue; } - _outb(0x64, 0xAD); /* Disable PS/2 port */ - - while (_inb(0x64) & 2) { continue; } - _outb(0x64, 0xD0); /* Prepare to read data-output port */ - - while (!(_inb(0x64) & 1)) { continue; } - kb_data = _inb(0x60); /* Read data-output port */ - - while (_inb(0x64) & 2) { continue; } - _outb(0x64, 0xD1); /* Prepare to write to data-output port */ - - while (_inb(0x64) & 2) { continue; } - _outb(0x60, kb_data | 2); /* Set A20 gate bit */ - - while (_inb(0x64) & 2) { continue; } - _outb(0x64, 0xAE); /* Enable PS/2 port */ - - while (_inb(0x64) & 2) { continue; } - - if (_check_A20()) { - return true; - } - - /* Try Fast A20 method */ - _outb(0x92, _inb(0x92) | 2); - if (_check_A20()) { - return true; - } - - return false; -} - -void set_GDT32_entry( - GDT32_entry* entry, - dword_t base, - dword_t limit, - GDT_flags flags, - GDT_access access -) { - *(word_t*)&entry->data[0] = (word_t)limit; - *(word_t*)&entry->data[2] = (word_t)base; - *(byte_t*)&entry->data[4] = (byte_t)(base >> 16); - *(byte_t*)&entry->data[5] = (byte_t)access; - *(byte_t*)&entry->data[6] = (byte_t)((flags << 4) | ((limit >> 16) & 0x0F)); - *(byte_t*)&entry->data[7] = (byte_t)(base >> 24); -} - -void set_GDTR32(GDTR32* gdtr, GDT32_entry const* gdt32_table, size_t count) { - *(word_t*)&gdtr->data[0] = sizeof(GDT32_entry) * count - 1; - *(dword_t*)&gdtr->data[2] = ((dword_t)get_ds() << 4) | (dword_t)gdt32_table; -} - -void load_GDT32(GDTR32 gdtr) { - __asm__ volatile("lgdt %[gdtr]" - : - : [gdtr] "m"(gdtr)); -} - -void enter_unreal(word_t data_segment_offset) { - __asm__ volatile( - "cli\n" /* Save real mode segments and disable interrupts */ - "pushw %%ds\n" - "pushw %%es\n" - - "movl %%cr0, %%eax\n" /* Enter Protected mode */ - "orb $1, %%al\n" - "movl %%eax, %%cr0\n" - - "jmp .pm\n" /* Clear CPU intstruction cache */ - ".pm:\n" - - "movw %[seg], %%bx\n" /* Load data descriptor */ - "movw %%bx, %%ds\n" - "movw %%bx, %%es\n" - - "andb $0xFE, %%al\n" /* Enter Unreal mode by disabling Protected mode */ - "mov %%eax, %%cr0\n" - - "popw %%es\n" /* Restore real mode segments and enable interrupts */ - "popw %%ds\n" - "sti" - : - : [seg] "rm"(data_segment_offset) - : "eax", "bx" - ); -} - -GPT_partition_array* get_partition_array(GPT_header const* gpt_hdr) { - GPT_partition_array* partition_array; - dword_t partition_table_size; - DAP read_context; - size_t li, ri; - GPT_partition_entry *lp, *rp; - - /* Allocate struct */ - if ((partition_array = malloc(sizeof(GPT_partition_array))) == NULL) { - return NULL; - } - partition_array->entry_size = gpt_hdr->entry_size; - - /* Prepare DAP */ - memset(&read_context, 0, sizeof(DAP)); - read_context.size = sizeof(DAP); - read_context.segment = get_ds(); - - /* Calculate size of array */ - partition_table_size = gpt_hdr->entries_count * gpt_hdr->entry_size; - - /* Calculate count of sectors to read */ - read_context.sectors = - (word_t)(partition_table_size / SECTOR_SIZE + - (partition_table_size % SECTOR_SIZE == 0 ? 0 : 1)); - - /* Allocate enough space for reading partition array */ - if ((partition_array->array = malloc(read_context.sectors * 512)) == NULL) { - free(partition_array); - return NULL; - } - - /* Read partition array */ - read_context.offset = (word_t)((uintptr_t)partition_array->array); - read_context.lba = gpt_hdr->partition_array; - if (!bios_read_drive(&read_context)) { - free(partition_array->array); - free(partition_array); - return NULL; - } - - /* Remove empty entries */ - li = 0; - lp = partition_array->array; - - while (true) { - /* Move left pointer to empty entry */ - while (li < gpt_hdr->entries_count && - memcmp(lp->type, null_partition_type, 16) != 0) { - ++li; - lp = (GPT_partition_entry*)(((byte_t*)lp) + partition_array->entry_size); - } - - /* Move right pointer to the first valid entry after left pointer */ - ri = li; - rp = lp; - while (ri < gpt_hdr->entries_count) { - if (memcmp(rp->type, null_partition_type, 16) != 0) { - break; - } - ++ri; - rp = (GPT_partition_entry*)(((byte_t*)rp) + partition_array->entry_size); - } - - /* Move entry from right pointer to left pointer */ - if (li < gpt_hdr->entries_count && ri < gpt_hdr->entries_count) { - memcpy(lp, rp, partition_array->entry_size); - memset(rp, 0, partition_array->entry_size); - } else { - break; - } - } - partition_array->count = li; - - /* Reallocate array with less size */ - if ((partition_array->array = realloc( - partition_array->array, - partition_array->entry_size * partition_array->count - )) == NULL) { - free(partition_array->array); - free(partition_array); - return NULL; - } - - return partition_array; -} - -GPT_partition_entry* -find_partition(GPT_partition_array const* partition_array, byte_t const* GUID) { - GPT_partition_entry* partition = partition_array->array; - size_t count = partition_array->count; - while (count--) { - if (memcmp(partition->type, GUID, 16) == 0) { - return partition; - } - partition = (GPT_partition_entry*)(((byte_t*)partition) + - partition_array->entry_size); - } - return NULL; -} - -static bool _query_video_bios(dword_t* type, dword_t* address) { - video_lintext* video_info; - word_t ax, bx; - byte_t cf; - - __asm__ volatile("int $0x10" - : "=a"(ax), "=b"(bx), "=ccc"(cf) - : "a"((word_t)0x0F00)); - - if (cf) { - return false; - } else { - if ((video_info = malloc(sizeof(video_lintext))) == NULL) { - return false; - } - video_info->mode = ax & 0xFF; - video_info->seg = 0xB800; - video_info->cols = (ax >> 8) & 0xFF; - video_info->rows = 25; - - *type = BOOT_VIDEO_LINTEXT; - *address = (dword_t)video_info; - return true; - } -} - -static void _query_video(dword_t* type, dword_t* address) { - dword_t ret_type = BOOT_VIDEO_NOVIDEO; - dword_t ret_addr = 0; - - _query_video_bios(&ret_type, &ret_addr); - - *type = ret_type; - *address = ret_addr; -} - -bool load_kernel(GPT_partition_entry const* partition, dword_t address) { - void* buffer; - DAP read_context; - qword_t i; - qword_t sectors_count = partition->end_lba - partition->start_lba + 1; - - address -= (dword_t)get_ds() << 4; - - if ((buffer = malloc(SECTOR_SIZE)) == NULL) { - return false; - } - - read_context.size = sizeof(DAP); - read_context.rsv = 0; - read_context.sectors = 1; - read_context.segment = get_ds(); - read_context.offset = (word_t)(uintptr_t)buffer; - read_context.lba = partition->start_lba; - - for (i = 0; i < sectors_count; ++i) { - if (!bios_read_drive(&read_context)) { - free(buffer); - return false; - } - memcpy((byte_t*)address + (i * SECTOR_SIZE), buffer, SECTOR_SIZE); - ++read_context.lba; - } - - free(buffer); - return true; -} - -boot_info_t* create_boot_info( - byte_t const* drive_GUID, memory_map* mem_map, qword_t ramfs_addr -) { - boot_info_t* boot_info; - memory_map_entry* mem_map_array; - memory_map_node* mem_map_node; - dword_t video_type; - dword_t video_addr; - size_t i; - - if ((boot_info = malloc(sizeof(boot_info_t))) == NULL) { - return NULL; - } - - /* Fill boot info size */ - boot_info->size = sizeof(boot_info_t); - - /* Fill boot drive info */ - memcpy(boot_info->boot_drive.GUID, drive_GUID, 16); - - /* Convert memory map list to array */ - if ((mem_map_array = malloc(sizeof(memory_map_entry) * mem_map->count)) == - NULL) { - free(boot_info); - return NULL; - } - for (i = 0, mem_map_node = mem_map->list; - i < mem_map->count && mem_map_node != NULL; - ++i, mem_map_node = mem_map_node->next) { - memcpy(&mem_map_array[i], &mem_map_node->entry, sizeof(memory_map_entry)); - } - - /* Fill memory map info */ - boot_info->memory_map.entry_size = sizeof(memory_map_entry); - boot_info->memory_map.count = mem_map->count; - boot_info->memory_map.address = - (dword_t)mem_map_array + ((dword_t)get_ds() << 4); - - /* Fill video info */ - _query_video(&video_type, &video_addr); - boot_info->video_info.type = video_type; - boot_info->video_info.address = video_addr + ((dword_t)get_ds() << 4); - - /* Fill RAMFS info */ - boot_info->RAMFS.address = ramfs_addr; - - return boot_info; -} - -bool check_cpuid(void) { - bool ret; - __asm__ volatile( - "pushfl\n" - "popl %%eax\n" /* Move EFLAGS to EAX */ - - "movl %%eax, %%ebx\n" /* Save original EFLAGS to EBX*/ - - "xorl $0x200000, %%eax\n" /* Change ID bit */ - - "pushl %%eax\n" - "popfl\n" /* Load Updated EFLAGS */ - - "pushfl\n" - "popl %%eax\n" /* Move Updated EFLAGS to EAX */ - - "xorl %%eax, %%ebx" /* Check ID bit */ - : "=@ccz"(ret) - : - : "eax", "ebx" - ); - return !ret; -} - -static void _cpuid(dword_t* eax, dword_t* ebx, dword_t* ecx, dword_t* edx) { - __asm__("cpuid" - : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) - : "a"(*eax)); -} - -/* CPUID EAX = 1: EDX */ -#define CPUID_PSE (1 << 3) -#define CPUID_MSR (1 << 5) -#define CPUID_PAE (1 << 6) -#define CPUID_APIC (1 << 9) -#define CPUID_PGE (1 << 13) -#define CPUID_PAT (1 << 16) -#define CPUID_ACPI (1 << 22) - -/* CPUID EAX = 1: ECX */ -#define CPUID_SSE3 (1 << 0) -#define CPUID_SSE41 (1 << 19) -#define CPUID_SSE42 (1 << 20) -#define CPUID_x2APIC (1 << 21) -#define CPUID_AVX (1 << 28) - -/* CPUID EAX = 0x80000001: EDX */ -#define CPUID_SYSCALL (1 << 11) -#define CPUID_NX (1 << 20) -#define CPUID_PG1G (1 << 26) -#define CPUID_LM (1 << 29) - -bool check_cpu_compat(void) { - dword_t eax, ebx, ecx, edx; - dword_t cpuid_max, cpuid_ext_max; - - eax = 0; - _cpuid(&eax, &ebx, &ecx, &edx); - cpuid_max = eax; - - eax = 0x80000000; - _cpuid(&eax, &ebx, &ecx, &edx); - cpuid_ext_max = eax; - - if (cpuid_max < 1 && cpuid_ext_max < 0x80000001) { - return false; - } - - eax = 1; - _cpuid(&eax, &ebx, &ecx, &edx); - if (!(edx & CPUID_PAE)) { - return false; - } - - eax = 0x80000001; - _cpuid(&eax, &ebx, &ecx, &edx); - if (!(edx & CPUID_LM) || !(edx & CPUID_PG1G)) { - return false; - } - - return true; -} diff --git a/bootloader/TSL/CMakeLists.txt b/bootloader/TSL/CMakeLists.txt deleted file mode 100644 index 4692dc1..0000000 --- a/bootloader/TSL/CMakeLists.txt +++ /dev/null @@ -1,73 +0,0 @@ -cmake_minimum_required(VERSION 3.20) -project(${TSL_TARGET} - DESCRIPTION "Third Stage Loader" - LANGUAGES C ASM_NASM -) - -# TSL Sources -file(GLOB_RECURSE C_SRCS "src/*.c") -file(GLOB_RECURSE ASM_SRCS "src/*.asm") -file(GLOB_RECURSE HDRS "include/*.h") -list(APPEND SRCS ${C_SRCS} ${ASM_SRCS}) - -# LD Script -set(LD_SCRIPT "${PROJECT_SOURCE_DIR}/TSL.ld") - -# Output symbols map -set(SYM_MAP "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.map") - -# Compile options -list(APPEND C_OPTIONS - ${C_DIALECT} - ${C_OPTIMIZATION} - ${C_INSTRUMENTATION} - ${C_GENERATION} - ${C_x86_32} -) -list(APPEND ASM_OPTIONS - ${ASM_OPTIMIZATION} - ${ASM_GENERATION} -) - -# Link options -list(APPEND LINK_OPTIONS - ${LINK_FLAGS} - "-m32" -) - -# Configure Sources -set_source_files_properties(${C_SRCS} PROPERTIES - LANGUAGE C - COMPILE_OPTIONS "${C_OPTIONS}" -) -set_source_files_properties(${ASM_SRCS} PROPERTIES - LANGUAGE ASM_NASM - COMPILE_OPTIONS "${ASM_OPTIONS}" -) - -# Add TSL target -add_executable(${PROJECT_NAME} EXCLUDE_FROM_ALL ${SRCS} ${HDRS}) -target_include_directories(${PROJECT_NAME} PRIVATE "include") - -# Configure linking -target_link_options(${PROJECT_NAME} PRIVATE ${LINK_OPTIONS}) -set_target_properties(${PROJECT_NAME} PROPERTIES - LINK_DEPENDS ${LD_SCRIPT} - LINK_FLAGS "-Xlinker --oformat=binary -Xlinker -Map=${SYM_MAP} -T ${LD_SCRIPT}" -) - -# Generate docs -if(BUILD_DOCS) - set(DOXYGEN_OUTPUT_DIRECTORY ${OUTPUT_DOCS}/VolgaBL/TSL) - set(DOXYGEN_PROJECT_NAME "TSL") - set(DOXYGEN_PROJECT_BRIEF "Third Stage Loader") - #set(DOXYGEN_PROJECT_NUMBER ${VLGBL_VERSION}) - set(DOXYGEN_MACRO_EXPANSION YES) - set(DOXYGEN_EXPAND_ONLY_PREDEF NO) - list(APPEND DOXYGEN_PREDEFINED - "__attribute__(x)=" - "__bool_true_false_are_defined" - "DOX_SKIP" - ) - doxygen_add_docs(${TSL_DOCS}) -endif(BUILD_DOCS) diff --git a/bootloader/TSL/TSL.ld b/bootloader/TSL/TSL.ld deleted file mode 100644 index 535a727..0000000 --- a/bootloader/TSL/TSL.ld +++ /dev/null @@ -1,32 +0,0 @@ -OUTPUT(binary) -ENTRY(__bootstrap) -MEMORY -{ - TSL_segment (rwx) : ORIGIN = 0x00020000, LENGTH = 0x00010000 -} -SECTIONS -{ - .text : - { - BYTE(0xE9); - LONG(__bootstrap - 5 - 0x20000); - *(.text) - } > TSL_segment - .rodata : - { - *(.rodata*) - } > TSL_segment - .data : - { - *(.data) - } > TSL_segment - .bss (NOLOAD) : - { - *(.bss) - } > TSL_segment - /DISCARD/ : - { - *(.note*) - *(.comment*) - } -} \ No newline at end of file diff --git a/bootloader/TSL/include/bl/defines.h b/bootloader/TSL/include/bl/defines.h deleted file mode 100644 index 0f25cc6..0000000 --- a/bootloader/TSL/include/bl/defines.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef BL_DEFINES_H -#define BL_DEFINES_H - -#define __stdcall __attribute__((stdcall)) -#define __noreturn __attribute__((noreturn)) -#define __packed __attribute__((packed)) -#define __unused __attribute__((unused)) -#define __print_fmt(fmt, va) __attribute__((format(printf, fmt, va))) -#define __check_ret __attribute__((warn_unused_result)) -#define __align(n) __attribute__((aligned(n))) - -#endif /* BL_DEFINES_H */ diff --git a/bootloader/TSL/include/bl/io.h b/bootloader/TSL/include/bl/io.h deleted file mode 100644 index 0024fcb..0000000 --- a/bootloader/TSL/include/bl/io.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @file io.h - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Implements printf - * - */ -#ifndef BL_IO_H -#define BL_IO_H - -#include "types.h" - -#include - -/** - * @brief Write formatted data from variable argument list to sized buffer - * - * @param [out] s Pointer to a buffer where the resulting C-string is stored - * @param [in] n Maximum number of bytes to be used in the buffer - * @param [in] format C-string that contains a format string - * @param [in] arg A value identifying a variable arguments list initialized - * with va_start - * @return The number of characters that would have been written if n had been - * sufficiently large, not counting the terminating null character - */ -int vsnprintf(char* s, size_t n, char const* format, va_list arg); - -/** - * @brief Write formatted output to sized buffer - * - * @param [out] s Pointer to a buffer where the resulting C-string is stored - * @param [in] n Maximum number of bytes to be used in the buffer - * @param [in] format C-string that contains a format string - * @param [in out] ... Additional args - * @return The number of characters that would have been written if n had been - * sufficiently large, not counting the terminating null character - */ -int __print_fmt(3, 4) snprintf(char* s, size_t n, char const* format, ...); - -/** - * @brief Write formatted data to string - * - * @param [out] s Pointer to a buffer where the resulting C-string is stored - * @param [in] format C-string that contains a format string - * @param [in] ... Additional args - * @return The number of characters that would have been written if n had been - * sufficiently large, not counting the terminating null character - */ -int __print_fmt(2, 3) sprintf(char* s, char const* format, ...); - -/** - * @brief Print formatted data to COM port - * - * @param [in] format C-string that contains a format string - * @param [in] ... Additional args - * @return The number of characters that would have been written if n had been - * sufficiently large, not counting the terminating null character - */ -int __print_fmt(1, 2) serial_printf(char const* format, ...); - -#endif /* BL_IO_H */ diff --git a/bootloader/TSL/include/bl/pe.h b/bootloader/TSL/include/bl/pe.h deleted file mode 100644 index 4b4f8f1..0000000 --- a/bootloader/TSL/include/bl/pe.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef BL_PE_H -#define BL_PE_H - -#include -#include - -typedef struct pe_load_state { - char name[256]; - dword_t load_addr; - dword_t image_size; - dword_t entry; - dword_t stack_size; -} pe_load_state; - -/** - * @brief Initialize PE loader - * - * @param [in] start Beginning of memory where PE images are put - * @return true on success - * @return false on failure - */ -bool pe_loader_init(void* start); - -/** - * @brief Get memory range used for loading PE images - * - * @param [out] begin Begin of memory range - * @param [out] end End of memory range - */ -void pe_get_memory_range(dword_t* begin, dword_t* end); - -/** - * @brief Load PE into memory - * - * @param [in] file Full path to PE file in RAMFS - * @param [out] state Result of loading - * @return true on success - * @return false on failure - */ -bool pe_load(char const* filename, pe_load_state** state); - -#endif diff --git a/bootloader/TSL/include/bl/ramfs.h b/bootloader/TSL/include/bl/ramfs.h deleted file mode 100644 index f938280..0000000 --- a/bootloader/TSL/include/bl/ramfs.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @file ramfs.h - * @author Arseny Lashkevicj (arsenez@cybercommunity.space) - * @brief Functions for reading RAMFS - * - */ -#ifndef BL_RAMFS_H -#define BL_RAMFS_H - -#include "defines.h" -#include "types.h" - -/** - * @brief Initialize RAMFS driver - * - * @param [in] address Address of RAMFS - * @return true on success - */ -bool ramfs_init(void* address); - -/** - * @brief Get memory right after RAMFS - * - * @return Pointer to the first usable block of memory after RAMFS - */ -void* ramfs_get_end(void); - -/** - * @brief Get file from RAMFS - * - * @param [in] name Full filename - * @param [out] size Actual file size - * @return Pointer to the file in memory - */ -void* ramfs_file(char const* name, size_t* size); - -#endif diff --git a/bootloader/TSL/include/bl/string.h b/bootloader/TSL/include/bl/string.h deleted file mode 100644 index 2ef5cd2..0000000 --- a/bootloader/TSL/include/bl/string.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @file string.h - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Functions for manipulating c-strings and buffers - * - */ -#ifndef BL_STRING_H -#define BL_STRING_H - -#include "types.h" - -/** - * @brief Returns the length of a given string - * - * @param [in] str Pointer to the null-terminated byte string to be examined - * @return The length of the null-terminated byte string str. - */ -size_t __check_ret strlen(char const* str); - -/** - * @brief Compares two buffers - * - * @param [in] lhs Pointer to the first buffer - * @param [in] rhs Pointer to the second buffer - * @param [in] count Number of bytes to examine - * @return Zero if lhs and rhs compare equal, or if count is zero. - */ -int __check_ret memcmp(void const* lhs, void const* rhs, size_t count); - -/** - * @brief Copies one buffer to another - * - * @param [out] dest Pointer to the object to copy to - * @param [in] src Pointer to the object to copy from - * @param [in] count Number of bytes to copy - * @return dest - */ -void* memcpy(void* dest, void const* src, size_t count); - -/** - * @brief Fills a buffer with a character - * - * @param [out] ptr Pointer to the object to fill - * @param [in] val Fill byte - * @param [in] count Number of bytes to fill - * @return ptr - */ -void* memset(void* ptr, int val, size_t count); - -#endif /* BL_STRING_H */ diff --git a/bootloader/TSL/include/bl/types.h b/bootloader/TSL/include/bl/types.h deleted file mode 100644 index 9bbace3..0000000 --- a/bootloader/TSL/include/bl/types.h +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @file types.h - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Typedefs, data structers and enums used in Third Stage Loader - * - */ -#ifndef BL_TYPES_H -#define BL_TYPES_H - -#include "defines.h" - -#include -#include - -/** - * @typedef byte_t - * @brief Byte type - * - */ -typedef uint8_t byte_t; - -/** - * @typedef word_t - * @brief Word type - * - */ -typedef uint16_t word_t; - -/** - * @typedef dword_t - * @brief Double word type - * - */ -typedef uint32_t dword_t; - -/** - * @typedef qword_t - * @brief Quad word type - * - */ -typedef uint64_t qword_t; - -#ifndef __bool_true_false_are_defined -# define __bool_true_false_are_defined - -typedef enum { false, true } bool; -#endif /* __bool_true_false_are_defined */ - -/** - * @struct boot_info_t - * @brief Boot info, passed to TSL and kernel - * - * @typedef boot_info_t - * @brief boot_info_t type - * - */ -typedef struct __packed boot_info_t { - /** - * @brief Size of this structure - * - */ - dword_t size; - - /** - * @brief Booted drive info - * - */ - struct { - /** - * @brief Booted drive GUID - * - */ - byte_t GUID[16]; - } boot_drive; - - /** - * @brief Memory map info - * - */ - struct { - /** - * @brief Count of memory map entries - * - */ - dword_t count; - /** - * @brief Size of each memory map entry - * - */ - dword_t entry_size; - /** - * @brief Physical address to memory map array - * - */ - qword_t address; - } memory_map; - - /** - * @brief Video info - * - */ - struct { - /** - * @brief Driver type - * - */ - dword_t type; - /** - * @brief Physical address to driver info - * - */ - qword_t address; - } video_info; - - /** - * @brief ACPI tables - * - */ - struct { - /** - * @brief Address of RSDP - * - */ - qword_t rsdp; - } ACPI; - - /** - * @brief RAMFS info - * - */ - struct { - /** - * @brief Physical address of RAMFS - * - */ - qword_t address; - } RAMFS; -} boot_info_t; - -#endif /* BL_TYPES_H */ diff --git a/bootloader/TSL/include/bl/utils.h b/bootloader/TSL/include/bl/utils.h deleted file mode 100644 index cade5e1..0000000 --- a/bootloader/TSL/include/bl/utils.h +++ /dev/null @@ -1,123 +0,0 @@ -/** - * @file utils.h - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Utility functions used for Third Stage Loader - * - */ -#ifndef BL_UTILS_H -#define BL_UTILS_H - -#include "defines.h" -#include "types.h" - -/** - * @brief Read byte from the port - * - * @param [in] port Port number - * @return The byte - */ -byte_t inb(word_t port); - -/** - * @brief Read word from the port - * - * @param [in] port Port number - * @return The word - */ -word_t inw(word_t port); - -/** - * @brief Read dword from the port - * - * @param [in] port Port number - * @return The dword - */ -dword_t inl(word_t port); - -/** - * @brief Send byte to the port - * - * @param [in] port Port number - * @param [in] val Byte - */ -void outb(word_t port, byte_t val); - -/** - * @brief Send word to the port - * - * @param [in] port Port number - * @param [in] val Word - */ -void outw(word_t port, word_t val); - -/** - * @brief Send dword to the port - * - * @param [in] port Port number - * @param [in] val Dword - */ -void outl(word_t port, dword_t val); - -/** - * @brief Print character to COM port - * - * @param [in] ch ASCII character to print - */ -void serial_putch(byte_t ch); - -/** - * @brief Checks if CPUID available - * - * @return true - CPUID is available - * @return false - CPUID is not available - */ -bool check_cpuid(void); - -/** - * @brief Checks CPU extensions - * - * @return true - all required extensions are present - * @return false - some of the extensions are not implemented - */ -bool check_cpu_compat(void); - -/** - * @brief Enables Physical Address Extension - * - */ -void enable_PAE(void); - -/** - * @brief Loads page table in CR3 - * - * @param address Physical address of the page table - */ -void load_page_table(void* address); - -/** - * @brief Enables Long Mode - * - */ -void enable_long_mode(void); - -/** - * @brief Enables paging - * - */ -void enable_paging(void); - -/** - * @brief Disables all PCI devices - * - */ -void disable_pci(void); - -/** - * @brief Align address to Page alignment - * - * @param addr Address to align - * @return Aligned address - */ -dword_t align_page(dword_t addr); - -#endif /* BL_UTILS_H */ diff --git a/bootloader/TSL/src/bootstrap.asm b/bootloader/TSL/src/bootstrap.asm deleted file mode 100644 index 8bc497a..0000000 --- a/bootloader/TSL/src/bootstrap.asm +++ /dev/null @@ -1,32 +0,0 @@ -cpu 686 -bits 32 - -global __bootstrap - -extern _tsl_entry - -; ------------------------------------------------------------------------------------------------- -; BSS -; ------------------------------------------------------------------------------------------------- -section .bss -; Allocate stack -stack: -align 16 -.bot: - resb 2 * 1024 -.top: - -; ------------------------------------------------------------------------------------------------- -; TEXT -; ------------------------------------------------------------------------------------------------- -section .text -__bootstrap: - ; Get boot info - pop dword eax - ; Setup stack - cld - mov esp, stack.top - - ; Call C code - push dword eax - call _tsl_entry diff --git a/bootloader/TSL/src/gcc_arithmetics64.c b/bootloader/TSL/src/gcc_arithmetics64.c deleted file mode 100644 index 3717be1..0000000 --- a/bootloader/TSL/src/gcc_arithmetics64.c +++ /dev/null @@ -1,106 +0,0 @@ -/** - * @file gcc_arithmetics64.c - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief 64bit arithmetics function for GCC - * - */ -#include - -/** - * @union gcc64 - * @brief Union for cutting 64bit integer - * - * @typedef gcc64 - * @brief gcc64 type - * - */ -typedef union gcc64 { - /** - * @brief Unsigned 64bit integer - * - */ - uint64_t u64; - /** - * @brief Signed 64bit integer - * - */ - int64_t s64; - - /** - * @brief Cutted unsigned 64bit integer - * - */ - struct { - uint32_t hi; - uint32_t lo; - } u32; - - /** - * @brief Cutted signed 64bit integer - * - */ - struct { - int32_t hi; - int32_t lo; - } s32; -} gcc64; - -/** - * @brief Divide unsigned 64bit divdend by unsigned 64bit divisor - * - * @param [in] dividend The dividend - * @param [in] divisor The divisor - * @param [out] quotient Pointer to the output quotient or NULL - * @param [out] remainder Pointer to the output remainder or NULL - */ -void unsigned_division64( - qword_t dividend, qword_t divisor, qword_t* quotient, qword_t* remainder -) { - /* Based on "Long division" algorithm - * https://en.wikipedia.org/wiki/Division_algorithm#Integer_division_(unsigned)_with_remainder - */ - - int i; - gcc64 N, D, Q, R; - N.u64 = dividend; - D.u64 = divisor; - - /* If divisor is zero cause divide exception */ - if (D.u64 == 0) { - __asm__ volatile("div %[reg]" - : - : [reg] "r"(0)); - } - Q.u64 = 0; - R.u64 = 0; - for (i = 64 - 1; i >= 0; --i) { - R.u64 = R.u64 << 1; - /* Set the least-significant bit of R equal to bit i of the numerator */ - R.u64 |= !!(N.u64 & (1ULL << i)); - if (R.u64 >= D.u64) { - R.u64 = R.u64 - D.u64; - Q.u64 |= 1ULL << i; - } - } - - if (quotient) { - *quotient = Q.u64; - } - if (remainder) { - *remainder = R.u64; - } -} - -/** - * @brief GCC interface for \ref unsigned_division64 "unsigned_division64" - * - * @param [in] a The dividend - * @param [in] b The divisor - * @param [out] c Pointer to the output remainder or NULL - * @return Quotient - */ -qword_t __udivmoddi4(qword_t a, qword_t b, qword_t* c) { - qword_t ret; - unsigned_division64(a, b, &ret, c); - return ret; -} diff --git a/bootloader/TSL/src/io.c b/bootloader/TSL/src/io.c deleted file mode 100644 index d545dad..0000000 --- a/bootloader/TSL/src/io.c +++ /dev/null @@ -1,524 +0,0 @@ -/** - * @file io.c - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Implements printf - * - */ -#include -#include -#include - -/* Leave this undocumented */ -#ifndef DOX_SKIP - -/* Write function prototype */ -typedef void (*buffer_fcn)( - void* buffer, size_t max_size, size_t index, char ch -); - -/* Write to memory buffer */ -static void _buffer_mem(void* buffer, size_t max_size, size_t index, char ch) { - if (index < max_size) { - ((char*)buffer)[index] = ch; - } -} - -/* Write to COM port */ -static void -_buffer_serial(void* buffer, size_t max_size, size_t index, char ch) { - (void)buffer; - (void)max_size; - (void)index; - - if (ch == '\n') { - serial_putch('\r'); - serial_putch('\n'); - } else { - serial_putch(ch); - } -} - -/* Don't write */ -static void _buffer_null(void* buffer, size_t max_size, size_t index, char ch) { - (void)buffer; - (void)max_size; - (void)index; - (void)ch; -} - -/* Format flags */ -# define FLAG_LEFT (1U << 0) -# define FLAG_SIGN (1U << 1) -# define FLAG_SPACE (1U << 2) -# define FLAG_HASH (1U << 3) -# define FLAG_ZERO (1U << 4) - -/* Precision flag */ -# define FLAG_PRECISION (1U << 5) - -/* Size flags */ -# define FLAG_CHAR (1U << 6) -# define FLAG_SHORT (1U << 7) -# define FLAG_LONG (1U << 8) -# define FLAG_LONG_LONG (1U << 9) -# define FLAG_SIZE (1U << 10) -# define FLAG_PTRDIFF (1U << 11) -# define FLAG_INTMAX (1U << 12) - -/* Writes formatted output */ -static size_t _format_output( - buffer_fcn write, - void* buffer, - size_t max_size, - size_t index, - char const* output, - size_t output_size, - uint16_t flags, - uint16_t width -) { - size_t i; - char fill = flags & FLAG_ZERO ? '0' : ' '; - - if (flags & FLAG_LEFT) { - /* Left-Justification*/ - - /* Write output string first */ - for (i = 0U; i < output_size; ++i) { - write(buffer, max_size, index++, *output++); - } - - /* Pad if output_size < width */ - for (; i < width; ++i) { write(buffer, max_size, index++, fill); } - } else { - /* Right-Justification */ - - /* Calculate fill size, assuming width is unsigned (if output_size > - * width then output_size - * - width will be incorrect) */ - width = width < output_size ? 0 : width - output_size; - - /* Pad if calculated fill size > 0 */ - for (i = 0U; i < width; ++i) { write(buffer, max_size, index++, fill); } - - /* Write output string */ - for (i = 0U; i < output_size; ++i) { - write(buffer, max_size, index++, *output++); - } - } - - return index; -} - -/* Reverse string */ -static void _reverse(char* buff, size_t buff_size) { - size_t i, j; - char c; - - for (i = 0, j = buff_size - 1; i < j; ++i, --j) { - c = buff[i]; - buff[i] = buff[j]; - buff[j] = c; - } -} - -/* Hexademical ASCII alphabet */ -static char hcase_alphabet[] = "0123456789ABCDEF"; -static char lcase_alphabet[] = "0123456789abcdef"; - -/* Converts number to formatted string */ -static size_t _ntoa( - uintmax_t num, - bool negative, - uint8_t radix, - char* num_buffer, - uint16_t flags, - uint16_t precision, - bool hcase -) { - size_t index = 0U; - - /* Write digits in reverse sequence */ - do { - num_buffer[index++] = - (hcase ? hcase_alphabet : lcase_alphabet)[num % radix]; - } while ((num /= radix) > 0); - - /* Pad number if precision > index */ - if (flags & FLAG_PRECISION) { - while (index < precision) { num_buffer[index++] = '0'; } - } - - /* Add prefix */ - if (flags & FLAG_HASH) { - if (radix == 16) { - num_buffer[index++] = hcase ? 'X' : 'x'; - } - if (radix % 8 == 0) { - num_buffer[index++] = '0'; - } - } - - /* Write sign */ - if (negative) { - num_buffer[index++] = '-'; - } else if (flags & FLAG_SIGN) { - num_buffer[index++] = '+'; - } else if (flags & FLAG_SPACE) { - num_buffer[index++] = ' '; - } - - /* Reverse buffer */ - _reverse(num_buffer, index); - - return index; -} - -/* Internal vsnprintf */ -static int _vsnprintf( - void* buffer, - size_t max_size, - char const* format, - va_list va, - buffer_fcn write -) { - size_t index = 0U, num_size; - uint16_t flags, width, precision; - bool flags_loop; - uint8_t radix; - char num_buffer[32]; - - union { - char char_type; - unsigned char uchar_type; - short short_type; - unsigned short ushort_type; - int int_type; - unsigned int uint_type; - long long_type; - unsigned long ulong_type; - long long long_long_type; - unsigned long long ulong_long_type; - size_t size_type; - ptrdiff_t ptrdiff_type; - intmax_t intmax_type; - uintmax_t uintmax_type; - uintptr_t ptr_type; - } arg; - - if (!buffer) { - write = _buffer_null; - } - - while (*format) { - if (*format != '%') { - write(buffer, max_size, index++, *format++); - } else { - format++; - - /* Parse flags */ - flags = 0U; - flags_loop = true; - while (flags_loop) { - switch (*format) { - case '-': - flags |= FLAG_LEFT; - format++; - break; - case '+': - flags |= FLAG_SIGN; - format++; - break; - case ' ': - flags |= FLAG_SPACE; - format++; - break; - case '#': - flags |= FLAG_HASH; - format++; - break; - case '0': - flags |= FLAG_ZERO; - format++; - break; - default: flags_loop = false; - } - } - - /* Parse width */ - width = 0U; - if (*format == '*') { - arg.int_type = va_arg(va, int); - if (arg.int_type < 0) { - flags |= FLAG_LEFT; - width = -arg.int_type; - } else { - width = arg.int_type; - } - format++; - } else { - while ('0' <= *format && *format <= '9') { - width = (width * 10) + (*format++ - '0'); - } - } - - /* Parse precision */ - precision = 0U; - if (*format == '.') { - flags |= FLAG_PRECISION; - format++; - if (*format == '*') { - arg.int_type = va_arg(va, int); - precision = arg.int_type < 0 ? 0 : arg.int_type; - format++; - } else { - while ('0' <= *format && *format <= '9') { - precision = (precision * 10) + (*format++ - '0'); - } - } - } - - /* Parse length */ - switch (*format) { - case 'h': - flags |= FLAG_SHORT; - format++; - if (*format == 'h') { - flags |= FLAG_CHAR; - format++; - } - break; - case 'l': - flags |= FLAG_LONG; - format++; - if (*format == 'l') { - flags |= FLAG_LONG_LONG; - format++; - } - break; - case 'j': - flags |= FLAG_INTMAX; - format++; - break; - case 'z': - flags |= FLAG_SIZE; - format++; - break; - case 't': - flags |= FLAG_PTRDIFF; - format++; - break; - } - - /* Parse specifier and format output */ - switch (*format) { - case 'i': - case 'd': { - arg.intmax_type = 0U; - if (flags & FLAG_CHAR) { - arg.char_type = (char)va_arg(va, int); - } else if (flags & FLAG_SHORT) { - arg.short_type = (short)va_arg(va, int); - } else if (flags & FLAG_LONG_LONG) { - arg.long_long_type = va_arg(va, long long); - } else if (flags & FLAG_LONG) { - arg.long_type = va_arg(va, long); - } else if (flags & FLAG_INTMAX) { - arg.intmax_type = va_arg(va, intmax_t); - } else if (flags & FLAG_SIZE) { - arg.size_type = va_arg(va, size_t); - } else if (flags & FLAG_PTRDIFF) { - arg.ptrdiff_type = va_arg(va, ptrdiff_t); - } else { - arg.int_type = va_arg(va, int); - } - - num_size = _ntoa( - arg.intmax_type < 0 ? -arg.intmax_type : arg.intmax_type, - arg.intmax_type < 0, - 10, - num_buffer, - flags, - precision, - false - ); - index = _format_output( - write, buffer, max_size, index, num_buffer, num_size, flags, width - ); - - format++; - } break; - case 'u': - case 'o': - case 'x': - case 'X': { - arg.uintmax_type = 0U; - if (flags & FLAG_CHAR) { - arg.uchar_type = (unsigned char)va_arg(va, unsigned int); - } else if (flags & FLAG_SHORT) { - arg.ushort_type = (unsigned short)va_arg(va, unsigned int); - } else if (flags & FLAG_LONG_LONG) { - arg.ulong_long_type = va_arg(va, unsigned long long); - } else if (flags & FLAG_LONG) { - arg.ulong_type = va_arg(va, unsigned long); - } else if (flags & FLAG_INTMAX) { - arg.uintmax_type = va_arg(va, uintmax_t); - } else if (flags & FLAG_SIZE) { - arg.size_type = va_arg(va, size_t); - } else if (flags & FLAG_PTRDIFF) { - arg.ptrdiff_type = va_arg(va, ptrdiff_t); - } else { - arg.uint_type = va_arg(va, unsigned int); - } - - switch (*format) { - case 'u': radix = 10; break; - case 'o': radix = 8; break; - case 'x': - case 'X': radix = 16; break; - } - - num_size = _ntoa( - arg.uintmax_type, - false, - radix, - num_buffer, - flags, - precision, - *format == 'X' ? true : false - ); - index = _format_output( - write, buffer, max_size, index, num_buffer, num_size, flags, width - ); - - format++; - } break; - case 'c': { - arg.intmax_type = 0U; - if (flags & FLAG_LONG) - /* WINT_T won't be implemented */; - else { - arg.int_type = va_arg(va, int); - } - - index = _format_output( - write, - buffer, - max_size, - index, - (char const*)&arg.int_type, - 1, - flags, - width - ); - - format++; - } break; - case 's': { - arg.ptr_type = (uintptr_t)va_arg(va, void*); - if (flags & FLAG_LONG) - /* WCHAR_T won't be implemented */; - else { - index = _format_output( - write, - buffer, - max_size, - index, - (char const*)arg.ptr_type, - strlen((char const*)arg.ptr_type), - flags, - width - ); - } - - format++; - } break; - case 'p': { - arg.uintmax_type = 0U; - arg.ptr_type = (uintptr_t)va_arg(va, void*); - - flags |= FLAG_HASH; - num_size = _ntoa( - arg.uintmax_type, false, 16, num_buffer, flags, precision, false - ); - index = _format_output( - write, buffer, max_size, index, num_buffer, num_size, flags, width - ); - - format++; - } break; - case 'n': { - arg.ptr_type = (uintptr_t)va_arg(va, void*); - if (flags & FLAG_CHAR) { - *(char*)arg.ptr_type = index; - } else if (flags & FLAG_SHORT) { - *(short*)arg.ptr_type = index; - } else if (flags & FLAG_LONG_LONG) { - *(long long*)arg.ptr_type = index; - } else if (flags & FLAG_LONG) { - *(long*)arg.ptr_type = index; - } else if (flags & FLAG_INTMAX) { - *(intmax_t*)arg.ptr_type = index; - } else if (flags & FLAG_SIZE) { - *(size_t*)arg.ptr_type = index; - } else if (flags & FLAG_PTRDIFF) { - *(ptrdiff_t*)arg.ptr_type = index; - } else { - *(int*)arg.ptr_type = index; - } - - format++; - } break; - case '%': { - index = _format_output( - write, buffer, max_size, index, format++, 1, flags, width - ); - } break; - default: format++; - } - } - } - - /* Place null-terminator */ - write(buffer, max_size, index < max_size ? index : max_size - 1, '\0'); - return index; -} - -#endif /* DOX_SKIP */ - -int vsnprintf(char* s, size_t n, char const* format, va_list arg) { - return _vsnprintf(s, n, format, arg, _buffer_mem); -} - -int snprintf(char* s, size_t n, char const* format, ...) { - va_list va; - int ret; - - va_start(va, format); - ret = _vsnprintf(s, n, format, va, _buffer_mem); - va_end(va); - - return ret; -} - -int sprintf(char* s, char const* format, ...) { - va_list va; - int ret; - - va_start(va, format); - ret = _vsnprintf(s, SIZE_MAX, format, va, _buffer_mem); - va_end(va); - - return ret; -} - -int serial_printf(char const* format, ...) { - va_list va; - char buffer[1]; - int ret; - - va_start(va, format); - ret = _vsnprintf(buffer, SIZE_MAX, format, va, _buffer_serial); - va_end(va); - - return ret; -} diff --git a/bootloader/TSL/src/pe.c b/bootloader/TSL/src/pe.c deleted file mode 100644 index d3959d4..0000000 --- a/bootloader/TSL/src/pe.c +++ /dev/null @@ -1,309 +0,0 @@ -#include -#include -#include -#include - -typedef struct __packed dos_header { - word_t e_magic; - byte_t _unused0[58]; - dword_t e_lfanew; -} dos_header; - -typedef struct __packed file_header { - word_t machine; - word_t number_of_sections; - dword_t time_date_stamp; - dword_t pointer_to_symbol_table; - dword_t number_of_symbols; - word_t size_of_optional_header; - word_t characteristics; -} file_header; - -typedef struct __packed data_directoru { - dword_t virtual_address; - dword_t size; -} data_directoru; - -typedef struct __packed optional_header { - word_t magic; - byte_t major_linker_version; - byte_t minor_linker_version; - dword_t size_of_code; - dword_t size_of_initialized_data; - dword_t size_of_uninitialized_data; - dword_t address_of_entry_point; - dword_t base_of_code; - - qword_t image_base; - dword_t section_alignment; - dword_t file_alignment; - word_t major_operating_system_version; - word_t minor_operating_system_version; - word_t major_image_version; - word_t minor_image_version; - word_t major_subsystem_version; - word_t minor_subsystem_version; - dword_t win32_version_value; - dword_t size_of_image; - dword_t size_of_headers; - dword_t checksum; - word_t subsystem; - word_t dll_characteristics; - qword_t size_of_stack_reserve; - qword_t size_of_stack_commit; - qword_t size_of_heap_reserve; - qword_t size_of_heap_commit; - dword_t loader_flags; - dword_t number_of_rva_and_sizes; - - data_directoru data_directories[16]; -} optional_header; - -typedef struct __packed pe_header { - dword_t signature; - file_header file_header; - optional_header optional_header; - -} pe_header; - -typedef struct __packed section_header { - byte_t name[8]; - dword_t virtual_size; - dword_t virtual_address; - dword_t size_of_raw_data; - dword_t pointer_to_raw_data; - dword_t pointer_to_relocations; - dword_t pointer_to_line_numbers; - word_t number_of_relocations; - word_t number_of_line_numbers; - dword_t characteristics; -} section_header; - -typedef struct __packed import_directory { - dword_t import_lookup_rva; - dword_t time_stamp; - dword_t forwarder_chain; - dword_t name_rva; - dword_t import_address_table_rva; -} import_directory; - -typedef struct __packed export_directory { - dword_t flags; - dword_t time_stamp; - word_t major_version; - word_t minor_version; - dword_t name_rva; - dword_t ordinal_base; - dword_t address_table_count; - dword_t number_of_name_pointers; - dword_t export_address_table_rva; - dword_t name_pointer_rva; - dword_t ordinal_table_rva; -} export_directory; - -#define STATES_MAX 16 - -static struct { - pe_load_state states[STATES_MAX + 1]; -} _ctx; - -bool pe_loader_init(void* start) { - memset(&_ctx, 0, sizeof _ctx); - _ctx.states[0].load_addr = (dword_t)start; - return true; -} - -void pe_get_memory_range(dword_t* begin, dword_t* end) { - size_t i; - - if (begin) { - *begin = _ctx.states[0].load_addr; - } - if (end) { - for (i = STATES_MAX - 1; i >= 0; --i) { - if (_ctx.states[i].load_addr != 0) { - *end = _ctx.states[i].load_addr + _ctx.states[i].image_size; - break; - } - } - } -} - -bool pe_load(char const* filename, pe_load_state** state) { - void* pe_addr; - pe_load_state* ret; - - dos_header* dos_hdr; - pe_header* pe_hdr; - - section_header* sections; - size_t sections_count; - - size_t i; - - /* Check if already loaded */ - ret = NULL; - for (i = 0; i < STATES_MAX; ++i) { - size_t name_len = strlen(_ctx.states[i].name); - if (name_len == 0) { - ret = &_ctx.states[i]; - break; - } else if (!memcmp(_ctx.states[i].name, filename, name_len + 1)) { - if (state) { - *state = &_ctx.states[i]; - } - return true; - } - } - if (ret == NULL) { - return false; - } - - /* Open the file */ - if ((pe_addr = ramfs_file(filename, NULL)) == NULL) { - return false; - } - - /* Verify MZ and PE signatures */ - dos_hdr = pe_addr; - if (dos_hdr->e_magic != 0x5A4D) { - return false; - } - pe_hdr = (pe_header*)((byte_t*)pe_addr + dos_hdr->e_lfanew); - if (pe_hdr->signature != 0x00004550) { - return false; - } - if (pe_hdr->optional_header.magic != 0x020B) { - return false; - } - - /* Get sections */ - sections_count = pe_hdr->file_header.number_of_sections; - sections = (section_header*)((byte_t*)&pe_hdr->optional_header + - pe_hdr->file_header.size_of_optional_header); - - /* Load headers */ - memcpy( - (void*)ret->load_addr, pe_addr, pe_hdr->optional_header.size_of_headers - ); - - /* Load sections */ - for (i = 0; i < sections_count; ++i) { - memcpy( - (byte_t*)ret->load_addr + sections[i].virtual_address, - (char*)pe_addr + sections[i].pointer_to_raw_data, - sections[i].size_of_raw_data - ); - } - - /* Fill Load state */ - snprintf(ret->name, sizeof ret->name, "%s", filename); - ret->image_size = (dword_t)pe_hdr->optional_header.size_of_image; - ret->entry = ret->load_addr + pe_hdr->optional_header.address_of_entry_point; - ret->stack_size = pe_hdr->optional_header.size_of_stack_commit; - - if (ret + 1 - &_ctx.states[0] < STATES_MAX) { - (ret + 1)->load_addr = ret->load_addr + ret->image_size; - } - - /* Parse import table */ - if (pe_hdr->optional_header.data_directories[1].size != 0) { - import_directory* dll_dir; - /* Go through DLLs */ - for (dll_dir = (import_directory*)(ret->load_addr + pe_hdr->optional_header - .data_directories[1] - .virtual_address); - dll_dir->import_lookup_rva != 0; - ++dll_dir) { - char dll_path[256]; - pe_load_state* dll; - pe_header* dll_pe_hdr; - export_directory* export_dir; - dword_t* export_table; - dword_t* name_table; - word_t* ordinal_table; - qword_t* address_table; - - /* Load DLL */ - snprintf( - dll_path, - sizeof dll_path, - "ramfs/%s", - (char*)(ret->load_addr + dll_dir->name_rva) - ); - if (!pe_load(dll_path, &dll)) { - return false; - } - - /* Get DLL export directory */ - dll_pe_hdr = (pe_header*)(dll->load_addr + - (((dos_header*)dll->load_addr)->e_lfanew)); - if (dll_pe_hdr->optional_header.data_directories[0].size == 0) { - return false; - } - export_dir = - (export_directory*)(dll->load_addr + - dll_pe_hdr->optional_header.data_directories[0] - .virtual_address); - - /* Get export tables */ - export_table = - (dword_t*)(dll->load_addr + export_dir->export_address_table_rva); - name_table = (dword_t*)(dll->load_addr + export_dir->name_pointer_rva); - ordinal_table = (word_t*)(dll->load_addr + export_dir->ordinal_table_rva); - - /* Go through symbols */ - for (address_table = - (qword_t*)(ret->load_addr + dll_dir->import_address_table_rva); - *address_table != 0; - ++address_table) { - if (*address_table & (1ULL << 63)) { - /* // TODO: Import by ordinal */ - return false; - } else { - /* Import by name */ - word_t symbol_index; - char const* symbol_name; - - symbol_index = *(word_t*)(ret->load_addr + - (dword_t)(*address_table & 0xFFFFFFFF)); - symbol_name = (char*)(ret->load_addr + - (dword_t)(*address_table & 0xFFFFFFFF) + 2); - - /* Find symbol in export name table */ - if (!memcmp( - symbol_name, - (byte_t*)dll->load_addr + name_table[symbol_index], - strlen(symbol_name) + 1 - )) { - i = symbol_index; - } else { - bool found = false; - for (i = 0; i < export_dir->number_of_name_pointers; ++i) { - if (!memcmp( - symbol_name, - (byte_t*)dll->load_addr + name_table[i], - strlen(symbol_name) + 1 - )) { - found = true; - break; - } - } - if (!found) { - return false; - } - } - - /* Bind symbol */ - *address_table = dll->load_addr + export_table[ordinal_table[i]]; - } - } - } - } - - if (state != NULL) { - *state = ret; - } - - return true; -} diff --git a/bootloader/TSL/src/ramfs.c b/bootloader/TSL/src/ramfs.c deleted file mode 100644 index eb12946..0000000 --- a/bootloader/TSL/src/ramfs.c +++ /dev/null @@ -1,65 +0,0 @@ -/** - * @file ramfs.c - * @author Arseny Lashkevicj (arsenez@cybercommunity.space) - * @brief Functions for reading RAMFS - * - */ - -#include -#include - -static struct { - void* addr; - size_t size; -} _ctx; - -typedef struct posix_header { - char name[100]; - char _unused0[24]; - char size[12]; - char _unused1[121]; - char magic[6]; - char _unused2[249]; -} posix_header; - -static size_t _str_oct_to_dec(char const* oct) { - size_t ret = 0; - while (*oct != 0) { ret = ret * 8 + *oct++ - '0'; } - return ret; -} - -static size_t _align512(size_t val) { return (val + 511) & -512; } - -static posix_header* _next(posix_header* hdr) { - return (posix_header*)((byte_t*)(hdr + 1) + - _align512(_str_oct_to_dec(hdr->size))); -} - -bool ramfs_init(void* address) { - posix_header* i; - /* Set RAMFS base address */ - _ctx.addr = address; - - /* Get RAMFS size */ - for (i = _ctx.addr; memcmp("ustar", i->magic, 5) == 0; i = _next(i)) - ; - _ctx.size = (char*)i - (char*)_ctx.addr; - - return true; -} - -void* ramfs_get_end(void) { return (byte_t*)_ctx.addr + _ctx.size; } - -void* ramfs_file(char const* name, size_t* size) { - posix_header* hdr; - for (hdr = _ctx.addr; memcmp("ustar", hdr->magic, 5) == 0; hdr = _next(hdr)) { - if (memcmp(hdr->name, name, strlen(name)) == 0) { - if (size != NULL) { - *size = _str_oct_to_dec(hdr->size); - } - return hdr + 1; - } - } - - return NULL; -} diff --git a/bootloader/TSL/src/string.c b/bootloader/TSL/src/string.c deleted file mode 100644 index f640001..0000000 --- a/bootloader/TSL/src/string.c +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @file string.c - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Functions for manipulating c-strings and buffers - * - */ -#include - -size_t strlen(char const* start) { - char const* end; - for (end = start; *end != '\0'; ++end) - ; - return end - start; -} - -int memcmp(void const* lhs, void const* rhs, size_t count) { - while (count--) { - if (*(byte_t*)lhs != *(byte_t*)rhs) { - return (uintptr_t)lhs - (uintptr_t)rhs; - } - lhs = (byte_t*)lhs + 1; - rhs = (byte_t*)rhs + 1; - } - return 0; -} - -void* memcpy(void* dest, void const* src, size_t count) { - size_t i; - for (i = 0; i < count; ++i) { ((byte_t*)dest)[i] = ((byte_t*)src)[i]; } - return dest; -} - -void* memset(void* ptr, int val, size_t count) { - byte_t* data = (byte_t*)ptr; - while (count--) { *data++ = (byte_t)val; } - return ptr; -} diff --git a/bootloader/TSL/src/tsl_entry.c b/bootloader/TSL/src/tsl_entry.c deleted file mode 100644 index a0e631a..0000000 --- a/bootloader/TSL/src/tsl_entry.c +++ /dev/null @@ -1,145 +0,0 @@ -/** - * @file tsl_entry.c - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Third Stage Loader entry - * - */ -#include -#include -#include -#include -#include -#include -#include - -static qword_t pml4[512] __align(1 << 12); -static qword_t pml3[512] __align(1 << 12); -static qword_t pml2[512] __align(1 << 12); -static qword_t pml1[512] __align(1 << 12); - -/** - * @brief Print error message to screen - * - * @param error_str Error message - */ -static void print_error(char const* error_str) { - serial_printf("VLGBL Error: %s.\n", error_str); -} - -/** - * @brief Third Stage Loader entry - * - * @details `Third Stage Loader` works in Protected Mode. It's purpose is - * getting system ready for loading kernel\n - * - */ -void __stdcall __noreturn tsl_entry(boot_info_t* boot_info) { - size_t i; - pe_load_state* kernel; - dword_t pe_memory_end; - - /* Verify boot info size */ - if (boot_info->size != sizeof(boot_info_t)) { - print_error("Boot info is outdated"); - goto halt; - } - - /* Disable all PCI devices */ - disable_pci(); - - /* Initialize RAMFS driver */ - if (!ramfs_init((void*)(uintptr_t)boot_info->RAMFS.address)) { - print_error("Failed to initialize RAMFS"); - goto halt; - } - - /* Initialize PE loader */ - if (!pe_loader_init((void*)align_page((dword_t)ramfs_get_end()))) { - print_error("Failed to initialize PE loader"); - goto halt; - } - - /* Load kernel image */ - if (!pe_load("ramfs/kernel.pe", &kernel)) { - print_error("Failed to load kernel image"); - goto halt; - } - - /* Enable Physical Address Extension */ - enable_PAE(); - - /* Clear page tables */ - memset(pml4, 0, sizeof pml4); - memset(pml3, 0, sizeof pml3); - memset(pml2, 0, sizeof pml2); - memset(pml1, 0, sizeof pml1); - - /* Identity map SSL */ - for (i = 0; i < 16; ++i) { - qword_t addr = 0x10000 + (i << 12); - pml1[addr >> 12] = addr | 0x1; - } - - /* Identity map TSL */ - for (i = 0; i < 16; ++i) { - qword_t addr = 0x20000 + (i << 12); - pml1[addr >> 12] = addr | 0x1; - } - - /* Identity map RAMFS and kernel image */ - pe_get_memory_range(NULL, &pe_memory_end); - pe_memory_end = align_page(pe_memory_end); - for (i = boot_info->RAMFS.address >> 12; i < pe_memory_end >> 12; ++i) { - pml1[i] = (i << 12) | 0x1; - } - - /* Identity map temporary stack */ - for (i = 0; i < align_page(kernel->stack_size) >> 12; ++i) { - qword_t addr = pe_memory_end + (i << 12); - pml1[addr >> 12] = addr | 0x1; - } - - pml2[0] = (qword_t)(uintptr_t)pml1 | 0x3; - pml3[0] = (qword_t)(uintptr_t)pml2 | 0x3; - pml4[0] = (qword_t)(uintptr_t)pml3 | 0x3; - - /* Find ACPI RSDP table*/ - for (i = 0xE0000; i < 0xFFFFF; ++i) { - if (!memcmp((void*)i, "RSD PTR ", 8)) { - break; - } - } - if (i == 0xFFFFF) { - print_error("Failed to find ACPI tables"); - } - boot_info->ACPI.rsdp = i; - - /* Load page table */ - load_page_table(pml4); - - /* Enable Long Mode */ - enable_long_mode(); - - /* Enable Paging */ - enable_paging(); - - /* Finalize TSL */ - __asm__ volatile( - "pushw %[segment]\n" - "pushl %[offset]\n" - "movl %%esp, %%ebp\n" - - "movl %[tmp_stack], %%esp\n" - "movl %[bootinfo], %%ecx\n" - - "lcall *(%%ebp)" - : - : [segment] "rmN"((word_t)3 << 3), - [offset] "rm"((dword_t)kernel->entry), - [bootinfo] "rmN"((dword_t)boot_info), - [tmp_stack] "rmN"((dword_t)pe_memory_end + kernel->stack_size) - ); - -halt: - while (1) { __asm__ volatile("hlt"); } -} diff --git a/bootloader/TSL/src/utils.c b/bootloader/TSL/src/utils.c deleted file mode 100644 index 615f17e..0000000 --- a/bootloader/TSL/src/utils.c +++ /dev/null @@ -1,231 +0,0 @@ -/** - * @file utils.c - * @author Arseny Lashkevich (arsenez@cybercommunity.space) - * @brief Utility functions used for Third Stage Loader - * - */ -#include - -byte_t inb(word_t port) { - byte_t ret; - __asm__ volatile("inb %[port], %[ret]" - : [ret] "=a"(ret) - : [port] "Nd"(port)); - return ret; -} - -word_t inw(word_t port) { - word_t ret; - __asm__ volatile("inw %[port], %[ret]" - : [ret] "=a"(ret) - : [port] "Nd"(port)); - return ret; -} - -dword_t inl(word_t port) { - dword_t ret; - __asm__ volatile("inl %[port], %[ret]" - : [ret] "=a"(ret) - : [port] "Nd"(port)); - return ret; -} - -void outb(word_t port, byte_t val) { - __asm__ volatile("outb %[val], %[port]" - : - : [val] "a"(val), [port] "Nd"(port)); -} - -void outw(word_t port, word_t val) { - __asm__ volatile("outw %[val], %[port]" - : - : [val] "a"(val), [port] "Nd"(port)); -} - -void outl(word_t port, dword_t val) { - __asm__ volatile("outl %[val], %[port]" - : - : [val] "a"(val), [port] "Nd"(port)); -} - -void serial_putch(byte_t ch) { - while ((inb(0x3F8 + 5) & 0x20) == 0) { continue; } - outb(0x3F8, ch); -} - -bool check_cpuid(void) { - bool ret; - __asm__ volatile( - "pushfl\n" - "popl %%eax\n" /* Move EFLAGS to EAX */ - - "movl %%eax, %%ebx\n" /* Save original EFLAGS to EBX*/ - - "xorl $0x200000, %%eax\n" /* Change ID bit */ - - "pushl %%eax\n" - "popfl\n" /* Load Updated EFLAGS */ - - "pushfl\n" - "popl %%eax\n" /* Move Updated EFLAGS to EAX */ - - "xorl %%eax, %%ebx" /* Check ID bit */ - : "=@ccz"(ret) - : - : "eax", "ebx" - ); - return !ret; -} - -static void _cpuid(dword_t* eax, dword_t* ebx, dword_t* ecx, dword_t* edx) { - __asm__("cpuid" - : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) - : "a"(*eax)); -} - -/* CPUID EAX = 1: EDX */ -#define CPUID_PSE (1 << 3) -#define CPUID_MSR (1 << 5) -#define CPUID_PAE (1 << 6) -#define CPUID_APIC (1 << 9) -#define CPUID_PGE (1 << 13) -#define CPUID_PAT (1 << 16) -#define CPUID_ACPI (1 << 22) - -/* CPUID EAX = 1: ECX */ -#define CPUID_SSE3 (1 << 0) -#define CPUID_SSE41 (1 << 19) -#define CPUID_SSE42 (1 << 20) -#define CPUID_x2APIC (1 << 21) -#define CPUID_AVX (1 << 28) - -/* CPUID EAX = 0x80000001: EDX */ -#define CPUID_SYSCALL (1 << 11) -#define CPUID_NX (1 << 20) -#define CPUID_PG1G (1 << 26) -#define CPUID_LM (1 << 29) - -bool check_cpu_compat(void) { - dword_t eax, ebx, ecx, edx; - dword_t cpuid_max, cpuid_ext_max; - - eax = 0; - _cpuid(&eax, &ebx, &ecx, &edx); - cpuid_max = eax; - - eax = 0x80000000; - _cpuid(&eax, &ebx, &ecx, &edx); - cpuid_ext_max = eax; - - if (cpuid_max < 1 && cpuid_ext_max < 0x80000001) { - return false; - } - - eax = 1; - _cpuid(&eax, &ebx, &ecx, &edx); - if (!(edx & CPUID_PAE)) { - return false; - } - - eax = 0x80000001; - _cpuid(&eax, &ebx, &ecx, &edx); - if (!(edx & CPUID_LM)) { - return false; - } - - return true; -} - -void enable_PAE(void) { - __asm__ volatile( - "movl %%cr4, %%eax\n" - "orl $0x20, %%eax\n" - "movl %%eax, %%cr4\n" - : - : - : "eax" - ); -} - -void load_page_table(void* address) { - __asm__ volatile("movl %[table], %%cr3\n" - : - : [table] "a"((dword_t)address)); -} - -void enable_long_mode(void) { - __asm__ volatile( - "mov $0xC0000080, %%ecx\n" - "rdmsr\n" - "orl $0x100, %%eax\n" - "wrmsr\n" - : - : - : "eax", "ecx", "edx" - ); -} - -void enable_paging(void) { - __asm__ volatile( - "movl %%cr0, %%eax\n" - "orl $0x80000000, %%eax\n" - "movl %%eax, %%cr0\n" - : - : - : "eax" - ); -} - -static dword_t -_pci_read_reg(byte_t bus, byte_t device, byte_t func, byte_t reg) { - dword_t address = ((dword_t)1 << 31) | ((dword_t)bus << 16) | - ((dword_t)device << 11) | ((dword_t)func << 8) | - ((dword_t)reg * 0x4); - - outl(0xCF8, address); - return inl(0xCFC); -} - -static void _pci_write_reg( - byte_t bus, byte_t device, byte_t func, byte_t reg, dword_t value -) { - dword_t address = ((dword_t)1 << 31) | ((dword_t)bus << 16) | - ((dword_t)device << 11) | ((dword_t)func << 8) | - ((dword_t)reg * 0x4); - - outl(0xCF8, address); - outl(0xCFC, value); -} - -static word_t _pci_get_vendor(byte_t bus, byte_t device, byte_t func) { - return (word_t)(_pci_read_reg(bus, device, func, 0x0) & 0xFFFF); -} - -static byte_t _pci_get_type(byte_t bus, byte_t device, byte_t func) { - return (byte_t)((_pci_read_reg(bus, device, func, 0x3) >> 16) & 0xFF); -} - -void disable_pci(void) { - size_t bus, device, func; - dword_t reg; - - for (bus = 0; bus < 256; ++bus) { - for (device = 0; device < 32; ++device) { - if (_pci_get_vendor(bus, device, 0) != 0xFFFF) { - reg = _pci_read_reg(bus, device, 0, 0x1); - reg &= 0xFFFFFFFC; - _pci_write_reg(bus, device, 0, 0x1, reg); - - if (_pci_get_type(bus, device, 0) & 0x80) { - for (func = 1; func < 8; ++func) { - reg = _pci_read_reg(bus, device, func, 0x1); - reg &= 0xFFFFFFFC; - _pci_write_reg(bus, device, func, 0x1, reg); - } - } - } - } - } -} - -dword_t align_page(dword_t addr) { return (addr + 4095) & -4096; } diff --git a/cmake/dependencies.cmake b/cmake/dependencies.cmake deleted file mode 100644 index 0575a1f..0000000 --- a/cmake/dependencies.cmake +++ /dev/null @@ -1,7 +0,0 @@ -function(find_dependencies) - - if(BUILD_DOCS) - find_package(Doxygen) - endif() - -endfunction(find_dependencies) diff --git a/cmake/flags.cmake b/cmake/flags.cmake deleted file mode 100644 index 1ee3605..0000000 --- a/cmake/flags.cmake +++ /dev/null @@ -1,57 +0,0 @@ -list(APPEND C_DIALECT - "-Wall" - "-Wpedantic" - "-Wno-long-long" - "-ansi" - "-fno-builtin" - "-ffreestanding" -) -list(APPEND C_OPTIMIZATION - "-Os" -) -list(APPEND C_INSTRUMENTATION - "-fno-stack-protector" -) -list(APPEND C_GENERATION - "-freg-struct-return" - "-fverbose-asm" - "-fno-pic" - "-fno-pie" - "-fleading-underscore" - "-fno-asynchronous-unwind-tables" - "-fno-common" -) -list(APPEND C_x86_16 - "-march=i386" - "-mregparm=3" - "-mpreferred-stack-boundary=3" - "-mabi=sysv" - "-mgeneral-regs-only" - "-m16" -) - -list(APPEND C_x86_32 - "-march=i686" - "-mregparm=3" - "-mpreferred-stack-boundary=3" - "-mabi=sysv" - "-mgeneral-regs-only" - "-m32" -) - -list(APPEND ASM_OPTIMIZATION - "-Ox" -) - -list(APPEND ASM_GENERATION - "-felf32" -) - -list(APPEND LINK_FLAGS - "-nostartfiles" - "-nodefaultlibs" - "-nolibc" - "-nostdlib" - "-s" - "-static" -) diff --git a/cmake/options.cmake b/cmake/options.cmake deleted file mode 100644 index 967214b..0000000 --- a/cmake/options.cmake +++ /dev/null @@ -1,4 +0,0 @@ -# General configuration -set(OUTPUT "${CMAKE_BINARY_DIR}/out" CACHE PATH "Bootloader targets directory") -option(BUILD_DOCS "Build documentation (requires doxygen)" OFF) -set(OUTPUT_DOCS "${OUTPUT}/docs" CACHE PATH "Documentation directory") diff --git a/cmake/toolchain.cmake b/cmake/toolchain.cmake deleted file mode 100644 index d65a7a4..0000000 --- a/cmake/toolchain.cmake +++ /dev/null @@ -1,12 +0,0 @@ -set(CMAKE_SYSTEM_NAME Generic) - -# Assembler -set(CMAKE_ASM_NASM_COMPILE_OBJECT " -o ") -set(CMAKE_ASM_NASM_LINK_EXECUTABLE " -o ") -set(CMAKE_ASM_FLAGS "") - -# C Compiler -set(CMAKE_C_FLAGS_DEBUG "") -set(CMAKE_C_FLAGS_RELEASE "") -set(CMAKE_C_FLAGS_MINSIZEREL "") -set(CMAKE_C_FLAGS_RELWITHDEBINFO "") diff --git a/import.cmake b/import.cmake deleted file mode 100644 index e6a0836..0000000 --- a/import.cmake +++ /dev/null @@ -1,27 +0,0 @@ -include(ExternalProject) - -function(import_VolgaBL) - cmake_parse_arguments( - ARG - "" - "PATH" - "" - ${ARGN} - ) - - ExternalProject_Add(VolgaBL - SOURCE_DIR ${ARG_PATH} - BINARY_DIR ${ARG_PATH}/build - EXCLUDE_FROM_ALL TRUE - STEP_TARGETS build - BUILD_ALWAYS TRUE - - CMAKE_CACHE_ARGS - "-DOUTPUT:PATH=${ARG_PATH}/out" - ) - - set(VOLGABL_TARGET VolgaBL-build PARENT_SCOPE) - set(VOLGABL_MBR ${ARG_PATH}/out/bootloader_mbr PARENT_SCOPE) - set(VOLGABL_SSL ${ARG_PATH}/out/bootloader_ssl PARENT_SCOPE) - set(VOLGABL_TSL ${ARG_PATH}/out/bootloader_tsl PARENT_SCOPE) -endfunction(import_VolgaBL) From 873df944fbab224c8826a30332a7a6581f2c45b0 Mon Sep 17 00:00:00 2001 From: arsenez Date: Tue, 10 Sep 2024 19:02:20 +0300 Subject: [PATCH 02/13] Generate a config with version string --- bootloader/common/config/version.h.in | 6 ++++++ bootloader/common/meson.build | 13 +++++++++++++ bootloader/mbr/mbr.S | 1 + meson.build | 7 +++++++ 4 files changed, 27 insertions(+) create mode 100644 bootloader/common/config/version.h.in create mode 100644 bootloader/common/meson.build create mode 100644 bootloader/mbr/mbr.S create mode 100644 meson.build diff --git a/bootloader/common/config/version.h.in b/bootloader/common/config/version.h.in new file mode 100644 index 0000000..8a05ea2 --- /dev/null +++ b/bootloader/common/config/version.h.in @@ -0,0 +1,6 @@ +#ifndef COMMON_VERSION_H +#define COMMON_VERSION_H + +#define VERSION "@version@" + +#endif diff --git a/bootloader/common/meson.build b/bootloader/common/meson.build new file mode 100644 index 0000000..55deba7 --- /dev/null +++ b/bootloader/common/meson.build @@ -0,0 +1,13 @@ +# Generate a config +config_data = configuration_data() +config_data.set('version', bl_version) +configure_file(input : 'config' / 'version.h.in', + output : 'version.h', + configuration : config_data) + +# Include directories +config_include = include_directories('.') +common_include = include_directories('include') + +# Make a dependency +common_dep = declare_dependency(include_directories: [ config_include, common_include ]) diff --git a/bootloader/mbr/mbr.S b/bootloader/mbr/mbr.S new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/bootloader/mbr/mbr.S @@ -0,0 +1 @@ + diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..3bb3e58 --- /dev/null +++ b/meson.build @@ -0,0 +1,7 @@ +project('VolgaBL', 'c', version: run_command('git', 'describe', '--tags', check: true).stdout().strip()) + +# Bootloader version +bl_version = meson.project_version() + +# Import common library +subdir('bootloader/common') From 3280d0ec1d0cd95f231919d5fe28933e61b039e9 Mon Sep 17 00:00:00 2001 From: arsenez Date: Thu, 12 Sep 2024 16:44:03 +0300 Subject: [PATCH 03/13] Add common headers --- bootloader/common/include/attributes.h | 9 ++++++ bootloader/common/include/cpu/integer.h | 12 +++++++ bootloader/common/include/hardware/drive.h | 6 ++++ .../include/hardware/drive/mapping/gpt.h | 32 +++++++++++++++++++ .../include/hardware/drive/mapping/mbr.h | 26 +++++++++++++++ bootloader/common/include/stages.h | 11 +++++++ bootloader/common/include/stages/mbr.h | 12 +++++++ bootloader/common/include/stages/ssl.h | 8 +++++ bootloader/common/include/stages/tsl.h | 8 +++++ 9 files changed, 124 insertions(+) create mode 100644 bootloader/common/include/attributes.h create mode 100644 bootloader/common/include/cpu/integer.h create mode 100644 bootloader/common/include/hardware/drive.h create mode 100644 bootloader/common/include/hardware/drive/mapping/gpt.h create mode 100644 bootloader/common/include/hardware/drive/mapping/mbr.h create mode 100644 bootloader/common/include/stages.h create mode 100644 bootloader/common/include/stages/mbr.h create mode 100644 bootloader/common/include/stages/ssl.h create mode 100644 bootloader/common/include/stages/tsl.h diff --git a/bootloader/common/include/attributes.h b/bootloader/common/include/attributes.h new file mode 100644 index 0000000..915861d --- /dev/null +++ b/bootloader/common/include/attributes.h @@ -0,0 +1,9 @@ +#ifndef COMMON_ATTRIBUTES_H +#define COMMON_ATTRIBUTES_H + +#define __noreturn __attribute__((noreturn)) +#define __packed __attribute__((packed)) +#define __unused __attribute__((unused)) +#define __nodiscard __attribute__((warn_unused_result)) + +#endif diff --git a/bootloader/common/include/cpu/integer.h b/bootloader/common/include/cpu/integer.h new file mode 100644 index 0000000..bf127c2 --- /dev/null +++ b/bootloader/common/include/cpu/integer.h @@ -0,0 +1,12 @@ +#ifndef COMMON_CPU_INTEGER_H +#define COMMON_CPU_INTEGER_H + +#include +#include + +typedef uint8_t byte_t; +typedef uint16_t word_t; +typedef uint32_t dword_t; +typedef uint64_t qword_t; + +#endif diff --git a/bootloader/common/include/hardware/drive.h b/bootloader/common/include/hardware/drive.h new file mode 100644 index 0000000..8214c19 --- /dev/null +++ b/bootloader/common/include/hardware/drive.h @@ -0,0 +1,6 @@ +#ifndef COMMON_HARDWARE_DRIVE_H +#define COMMON_HARDWARE_DRIVE_H + + + +#endif diff --git a/bootloader/common/include/hardware/drive/mapping/gpt.h b/bootloader/common/include/hardware/drive/mapping/gpt.h new file mode 100644 index 0000000..9e8c347 --- /dev/null +++ b/bootloader/common/include/hardware/drive/mapping/gpt.h @@ -0,0 +1,32 @@ +#ifndef COMMON_HARDWARE_DRIVE_MAPPING_GPT_H +#define COMMON_HARDWARE_DRIVE_MAPPING_GPT_H + +#include "../../../cpu/integer.h" +#include "../../../attributes.h" + +typedef struct __packed _gpt_mapping { + qword_t signature; + dword_t revision; + dword_t header_size; + dword_t checksum; + dword_t rsv0; + qword_t this_lba; + qword_t alt_lba; + qword_t first_lba; + qword_t last_lba; + byte_t disk_guid[16]; + qword_t partition_table_lba; + dword_t partition_count; + dword_t partition_entry_size; + dword_t partition_table_checksum; +} gpt_mapping; + +typedef struct __packed _gpt_partition { + byte_t type[16]; + byte_t guid[16]; + qword_t start_lba; + qword_t end_lba; + qword_t attributes; +} gpt_partition; + +#endif diff --git a/bootloader/common/include/hardware/drive/mapping/mbr.h b/bootloader/common/include/hardware/drive/mapping/mbr.h new file mode 100644 index 0000000..1fd1234 --- /dev/null +++ b/bootloader/common/include/hardware/drive/mapping/mbr.h @@ -0,0 +1,26 @@ +#ifndef COMMON_HARDWARE_DRIVE_MAPPING_MBR_H +#define COMMON_HARDWARE_DRIVE_MAPPING_MBR_H +#include "../../../cpu/integer.h" +#include "../../../attributes.h" + +typedef struct __packed _mbr_partition { + byte_t attributes; + byte_t start_chs[3]; + byte_t type; + byte_t last_chs[3]; + dword_t lba_start; + dword_t sectors_count; +} mbr_partition; + +typedef struct __packed _mbr_mapping { + byte_t code[440]; + dword_t disk_id; + word_t rsv0; + mbr_partition partition_table[4]; + word_t signature; +} mbr_mapping; + +_Static_assert(sizeof(struct _mbr_partition) == 16, "Illegal structure size"); +_Static_assert(sizeof(struct _mbr_mapping) == 512, "Illegal structure size"); + +#endif diff --git a/bootloader/common/include/stages.h b/bootloader/common/include/stages.h new file mode 100644 index 0000000..88f191f --- /dev/null +++ b/bootloader/common/include/stages.h @@ -0,0 +1,11 @@ +#ifndef COMMON_STAGES_H +#define COMMON_STAGES_H + +#include "stages/mbr.h" +#include "stages/ssl.h" +#include "stages/tsl.h" + +#define EXTRA_LOAD_ADDRESS SSL_ADDRESS +#define EXTRA_LOAD_SIZE (SSL_SIZE + TSL_SIZE) + +#endif // !COMMON_STAGES_H diff --git a/bootloader/common/include/stages/mbr.h b/bootloader/common/include/stages/mbr.h new file mode 100644 index 0000000..00c844d --- /dev/null +++ b/bootloader/common/include/stages/mbr.h @@ -0,0 +1,12 @@ +#ifndef COMMON_STAGES_MBR_H +#define COMMON_STAGES_MBR_H + +#define MBR_ADDRESS 0x7C00 +#define MBR_SEGMENT (MBR_ADDRESS >> 4) + +#define MBR_STACK_BOT_ADDRESS 0x500 +#define MBR_STACK_TOP_ADDRESS (MBR_ADDRESS - 16) +#define MBR_STACK_SEGMENT (MBR_STACK_BOT_ADDR >> 4) +#define MBR_STACK_ADDRESS (MBR_STACK_TOP_ADDRESS - MBR_STACK_BOT_ADDRESS) + +#endif // !COMMON_STAGES_MBR_H diff --git a/bootloader/common/include/stages/ssl.h b/bootloader/common/include/stages/ssl.h new file mode 100644 index 0000000..a08ec64 --- /dev/null +++ b/bootloader/common/include/stages/ssl.h @@ -0,0 +1,8 @@ +#ifndef COMMON_STAGES_SSL_H +#define COMMON_STAGES_SSL_H + +#define SSL_ADDRESS 0x10000 +#define SSL_SEGMENT (SSL_ADDRESS >> 4) +#define SSL_SIZE (64 * 1024) + +#endif diff --git a/bootloader/common/include/stages/tsl.h b/bootloader/common/include/stages/tsl.h new file mode 100644 index 0000000..b3c1531 --- /dev/null +++ b/bootloader/common/include/stages/tsl.h @@ -0,0 +1,8 @@ +#ifndef COMMON_STAGES_TSL_H +#define COMMON_STAGES_TSL_H + +#define TSL_ADDRESS 0x20000 +#define TSL_SEGMENT (TSL_ADDRESS >> 4) +#define TSL_SIZE (64 * 1024) + +#endif From b939061b0287f93ad9b95109a5443f18084a83ba Mon Sep 17 00:00:00 2001 From: arsenez Date: Thu, 12 Sep 2024 18:48:44 +0300 Subject: [PATCH 04/13] Add mbr target --- bootloader/mbr/mbr.S | 6 ++++++ bootloader/mbr/mbr.ld | 20 ++++++++++++++++++++ bootloader/mbr/meson.build | 7 +++++++ meson.build | 26 ++++++++++++++++++++++++++ 4 files changed, 59 insertions(+) create mode 100644 bootloader/mbr/mbr.ld create mode 100644 bootloader/mbr/meson.build diff --git a/bootloader/mbr/mbr.S b/bootloader/mbr/mbr.S index 8b13789..0578ca8 100644 --- a/bootloader/mbr/mbr.S +++ b/bootloader/mbr/mbr.S @@ -1 +1,7 @@ +.code16 +.globl _entry +_entry: +.halt: + hlt + jmp .halt diff --git a/bootloader/mbr/mbr.ld b/bootloader/mbr/mbr.ld new file mode 100644 index 0000000..48e13d8 --- /dev/null +++ b/bootloader/mbr/mbr.ld @@ -0,0 +1,20 @@ +OUTPUT(binary) +ENTRY(_entry) +MEMORY +{ + code (rwx) : ORIGIN = 0x00000000, LENGTH = 0x000001B8 +} + +SECTIONS +{ + .text : + { + *(.text) + *(.data) + } > code + /DISCARD/ : + { + *(.note*) + *(.comment*) + } +} diff --git a/bootloader/mbr/meson.build b/bootloader/mbr/meson.build new file mode 100644 index 0000000..16129e4 --- /dev/null +++ b/bootloader/mbr/meson.build @@ -0,0 +1,7 @@ +mbr = executable('mbr.bin', 'mbr.S', + c_args: [ c_args, c16_args ], + link_args : [ + c_link_args, + c16_args, + '-Wl,--Map=' + (meson.current_build_dir() / 'mbr.map'), + '-Wl,-T' + (meson.current_source_dir() / 'mbr.ld')]) diff --git a/meson.build b/meson.build index 3bb3e58..ea468c1 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,33 @@ project('VolgaBL', 'c', version: run_command('git', 'describe', '--tags', check: true).stdout().strip()) +# Compile arguments +c_args = [ + '-Wall', + '-Wpedantic', + '-ansi', + '-fno-builtin', + '-ffreestanding', + '-fno-pic', + '-fno-pie', + '-fno-common'] +c_link_args = [ + c_args, + '-nostartfiles', + '-nodefaultlibs', + '-nolibc', + '-nostdlib', + '-s', + '-static', + '-Wl,--oformat=binary'] +c16_args = [ + '-march=i386', + '-m16'] + # Bootloader version bl_version = meson.project_version() # Import common library subdir('bootloader/common') + +# Import MBR +subdir('bootloader/mbr') From 5be4b53cabeb9be0cfa9963b9e10d302d3621ab9 Mon Sep 17 00:00:00 2001 From: arsenez Date: Thu, 12 Sep 2024 18:52:39 +0300 Subject: [PATCH 05/13] Reformat --- bootloader/common/include/attributes.h | 6 +++--- bootloader/common/include/cpu/integer.h | 4 ++-- bootloader/common/include/hardware/drive.h | 2 -- .../include/hardware/drive/mapping/gpt.h | 8 ++++---- .../include/hardware/drive/mapping/mbr.h | 18 +++++++++--------- bootloader/common/include/stages.h | 2 +- bootloader/common/include/stages/mbr.h | 8 ++++---- bootloader/common/include/stages/ssl.h | 2 +- bootloader/common/include/stages/tsl.h | 2 +- 9 files changed, 25 insertions(+), 27 deletions(-) diff --git a/bootloader/common/include/attributes.h b/bootloader/common/include/attributes.h index 915861d..9dab6f5 100644 --- a/bootloader/common/include/attributes.h +++ b/bootloader/common/include/attributes.h @@ -1,9 +1,9 @@ #ifndef COMMON_ATTRIBUTES_H #define COMMON_ATTRIBUTES_H -#define __noreturn __attribute__((noreturn)) -#define __packed __attribute__((packed)) -#define __unused __attribute__((unused)) +#define __noreturn __attribute__((noreturn)) +#define __packed __attribute__((packed)) +#define __unused __attribute__((unused)) #define __nodiscard __attribute__((warn_unused_result)) #endif diff --git a/bootloader/common/include/cpu/integer.h b/bootloader/common/include/cpu/integer.h index bf127c2..52934a7 100644 --- a/bootloader/common/include/cpu/integer.h +++ b/bootloader/common/include/cpu/integer.h @@ -1,10 +1,10 @@ #ifndef COMMON_CPU_INTEGER_H #define COMMON_CPU_INTEGER_H -#include #include +#include -typedef uint8_t byte_t; +typedef uint8_t byte_t; typedef uint16_t word_t; typedef uint32_t dword_t; typedef uint64_t qword_t; diff --git a/bootloader/common/include/hardware/drive.h b/bootloader/common/include/hardware/drive.h index 8214c19..d164698 100644 --- a/bootloader/common/include/hardware/drive.h +++ b/bootloader/common/include/hardware/drive.h @@ -1,6 +1,4 @@ #ifndef COMMON_HARDWARE_DRIVE_H #define COMMON_HARDWARE_DRIVE_H - - #endif diff --git a/bootloader/common/include/hardware/drive/mapping/gpt.h b/bootloader/common/include/hardware/drive/mapping/gpt.h index 9e8c347..da80565 100644 --- a/bootloader/common/include/hardware/drive/mapping/gpt.h +++ b/bootloader/common/include/hardware/drive/mapping/gpt.h @@ -1,8 +1,8 @@ #ifndef COMMON_HARDWARE_DRIVE_MAPPING_GPT_H #define COMMON_HARDWARE_DRIVE_MAPPING_GPT_H -#include "../../../cpu/integer.h" #include "../../../attributes.h" +#include "../../../cpu/integer.h" typedef struct __packed _gpt_mapping { qword_t signature; @@ -14,7 +14,7 @@ typedef struct __packed _gpt_mapping { qword_t alt_lba; qword_t first_lba; qword_t last_lba; - byte_t disk_guid[16]; + byte_t disk_guid[16]; qword_t partition_table_lba; dword_t partition_count; dword_t partition_entry_size; @@ -22,8 +22,8 @@ typedef struct __packed _gpt_mapping { } gpt_mapping; typedef struct __packed _gpt_partition { - byte_t type[16]; - byte_t guid[16]; + byte_t type[16]; + byte_t guid[16]; qword_t start_lba; qword_t end_lba; qword_t attributes; diff --git a/bootloader/common/include/hardware/drive/mapping/mbr.h b/bootloader/common/include/hardware/drive/mapping/mbr.h index 1fd1234..39f62ff 100644 --- a/bootloader/common/include/hardware/drive/mapping/mbr.h +++ b/bootloader/common/include/hardware/drive/mapping/mbr.h @@ -1,23 +1,23 @@ #ifndef COMMON_HARDWARE_DRIVE_MAPPING_MBR_H #define COMMON_HARDWARE_DRIVE_MAPPING_MBR_H -#include "../../../cpu/integer.h" #include "../../../attributes.h" +#include "../../../cpu/integer.h" typedef struct __packed _mbr_partition { - byte_t attributes; - byte_t start_chs[3]; - byte_t type; - byte_t last_chs[3]; + byte_t attributes; + byte_t start_chs[3]; + byte_t type; + byte_t last_chs[3]; dword_t lba_start; dword_t sectors_count; } mbr_partition; typedef struct __packed _mbr_mapping { - byte_t code[440]; - dword_t disk_id; - word_t rsv0; + byte_t code[440]; + dword_t disk_id; + word_t rsv0; mbr_partition partition_table[4]; - word_t signature; + word_t signature; } mbr_mapping; _Static_assert(sizeof(struct _mbr_partition) == 16, "Illegal structure size"); diff --git a/bootloader/common/include/stages.h b/bootloader/common/include/stages.h index 88f191f..70e80ce 100644 --- a/bootloader/common/include/stages.h +++ b/bootloader/common/include/stages.h @@ -6,6 +6,6 @@ #include "stages/tsl.h" #define EXTRA_LOAD_ADDRESS SSL_ADDRESS -#define EXTRA_LOAD_SIZE (SSL_SIZE + TSL_SIZE) +#define EXTRA_LOAD_SIZE (SSL_SIZE + TSL_SIZE) #endif // !COMMON_STAGES_H diff --git a/bootloader/common/include/stages/mbr.h b/bootloader/common/include/stages/mbr.h index 00c844d..202259c 100644 --- a/bootloader/common/include/stages/mbr.h +++ b/bootloader/common/include/stages/mbr.h @@ -1,12 +1,12 @@ #ifndef COMMON_STAGES_MBR_H #define COMMON_STAGES_MBR_H -#define MBR_ADDRESS 0x7C00 -#define MBR_SEGMENT (MBR_ADDRESS >> 4) +#define MBR_ADDRESS 0x7C00 +#define MBR_SEGMENT (MBR_ADDRESS >> 4) #define MBR_STACK_BOT_ADDRESS 0x500 #define MBR_STACK_TOP_ADDRESS (MBR_ADDRESS - 16) -#define MBR_STACK_SEGMENT (MBR_STACK_BOT_ADDR >> 4) -#define MBR_STACK_ADDRESS (MBR_STACK_TOP_ADDRESS - MBR_STACK_BOT_ADDRESS) +#define MBR_STACK_SEGMENT (MBR_STACK_BOT_ADDR >> 4) +#define MBR_STACK_ADDRESS (MBR_STACK_TOP_ADDRESS - MBR_STACK_BOT_ADDRESS) #endif // !COMMON_STAGES_MBR_H diff --git a/bootloader/common/include/stages/ssl.h b/bootloader/common/include/stages/ssl.h index a08ec64..1b8ed9a 100644 --- a/bootloader/common/include/stages/ssl.h +++ b/bootloader/common/include/stages/ssl.h @@ -3,6 +3,6 @@ #define SSL_ADDRESS 0x10000 #define SSL_SEGMENT (SSL_ADDRESS >> 4) -#define SSL_SIZE (64 * 1024) +#define SSL_SIZE (64 * 1024) #endif diff --git a/bootloader/common/include/stages/tsl.h b/bootloader/common/include/stages/tsl.h index b3c1531..cecd7b3 100644 --- a/bootloader/common/include/stages/tsl.h +++ b/bootloader/common/include/stages/tsl.h @@ -3,6 +3,6 @@ #define TSL_ADDRESS 0x20000 #define TSL_SEGMENT (TSL_ADDRESS >> 4) -#define TSL_SIZE (64 * 1024) +#define TSL_SIZE (64 * 1024) #endif From d9beff4368cbb2abd3c35f1bc88357f5075db190 Mon Sep 17 00:00:00 2001 From: arsenez Date: Sat, 14 Sep 2024 16:46:10 +0300 Subject: [PATCH 06/13] Relocate MBR to lower address --- bootloader/mbr/mbr.S | 20 ++++++++++++++++++++ bootloader/mbr/mbr.ld | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/bootloader/mbr/mbr.S b/bootloader/mbr/mbr.S index 0578ca8..10d89a4 100644 --- a/bootloader/mbr/mbr.S +++ b/bootloader/mbr/mbr.S @@ -1,7 +1,27 @@ .code16 .globl _entry +.section .text _entry: + cli + cld + /* Initialize segments */ + xorw %ax, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %ss + movw $0x7C00, %sp + + /* Relocate to lower address */ + movw $0x0100, %cx + movw $0x7C00, %si + movw $0x1000, %di + rep movsw + + /* Jump to relocated code */ + ljmp $0x0, $_relocated/* FIXME: Why the fuck ld segfaults when I put $_relocated here??? */ +_relocated: + sti .halt: hlt jmp .halt diff --git a/bootloader/mbr/mbr.ld b/bootloader/mbr/mbr.ld index 48e13d8..ae86075 100644 --- a/bootloader/mbr/mbr.ld +++ b/bootloader/mbr/mbr.ld @@ -2,7 +2,7 @@ OUTPUT(binary) ENTRY(_entry) MEMORY { - code (rwx) : ORIGIN = 0x00000000, LENGTH = 0x000001B8 + code (rwx) : ORIGIN = 0x00001000, LENGTH = 0x000001B8 } SECTIONS From d7f30d80d0c75c55bc59bbf4e24e8593d1caeae6 Mon Sep 17 00:00:00 2001 From: arsenez Date: Tue, 17 Sep 2024 22:27:33 +0300 Subject: [PATCH 07/13] Fix LD crash by swithing to cross-compiler --- bootloader/mbr/mbr.S | 19 +++++++++++++------ bootloader/mbr/mbr.ld | 1 + bootloader/mbr/meson.build | 3 ++- i686-elf.txt | 9 +++++++++ 4 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 i686-elf.txt diff --git a/bootloader/mbr/mbr.S b/bootloader/mbr/mbr.S index 10d89a4..292cdbc 100644 --- a/bootloader/mbr/mbr.S +++ b/bootloader/mbr/mbr.S @@ -1,3 +1,4 @@ +#include .code16 .globl _entry @@ -14,14 +15,20 @@ _entry: /* Relocate to lower address */ movw $0x0100, %cx - movw $0x7C00, %si - movw $0x1000, %di + movw %sp, %si + movw $_entry, %di rep movsw /* Jump to relocated code */ - ljmp $0x0, $_relocated/* FIXME: Why the fuck ld segfaults when I put $_relocated here??? */ -_relocated: + ljmp $0x0000, $.Lrelocated +.Lrelocated: sti -.halt: + +.Lhalt: hlt - jmp .halt + jmp .Lhalt + +.section .rodata +greet: .ascii "Loading VolgaBL " +version: .ascii VERSION +greet_end: .asciz "... " diff --git a/bootloader/mbr/mbr.ld b/bootloader/mbr/mbr.ld index ae86075..5c65f96 100644 --- a/bootloader/mbr/mbr.ld +++ b/bootloader/mbr/mbr.ld @@ -11,6 +11,7 @@ SECTIONS { *(.text) *(.data) + *(.rodata) } > code /DISCARD/ : { diff --git a/bootloader/mbr/meson.build b/bootloader/mbr/meson.build index 16129e4..1ab0106 100644 --- a/bootloader/mbr/meson.build +++ b/bootloader/mbr/meson.build @@ -4,4 +4,5 @@ mbr = executable('mbr.bin', 'mbr.S', c_link_args, c16_args, '-Wl,--Map=' + (meson.current_build_dir() / 'mbr.map'), - '-Wl,-T' + (meson.current_source_dir() / 'mbr.ld')]) + '-Wl,-T' + (meson.current_source_dir() / 'mbr.ld')], + dependencies: common_dep) diff --git a/i686-elf.txt b/i686-elf.txt new file mode 100644 index 0000000..296b05e --- /dev/null +++ b/i686-elf.txt @@ -0,0 +1,9 @@ +[binaries] +c = 'i686-elf-gcc' +strip = 'i686-elf-strip' + +[host_machine] +system = 'bios' +cpu_family = 'i686' +cpu = 'i686' +endian = 'little' From 8d9f7c4035bc1f64004b0f37231b1f1ea5a9d282 Mon Sep 17 00:00:00 2001 From: arsenez Date: Tue, 8 Oct 2024 00:34:44 +0300 Subject: [PATCH 08/13] Switch to el-torito boot strategy --- bootloader/common/include/attributes.h | 9 ----- bootloader/common/include/cpu/integer.h | 12 ------- bootloader/common/include/hardware/drive.h | 4 --- .../include/hardware/drive/mapping/gpt.h | 32 ----------------- .../include/hardware/drive/mapping/mbr.h | 26 -------------- bootloader/common/include/stages.h | 10 ++---- bootloader/common/include/stages/isoboot.h | 11 ++++++ bootloader/common/include/stages/mbr.h | 12 ------- bootloader/common/include/stages/pc-bios.h | 7 ++++ bootloader/common/include/stages/ssl.h | 8 ----- bootloader/common/include/stages/tsl.h | 8 ----- bootloader/isoboot/isoboot.ld | 12 +++++++ bootloader/isoboot/meson.build | 12 +++++++ bootloader/isoboot/pre_init.S | 28 +++++++++++++++ bootloader/mbr/mbr.S | 34 ------------------- bootloader/mbr/mbr.ld | 21 ------------ bootloader/mbr/meson.build | 8 ----- meson.build | 4 +-- 18 files changed, 75 insertions(+), 183 deletions(-) delete mode 100644 bootloader/common/include/attributes.h delete mode 100644 bootloader/common/include/cpu/integer.h delete mode 100644 bootloader/common/include/hardware/drive.h delete mode 100644 bootloader/common/include/hardware/drive/mapping/gpt.h delete mode 100644 bootloader/common/include/hardware/drive/mapping/mbr.h create mode 100644 bootloader/common/include/stages/isoboot.h delete mode 100644 bootloader/common/include/stages/mbr.h create mode 100644 bootloader/common/include/stages/pc-bios.h delete mode 100644 bootloader/common/include/stages/ssl.h delete mode 100644 bootloader/common/include/stages/tsl.h create mode 100644 bootloader/isoboot/isoboot.ld create mode 100644 bootloader/isoboot/meson.build create mode 100644 bootloader/isoboot/pre_init.S delete mode 100644 bootloader/mbr/mbr.S delete mode 100644 bootloader/mbr/mbr.ld delete mode 100644 bootloader/mbr/meson.build diff --git a/bootloader/common/include/attributes.h b/bootloader/common/include/attributes.h deleted file mode 100644 index 9dab6f5..0000000 --- a/bootloader/common/include/attributes.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef COMMON_ATTRIBUTES_H -#define COMMON_ATTRIBUTES_H - -#define __noreturn __attribute__((noreturn)) -#define __packed __attribute__((packed)) -#define __unused __attribute__((unused)) -#define __nodiscard __attribute__((warn_unused_result)) - -#endif diff --git a/bootloader/common/include/cpu/integer.h b/bootloader/common/include/cpu/integer.h deleted file mode 100644 index 52934a7..0000000 --- a/bootloader/common/include/cpu/integer.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef COMMON_CPU_INTEGER_H -#define COMMON_CPU_INTEGER_H - -#include -#include - -typedef uint8_t byte_t; -typedef uint16_t word_t; -typedef uint32_t dword_t; -typedef uint64_t qword_t; - -#endif diff --git a/bootloader/common/include/hardware/drive.h b/bootloader/common/include/hardware/drive.h deleted file mode 100644 index d164698..0000000 --- a/bootloader/common/include/hardware/drive.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef COMMON_HARDWARE_DRIVE_H -#define COMMON_HARDWARE_DRIVE_H - -#endif diff --git a/bootloader/common/include/hardware/drive/mapping/gpt.h b/bootloader/common/include/hardware/drive/mapping/gpt.h deleted file mode 100644 index da80565..0000000 --- a/bootloader/common/include/hardware/drive/mapping/gpt.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef COMMON_HARDWARE_DRIVE_MAPPING_GPT_H -#define COMMON_HARDWARE_DRIVE_MAPPING_GPT_H - -#include "../../../attributes.h" -#include "../../../cpu/integer.h" - -typedef struct __packed _gpt_mapping { - qword_t signature; - dword_t revision; - dword_t header_size; - dword_t checksum; - dword_t rsv0; - qword_t this_lba; - qword_t alt_lba; - qword_t first_lba; - qword_t last_lba; - byte_t disk_guid[16]; - qword_t partition_table_lba; - dword_t partition_count; - dword_t partition_entry_size; - dword_t partition_table_checksum; -} gpt_mapping; - -typedef struct __packed _gpt_partition { - byte_t type[16]; - byte_t guid[16]; - qword_t start_lba; - qword_t end_lba; - qword_t attributes; -} gpt_partition; - -#endif diff --git a/bootloader/common/include/hardware/drive/mapping/mbr.h b/bootloader/common/include/hardware/drive/mapping/mbr.h deleted file mode 100644 index 39f62ff..0000000 --- a/bootloader/common/include/hardware/drive/mapping/mbr.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef COMMON_HARDWARE_DRIVE_MAPPING_MBR_H -#define COMMON_HARDWARE_DRIVE_MAPPING_MBR_H -#include "../../../attributes.h" -#include "../../../cpu/integer.h" - -typedef struct __packed _mbr_partition { - byte_t attributes; - byte_t start_chs[3]; - byte_t type; - byte_t last_chs[3]; - dword_t lba_start; - dword_t sectors_count; -} mbr_partition; - -typedef struct __packed _mbr_mapping { - byte_t code[440]; - dword_t disk_id; - word_t rsv0; - mbr_partition partition_table[4]; - word_t signature; -} mbr_mapping; - -_Static_assert(sizeof(struct _mbr_partition) == 16, "Illegal structure size"); -_Static_assert(sizeof(struct _mbr_mapping) == 512, "Illegal structure size"); - -#endif diff --git a/bootloader/common/include/stages.h b/bootloader/common/include/stages.h index 70e80ce..fc38683 100644 --- a/bootloader/common/include/stages.h +++ b/bootloader/common/include/stages.h @@ -1,11 +1,7 @@ #ifndef COMMON_STAGES_H #define COMMON_STAGES_H -#include "stages/mbr.h" -#include "stages/ssl.h" -#include "stages/tsl.h" +#include "stages/isoboot.h" +#include "stages/pc-bios.h" -#define EXTRA_LOAD_ADDRESS SSL_ADDRESS -#define EXTRA_LOAD_SIZE (SSL_SIZE + TSL_SIZE) - -#endif // !COMMON_STAGES_H +#endif diff --git a/bootloader/common/include/stages/isoboot.h b/bootloader/common/include/stages/isoboot.h new file mode 100644 index 0000000..b5113d6 --- /dev/null +++ b/bootloader/common/include/stages/isoboot.h @@ -0,0 +1,11 @@ +#ifndef COMMON_STAGES_ISOBOOT_H +#define COMMON_STAGES_ISOBOOT_H + +#define ISOBOOT_ADDRESS 0x10000 +#define ISOBOOT_PRE_SIZE (2 * 1024) +#define ISOBOOT_SIZE (64 * 1024) + +#define ISOBOOT_SEGMENT (ISOBOOT_ADDRESS >> 4) +#define ISOBOOT_STACK (ISOBOOT_PRE_SIZE & -16) + +#endif diff --git a/bootloader/common/include/stages/mbr.h b/bootloader/common/include/stages/mbr.h deleted file mode 100644 index 202259c..0000000 --- a/bootloader/common/include/stages/mbr.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef COMMON_STAGES_MBR_H -#define COMMON_STAGES_MBR_H - -#define MBR_ADDRESS 0x7C00 -#define MBR_SEGMENT (MBR_ADDRESS >> 4) - -#define MBR_STACK_BOT_ADDRESS 0x500 -#define MBR_STACK_TOP_ADDRESS (MBR_ADDRESS - 16) -#define MBR_STACK_SEGMENT (MBR_STACK_BOT_ADDR >> 4) -#define MBR_STACK_ADDRESS (MBR_STACK_TOP_ADDRESS - MBR_STACK_BOT_ADDRESS) - -#endif // !COMMON_STAGES_MBR_H diff --git a/bootloader/common/include/stages/pc-bios.h b/bootloader/common/include/stages/pc-bios.h new file mode 100644 index 0000000..6827e2e --- /dev/null +++ b/bootloader/common/include/stages/pc-bios.h @@ -0,0 +1,7 @@ +#ifndef COMMON_STAGES_PCBIOS_H +#define COMMON_STAGES_PCBIOS_H + +#define PCBIOS_LOAD_ADDRESS 0x7C00 +#define PCBIOS_LOAD_SEGMENT (PCBIOS_LOAD_ADDRESS >> 4) + +#endif diff --git a/bootloader/common/include/stages/ssl.h b/bootloader/common/include/stages/ssl.h deleted file mode 100644 index 1b8ed9a..0000000 --- a/bootloader/common/include/stages/ssl.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef COMMON_STAGES_SSL_H -#define COMMON_STAGES_SSL_H - -#define SSL_ADDRESS 0x10000 -#define SSL_SEGMENT (SSL_ADDRESS >> 4) -#define SSL_SIZE (64 * 1024) - -#endif diff --git a/bootloader/common/include/stages/tsl.h b/bootloader/common/include/stages/tsl.h deleted file mode 100644 index cecd7b3..0000000 --- a/bootloader/common/include/stages/tsl.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef COMMON_STAGES_TSL_H -#define COMMON_STAGES_TSL_H - -#define TSL_ADDRESS 0x20000 -#define TSL_SEGMENT (TSL_ADDRESS >> 4) -#define TSL_SIZE (64 * 1024) - -#endif diff --git a/bootloader/isoboot/isoboot.ld b/bootloader/isoboot/isoboot.ld new file mode 100644 index 0000000..b632f79 --- /dev/null +++ b/bootloader/isoboot/isoboot.ld @@ -0,0 +1,12 @@ +OUTPUT(binary) +MEMORY +{ + segment (rwx) : org = 0, len = 64k +} + +SECTIONS +{ + .text.pre : { + *(.text.pre) + } > segment +} diff --git a/bootloader/isoboot/meson.build b/bootloader/isoboot/meson.build new file mode 100644 index 0000000..a14d47c --- /dev/null +++ b/bootloader/isoboot/meson.build @@ -0,0 +1,12 @@ +isoboot = executable( + 'isoboot.bin', + 'pre_init.S', + c_args: [ c_args, c16_args ], + link_args: [ + c_link_args, + c16_args, + '-Wl,--Map=' + (meson.build_root() / 'isoboot.map'), + '-Wl,-T' + (meson.current_source_dir() / 'isoboot.ld') + ], + dependencies: [ common_dep ] +) diff --git a/bootloader/isoboot/pre_init.S b/bootloader/isoboot/pre_init.S new file mode 100644 index 0000000..ef61daa --- /dev/null +++ b/bootloader/isoboot/pre_init.S @@ -0,0 +1,28 @@ +.code16 +.globl _pre_init + +#include +#include + +.section .text.pre +_pre_init: + /* Relocate to a well-known address */ + cld + cli + + movw $PCBIOS_LOAD_SEGMENT, %ax + movw %ax, %ds + xorw %si, %si + + movw $ISOBOOT_SEGMENT, %ax + movw %ax, %es + xorw %di, %di + + movw $ISOBOOT_PRE_SIZE >> 1, %cx + + ljmp $ISOBOOT_SEGMENT, $.Lrelocated +.Lrelocated: + +.Lhalt: + hlt + jmp .Lhalt diff --git a/bootloader/mbr/mbr.S b/bootloader/mbr/mbr.S deleted file mode 100644 index 292cdbc..0000000 --- a/bootloader/mbr/mbr.S +++ /dev/null @@ -1,34 +0,0 @@ -#include -.code16 -.globl _entry - -.section .text -_entry: - cli - cld - /* Initialize segments */ - xorw %ax, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %ss - movw $0x7C00, %sp - - /* Relocate to lower address */ - movw $0x0100, %cx - movw %sp, %si - movw $_entry, %di - rep movsw - - /* Jump to relocated code */ - ljmp $0x0000, $.Lrelocated -.Lrelocated: - sti - -.Lhalt: - hlt - jmp .Lhalt - -.section .rodata -greet: .ascii "Loading VolgaBL " -version: .ascii VERSION -greet_end: .asciz "... " diff --git a/bootloader/mbr/mbr.ld b/bootloader/mbr/mbr.ld deleted file mode 100644 index 5c65f96..0000000 --- a/bootloader/mbr/mbr.ld +++ /dev/null @@ -1,21 +0,0 @@ -OUTPUT(binary) -ENTRY(_entry) -MEMORY -{ - code (rwx) : ORIGIN = 0x00001000, LENGTH = 0x000001B8 -} - -SECTIONS -{ - .text : - { - *(.text) - *(.data) - *(.rodata) - } > code - /DISCARD/ : - { - *(.note*) - *(.comment*) - } -} diff --git a/bootloader/mbr/meson.build b/bootloader/mbr/meson.build deleted file mode 100644 index 1ab0106..0000000 --- a/bootloader/mbr/meson.build +++ /dev/null @@ -1,8 +0,0 @@ -mbr = executable('mbr.bin', 'mbr.S', - c_args: [ c_args, c16_args ], - link_args : [ - c_link_args, - c16_args, - '-Wl,--Map=' + (meson.current_build_dir() / 'mbr.map'), - '-Wl,-T' + (meson.current_source_dir() / 'mbr.ld')], - dependencies: common_dep) diff --git a/meson.build b/meson.build index ea468c1..eb22f83 100644 --- a/meson.build +++ b/meson.build @@ -29,5 +29,5 @@ bl_version = meson.project_version() # Import common library subdir('bootloader/common') -# Import MBR -subdir('bootloader/mbr') +# Import isoboot +subdir('bootloader/isoboot') From 7972a1084a5c590746ecc3967a467c9f9bcacfb5 Mon Sep 17 00:00:00 2001 From: arsenez Date: Tue, 8 Oct 2024 10:53:49 +0300 Subject: [PATCH 09/13] Initialize segments and print bootloader version --- bootloader/isoboot/isoboot.ld | 7 +++++-- bootloader/isoboot/pre_init.S | 28 ++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/bootloader/isoboot/isoboot.ld b/bootloader/isoboot/isoboot.ld index b632f79..5b7ffb3 100644 --- a/bootloader/isoboot/isoboot.ld +++ b/bootloader/isoboot/isoboot.ld @@ -1,12 +1,15 @@ OUTPUT(binary) MEMORY { - segment (rwx) : org = 0, len = 64k + preload (rwx) : org = 0, len = 64k } SECTIONS { .text.pre : { *(.text.pre) - } > segment + } > preload + .rodata.pre : { + *(.rodata.pre) + } } diff --git a/bootloader/isoboot/pre_init.S b/bootloader/isoboot/pre_init.S index ef61daa..61b143a 100644 --- a/bootloader/isoboot/pre_init.S +++ b/bootloader/isoboot/pre_init.S @@ -3,6 +3,7 @@ #include #include +#include .section .text.pre _pre_init: @@ -19,10 +20,33 @@ _pre_init: xorw %di, %di movw $ISOBOOT_PRE_SIZE >> 1, %cx - + + rep movsw + ljmp $ISOBOOT_SEGMENT, $.Lrelocated .Lrelocated: - + /* Initialize segments */ + movw %ax, %ds + movw %ax, %ss + movw $ISOBOOT_STACK, %sp + sti + + /* Print greet message */ + movw $greet, %si + xorb %bh, %bh + movb $0x0E, %ah +.Lgreet_loop: + lodsb + orb %al, %al + jz .Lhalt + int $0x10 + jmp .Lgreet_loop .Lhalt: hlt jmp .Lhalt + +.section .rodata.pre +greet: +.ascii "Loading VolgaBL " +.ascii VERSION +.asciz "...\r\n" From 8688b665cdd30da22a9390023424cd93725d7636 Mon Sep 17 00:00:00 2001 From: arsenez Date: Tue, 8 Oct 2024 12:08:18 +0300 Subject: [PATCH 10/13] Add git hooks --- .githooks/post-commit | 4 ++++ .githooks/pre-commit | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100755 .githooks/post-commit create mode 100755 .githooks/pre-commit diff --git a/.githooks/post-commit b/.githooks/post-commit new file mode 100755 index 0000000..fff8293 --- /dev/null +++ b/.githooks/post-commit @@ -0,0 +1,4 @@ +#!/bin/sh + +# Reconfigure preoject +meson setup --reconfigure build diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 0000000..81d8ae4 --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,16 @@ +#!/bin/sh + +# Run Clang-Format +for file in `git diff-index --cached --name-only HEAD | grep -iE '\.(cpp|cc|h|hpp)$'` ; do + clang-format -i $file + git add $file +done + +# Try to compile +pushd build +if ! meson compile; then + exit 1 +fi +popd + +exit 0 From 6232cd16e60d3e0a982d26043e31baa3410e6bb8 Mon Sep 17 00:00:00 2001 From: arsenez Date: Tue, 8 Oct 2024 12:10:26 +0300 Subject: [PATCH 11/13] Run clang-format --- bootloader/common/include/stages/isoboot.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bootloader/common/include/stages/isoboot.h b/bootloader/common/include/stages/isoboot.h index b5113d6..1420c87 100644 --- a/bootloader/common/include/stages/isoboot.h +++ b/bootloader/common/include/stages/isoboot.h @@ -1,11 +1,11 @@ #ifndef COMMON_STAGES_ISOBOOT_H #define COMMON_STAGES_ISOBOOT_H -#define ISOBOOT_ADDRESS 0x10000 +#define ISOBOOT_ADDRESS 0x10000 #define ISOBOOT_PRE_SIZE (2 * 1024) -#define ISOBOOT_SIZE (64 * 1024) +#define ISOBOOT_SIZE (64 * 1024) -#define ISOBOOT_SEGMENT (ISOBOOT_ADDRESS >> 4) -#define ISOBOOT_STACK (ISOBOOT_PRE_SIZE & -16) +#define ISOBOOT_SEGMENT (ISOBOOT_ADDRESS >> 4) +#define ISOBOOT_STACK (ISOBOOT_PRE_SIZE & -16) #endif From 838ae78e159fd7c89fabf4e994b58c918fe1735d Mon Sep 17 00:00:00 2001 From: arsenez Date: Wed, 9 Oct 2024 11:56:47 +0300 Subject: [PATCH 12/13] Add procedures for printing messages and errors --- bootloader/isoboot/pre_init.S | 45 +++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/bootloader/isoboot/pre_init.S b/bootloader/isoboot/pre_init.S index 61b143a..b9c64eb 100644 --- a/bootloader/isoboot/pre_init.S +++ b/bootloader/isoboot/pre_init.S @@ -33,20 +33,55 @@ _pre_init: /* Print greet message */ movw $greet, %si + call _print_msg + + movw $0xDEAD, %ax + call _error +.Lhalt: + hlt + jmp .Lhalt + +/* Prints message from SI */ +_print_msg: + pushaw xorb %bh, %bh movb $0x0E, %ah -.Lgreet_loop: +.Lprint_loop: lodsb orb %al, %al - jz .Lhalt + jz .Lprint_done int $0x10 - jmp .Lgreet_loop -.Lhalt: + jmp .Lprint_loop +.Lprint_done: + popaw + ret + +/* Prints error message with error code from AX and halt processor */ +_error: + movw %ax, %dx + movw $error_msg, %si + call _print_msg + movw $4, %cx + movb $0x0E, %ah +.Lnum_loop: + movb %dh, %bl + shrb $4, %bl + movb hex_alphabet(%bx), %al + int $0x10 + shlw $4, %dx + loop .Lnum_loop +.Lehalt: hlt - jmp .Lhalt + jmp .Lehalt .section .rodata.pre greet: .ascii "Loading VolgaBL " .ascii VERSION .asciz "...\r\n" + +error_msg: +.asciz "ISOBOOT PRE error: 0x" + +hex_alphabet: +.ascii "0123456789ABCDEF" From ec0f58b0d0170e9eeb84cffb0bbb376ab75586ab Mon Sep 17 00:00:00 2001 From: arsenez Date: Fri, 11 Oct 2024 13:39:50 +0300 Subject: [PATCH 13/13] Check presence of BIOS drive extension and get boot drive parameteres --- bootloader/isoboot/isoboot.ld | 8 ++++- bootloader/isoboot/pre_init.S | 65 ++++++++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/bootloader/isoboot/isoboot.ld b/bootloader/isoboot/isoboot.ld index 5b7ffb3..3acbbcd 100644 --- a/bootloader/isoboot/isoboot.ld +++ b/bootloader/isoboot/isoboot.ld @@ -1,7 +1,8 @@ OUTPUT(binary) MEMORY { - preload (rwx) : org = 0, len = 64k + preload (rwx) : org = 0, len = 2k + extended (rwx) : org = 0x800, len = 62k } SECTIONS @@ -11,5 +12,10 @@ SECTIONS } > preload .rodata.pre : { *(.rodata.pre) + } > preload + .data.pre : { + *(.data.pre) } + .text : { + } > extended } diff --git a/bootloader/isoboot/pre_init.S b/bootloader/isoboot/pre_init.S index b9c64eb..3df2333 100644 --- a/bootloader/isoboot/pre_init.S +++ b/bootloader/isoboot/pre_init.S @@ -5,6 +5,18 @@ #include #include +#define READ_BUFFER ISOBOOT_PRE_SIZE + +#define drive -2(%bp) +#define sector_size -4(%bp) +#define dap_lba_high -8(%bp) +#define dap_lba_low -12(%bp) +#define dap_segment -14(%bp) +#define dap_offset -16(%bp) +#define dap_count -18(%bp) +#define dap_size -20(%bp) +#define dap dap_size + .section .text.pre _pre_init: /* Relocate to a well-known address */ @@ -35,8 +47,58 @@ _pre_init: movw $greet, %si call _print_msg - movw $0xDEAD, %ax + /* Check for Extended Fixed Disk Services extension */ + movb $0x41, %ah + movw $0x55AA, %bx + int $0x13 + jnc .Lext_check_done + movw $0x01, %ax + call _error +.Lext_check_done: + + /* Get drive parameteres */ + movb $0x48, %ah + movw $READ_BUFFER, %si + movw $26, (%si) + int $0x13 + jnc .Lget_drive_done + mov $0x02, %ax call _error +.Lget_drive_done: + + /* Save drive number and sectors count on stack */ + movw %sp, %bp + xorb %dh, %dh + pushw %dx + movw 24(%si), %ax + pushw %ax + + /* Construct DAP */ + pushl $0 /* LBA high */ + pushl $0 /* LBA low */ + pushw %ds /* Segment */ + pushw $READ_BUFFER /* Offset */ + pushw $0 /* Sector count */ + pushw $16 /* DAP size */ + + /* Calculate sector count */ + movw sector_size, %bx + movw $2048, %ax + xorw %dx, %dx + div %bx + movw %ax, dap_count + + /* Calculate LBA */ + movw $32768, %ax + xorw %dx, %dx + div %bx + movw %ax, dap_lba_low + + movb drive, %dl + leaw dap, %si + movb $0x42, %ah + int $0x13 + .Lhalt: hlt jmp .Lhalt @@ -63,6 +125,7 @@ _error: call _print_msg movw $4, %cx movb $0x0E, %ah + xorb %bh, %bh .Lnum_loop: movb %dh, %bl shrb $4, %bl