From 7e36a0be7599e4d023b8696227e5d856ee82bfd0 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Fri, 12 Jan 2024 19:25:07 +0200 Subject: [PATCH] Bootloader: Add .data section --- bootloader/bios/a20_line.S | 2 ++ bootloader/bios/boot.S | 2 ++ bootloader/bios/command_line.S | 2 ++ bootloader/bios/disk.S | 1 + bootloader/bios/elf.S | 1 + bootloader/bios/ext2.S | 2 +- bootloader/bios/framebuffer.S | 1 + bootloader/bios/linker.ld | 2 ++ bootloader/bios/memory_map.S | 1 + bootloader/installer/GPT.cpp | 38 +++++++++++++++++++--------------- bootloader/installer/GPT.h | 4 ++-- bootloader/installer/build.sh | 3 --- bootloader/installer/main.cpp | 7 ++++--- 13 files changed, 40 insertions(+), 26 deletions(-) delete mode 100755 bootloader/installer/build.sh diff --git a/bootloader/bios/a20_line.S b/bootloader/bios/a20_line.S index 101e57bf..7b68b73c 100644 --- a/bootloader/bios/a20_line.S +++ b/bootloader/bios/a20_line.S @@ -156,6 +156,8 @@ enable_a20: popw %ax ret +.section .data + a20_line_disabled_msg: .asciz "A20 line disabled. Trying to enable it" diff --git a/bootloader/bios/boot.S b/bootloader/bios/boot.S index 90943117..4d61652e 100644 --- a/bootloader/bios/boot.S +++ b/bootloader/bios/boot.S @@ -143,6 +143,8 @@ enter_unreal_mode: ret +.section .data + hello_msg: .asciz "This is banan-os bootloader" diff --git a/bootloader/bios/command_line.S b/bootloader/bios/command_line.S index ba442e9a..847db219 100644 --- a/bootloader/bios/command_line.S +++ b/bootloader/bios/command_line.S @@ -74,6 +74,8 @@ read_user_command_line: ret +.section .data + command_line_enter_msg: .asciz "cmdline: " diff --git a/bootloader/bios/disk.S b/bootloader/bios/disk.S index 1b49c4d4..e5b13b2f 100644 --- a/bootloader/bios/disk.S +++ b/bootloader/bios/disk.S @@ -470,6 +470,7 @@ print_root_partition_info: popw %ax ret +.section .data # These will be patched during bootloader installation root_disk_guid: diff --git a/bootloader/bios/elf.S b/bootloader/bios/elf.S index d4a9b8df..3499e5ee 100644 --- a/bootloader/bios/elf.S +++ b/bootloader/bios/elf.S @@ -196,6 +196,7 @@ elf_read_kernel_to_memory: movw $elf_read_kernel_to_memory_not_loadable_header_msg, %si jmp print_and_halt +.section .data elf_validate_file_header_invalid_magic_msg: .asciz "ELF: file has invalid ELF magic" diff --git a/bootloader/bios/ext2.S b/bootloader/bios/ext2.S index 63901fab..edbcdfa3 100644 --- a/bootloader/bios/ext2.S +++ b/bootloader/bios/ext2.S @@ -692,6 +692,7 @@ ext2_find_kernel: movw $ext2_kernel_not_reg_msg, %si jmp print_and_halt +.section .data kernel_path: .short kernel_path1 @@ -704,7 +705,6 @@ kernel_path2: .short 15 .asciz "banan-os.kernel" - root_partition_does_not_fit_ext2_filesystem_msg: .asciz "Root partition is too small to contain ext2 filesystem" root_partition_has_invalid_ext2_magic_msg: diff --git a/bootloader/bios/framebuffer.S b/bootloader/bios/framebuffer.S index 3ff46c0f..23993ae1 100644 --- a/bootloader/bios/framebuffer.S +++ b/bootloader/bios/framebuffer.S @@ -185,6 +185,7 @@ vesa_set_video_mode: popw %ax ret +.section .data vesa_error_msg: .asciz "VESA error" diff --git a/bootloader/bios/linker.ld b/bootloader/bios/linker.ld index eecbf531..87de1da5 100644 --- a/bootloader/bios/linker.ld +++ b/bootloader/bios/linker.ld @@ -8,6 +8,8 @@ SECTIONS . = ALIGN(512); stage2_start = .; .stage2 : { *(.stage2) } + . = ALIGN(512); + .data : { *(.data) } stage2_end = .; . = ALIGN(512); diff --git a/bootloader/bios/memory_map.S b/bootloader/bios/memory_map.S index 55c7d710..e257d5db 100644 --- a/bootloader/bios/memory_map.S +++ b/bootloader/bios/memory_map.S @@ -114,6 +114,7 @@ print_memory_map: ret +.section .data memory_map_msg: .asciz "memmap:" diff --git a/bootloader/installer/GPT.cpp b/bootloader/installer/GPT.cpp index d864b301..f1874c6b 100644 --- a/bootloader/installer/GPT.cpp +++ b/bootloader/installer/GPT.cpp @@ -99,33 +99,33 @@ bool GPTFile::install_stage1(std::span stage1) return true; } -bool GPTFile::install_stage2(std::span stage2, const GUID& root_partition_guid) +bool GPTFile::install_stage2(std::span stage2, std::span data, const GUID& root_partition_guid) { - if (stage2.size() < 16) + if (data.size() < 16) { - std::cerr << m_path << ": contains invalid .stage2 section, too small for patches" << std::endl; + std::cerr << m_path << ": contains invalid .data section, too small for patches" << std::endl; return false; } // find GUID patch offsets std::size_t disk_guid_offset(-1); std::size_t part_guid_offset(-1); - for (std::size_t i = 0; i < stage2.size() - 16; i++) + for (std::size_t i = 0; i < data.size() - 16; i++) { - if (memcmp(stage2.data() + i, "root disk guid ", 16) == 0) + if (memcmp(data.data() + i, "root disk guid ", 16) == 0) { if (disk_guid_offset != std::size_t(-1)) { - std::cerr << m_path << ": contains invalid .stage2 section, multiple patchable disk guids" << std::endl; + std::cerr << m_path << ": contains invalid .data section, multiple patchable disk guids" << std::endl; return false; } disk_guid_offset = i; } - if (memcmp(stage2.data() + i, "root part guid ", 16) == 0) + if (memcmp(data.data() + i, "root part guid ", 16) == 0) { if (part_guid_offset != std::size_t(-1)) { - std::cerr << m_path << ": contains invalid .stage2 section, multiple patchable partition guids" << std::endl; + std::cerr << m_path << ": contains invalid .data section, multiple patchable partition guids" << std::endl; return false; } part_guid_offset = i; @@ -133,15 +133,14 @@ bool GPTFile::install_stage2(std::span stage2, const GUID& root_p } if (disk_guid_offset == std::size_t(-1)) { - std::cerr << m_path << ": contains invalid .stage2 section, no patchable disk guid" << std::endl; + std::cerr << m_path << ": contains invalid .data section, no patchable disk guid" << std::endl; return false; } if (part_guid_offset == std::size_t(-1)) { - std::cerr << m_path << ": contains invalid .stage2 section, no patchable partition guid" << std::endl; + std::cerr << m_path << ": contains invalid .data section, no patchable partition guid" << std::endl; return false; } - auto partition = find_partition_with_type(bios_boot_guid); if (!partition.has_value()) @@ -152,23 +151,28 @@ bool GPTFile::install_stage2(std::span stage2, const GUID& root_p const std::size_t partition_size = (partition->ending_lba - partition->starting_lba + 1) * SECTOR_SIZE; - if (stage2.size() > partition_size) + std::size_t data_offset = stage2.size(); + if (std::size_t rem = data_offset % 512) + data_offset += 512 - rem; + + if (data_offset + data.size() > partition_size) { - std::cerr << m_path << ": can't fit " << stage2.size() << " bytes of data to partition of size " << partition_size << std::endl; + std::cerr << m_path << ": can't fit " << stage2.size() + data.size() << " bytes of data to partition of size " << partition_size << std::endl; return false; } uint8_t* partition_start = m_mmap + partition->starting_lba * SECTOR_SIZE; memcpy(partition_start, stage2.data(), stage2.size()); + memcpy(partition_start + data_offset, data.data(), data.size()); // patch GUIDs - *reinterpret_cast(partition_start + disk_guid_offset) = gpt_header().disk_guid; - *reinterpret_cast(partition_start + part_guid_offset) = root_partition_guid; + *reinterpret_cast(partition_start + data_offset + disk_guid_offset) = gpt_header().disk_guid; + *reinterpret_cast(partition_start + data_offset + part_guid_offset) = root_partition_guid; return true; } -bool GPTFile::install_bootloader(std::span stage1, std::span stage2, const GUID& root_partition_guid) +bool GPTFile::install_bootloader(std::span stage1, std::span stage2, std::span data, const GUID& root_partition_guid) { if (!find_partition_with_guid(root_partition_guid).has_value()) { @@ -177,7 +181,7 @@ bool GPTFile::install_bootloader(std::span stage1, std::span stage1, std::span stage2, const GUID& root_partition_guid); + bool install_bootloader(std::span stage1, std::span stage2, std::span data, const GUID& root_partition_guid); const GPTHeader& gpt_header() const; @@ -80,7 +80,7 @@ private: std::optional find_partition_with_type(const GUID& type_guid) const; bool install_stage1(std::span stage1); - bool install_stage2(std::span stage2, const GUID& root_partition_guid); + bool install_stage2(std::span stage2, std::span data, const GUID& root_partition_guid); private: const std::string m_path; diff --git a/bootloader/installer/build.sh b/bootloader/installer/build.sh deleted file mode 100755 index 719fb30e..00000000 --- a/bootloader/installer/build.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -g++ -O2 -std=c++20 main.cpp crc32.cpp ELF.cpp GPT.cpp GUID.cpp -o install-bootloader diff --git a/bootloader/installer/main.cpp b/bootloader/installer/main.cpp index 3103256c..8e3f0145 100644 --- a/bootloader/installer/main.cpp +++ b/bootloader/installer/main.cpp @@ -26,9 +26,10 @@ int main(int argc, char** argv) auto stage1 = bootloader.find_section(".stage1"sv); auto stage2 = bootloader.find_section(".stage2"sv); - if (!stage1.has_value() || !stage2.has_value()) + auto data = bootloader.find_section(".data"sv); + if (!stage1.has_value() || !stage2.has_value() || !data.has_value()) { - std::cerr << bootloader.path() << " doesn't contain .stage1 and .stage2 sections" << std::endl; + std::cerr << bootloader.path() << " doesn't contain .stage1, .stage2 and .data sections" << std::endl; return 1; } @@ -36,7 +37,7 @@ int main(int argc, char** argv) if (!disk_image.success()) return 1; - if (!disk_image.install_bootloader(*stage1, *stage2, *root_partition_guid)) + if (!disk_image.install_bootloader(*stage1, *stage2, *data, *root_partition_guid)) return 1; std::cout << "bootloader installed" << std::endl;