kernel: Start reading the MBR partition table from the ATAPI drive

This commit is contained in:
apio 2023-05-26 23:28:51 +02:00
parent a3beaa4d53
commit 93922932fa
Signed by: apio
GPG Key ID: B8A7D06E42258954
4 changed files with 70 additions and 0 deletions

View File

@ -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

View File

@ -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 <luna/Alignment.h>
#include <luna/CType.h>
@ -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);
}
}

29
kernel/src/fs/MBR.cpp Normal file
View File

@ -0,0 +1,29 @@
#include "fs/MBR.h"
#include "Log.h"
namespace MBR
{
Result<bool> identify(SharedPtr<VFS::Inode> 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;
}
}

35
kernel/src/fs/MBR.h Normal file
View File

@ -0,0 +1,35 @@
#pragma once
#include "fs/VFS.h"
#include <luna/Types.h>
#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<bool> identify(SharedPtr<VFS::Inode> inode);
};