From 9f298841a4fdb3048ef6621c6aac903da009d797 Mon Sep 17 00:00:00 2001 From: apio Date: Fri, 26 May 2023 23:28:51 +0200 Subject: [PATCH] kernel: Start reading the MBR partition table from the ATAPI drive --- kernel/CMakeLists.txt | 1 + kernel/src/arch/x86_64/disk/ATA.cpp | 5 +++++ kernel/src/fs/MBR.cpp | 29 ++++++++++++++++++++++++ kernel/src/fs/MBR.h | 35 +++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+) create mode 100644 kernel/src/fs/MBR.cpp create mode 100644 kernel/src/fs/MBR.h diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 8c266e6d..4352da53 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -43,6 +43,7 @@ set(SOURCES src/fs/VFS.cpp src/fs/Pipe.cpp src/fs/Mount.cpp + src/fs/MBR.cpp src/fs/tmpfs/FileSystem.cpp src/fs/devices/DeviceRegistry.cpp src/fs/devices/NullDevice.cpp diff --git a/kernel/src/arch/x86_64/disk/ATA.cpp b/kernel/src/arch/x86_64/disk/ATA.cpp index 7e2050c0..412b1c9d 100644 --- a/kernel/src/arch/x86_64/disk/ATA.cpp +++ b/kernel/src/arch/x86_64/disk/ATA.cpp @@ -3,6 +3,7 @@ #include "arch/Serial.h" #include "arch/Timer.h" #include "arch/x86_64/IO.h" +#include "fs/MBR.h" #include "memory/MemoryManager.h" #include #include @@ -336,6 +337,10 @@ namespace ATA kwarnln("ata: Failed to register ATA drive %d:%d in DeviceRegistry", m_channel_index, drive); continue; } + + // FIXME: Do not hardcode the path like this. + auto inode = VFS::resolve_path("/dev/cdrom", Credentials {}).value(); + MBR::identify(inode); } } diff --git a/kernel/src/fs/MBR.cpp b/kernel/src/fs/MBR.cpp new file mode 100644 index 00000000..21bce837 --- /dev/null +++ b/kernel/src/fs/MBR.cpp @@ -0,0 +1,29 @@ +#include "fs/MBR.h" +#include "Log.h" + +namespace MBR +{ + Result identify(SharedPtr inode) + { + // Cannot read a partition table from a pipe/socket/character device! Who is even coming up with this silliness? + if (!VFS::is_seekable(inode)) return false; + + DiskHeader hdr; + usize nread = TRY(inode->read((u8*)&hdr, 0, sizeof(hdr))); + check(nread == 512); + + if (hdr.signature[0] != MBR_SIGNATURE_1 || hdr.signature[1] != MBR_SIGNATURE_2) return false; + + for (int i = 0; i < 4; i++) + { + const auto& part = hdr.partitions[i]; + if (part.partition_type == 0) continue; // Not active. + + bool bootable = part.attributes & MBR_BOOTABLE; + kinfoln("mbr: Partition #%d is active: bootable=%d, type=%x, start=%d, sectors=%d", i, bootable, + part.partition_type, part.start_lba, part.num_sectors); + } + + return true; + } +} diff --git a/kernel/src/fs/MBR.h b/kernel/src/fs/MBR.h new file mode 100644 index 00000000..d447cdef --- /dev/null +++ b/kernel/src/fs/MBR.h @@ -0,0 +1,35 @@ +#pragma once + +#include "fs/VFS.h" +#include + +#define MBR_BOOTABLE 0x80 + +#define MBR_SIGNATURE_1 0x55 +#define MBR_SIGNATURE_2 0xAA + +namespace MBR +{ + struct [[gnu::packed]] PartitionHeader + { + u8 attributes; + u8 chs_start[3]; + u8 partition_type; + u8 chs_end[3]; + u32 start_lba; + u32 num_sectors; + }; + + struct [[gnu::packed]] DiskHeader + { + u8 mbr_code[440]; + u8 disk_id[4]; + u8 reserved[2]; + PartitionHeader partitions[4]; + u8 signature[2]; + }; + + static_assert(sizeof(DiskHeader) == 512ul); + + Result identify(SharedPtr inode); +};