From bb20921d00c770cb30bb85a300423d9062a94d91 Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Sun, 8 Nov 2026 07:49:23 +0800 Subject: [mubios] Multi-sector INT 13h AH=42h Signed-off-by: Richard Qin --- mubios/core/post.c | 2 +- mubios/drivers/ata.c | 24 ++++++++++++++++++++++-- mubios/include/bios.h | 2 +- mubios/services/int13.c | 9 ++++++--- 4 files changed, 30 insertions(+), 7 deletions(-) (limited to 'mubios') diff --git a/mubios/core/post.c b/mubios/core/post.c index 076d262..2af797b 100644 --- a/mubios/core/post.c +++ b/mubios/core/post.c @@ -40,7 +40,7 @@ post_main (void) u8 ata_status; mbr = (volatile u8 *)0x00007C00u; - ata_status = ata_read_sector28 (0, (u16 *)mbr); + ata_status = ata_read_sectors28 (0, (u16 *)mbr, 1); if (ata_status == 0 && mbr[0x01FE] == 0x55 && mbr[0x01FF] == 0xAA) serial_write ("mubios: MBR loaded\r\n"); diff --git a/mubios/drivers/ata.c b/mubios/drivers/ata.c index a0cd12a..928a7d1 100644 --- a/mubios/drivers/ata.c +++ b/mubios/drivers/ata.c @@ -60,8 +60,8 @@ ata_delay_400ns (void) io_in8 (ATA_STATUS); } -u8 -ata_read_sector28 (u32 lba, u16 *buffer) +static u8 +ata_read_one_sector28 (u32 lba, u16 *buffer) { u8 status; u16 index; @@ -91,3 +91,23 @@ ata_read_sector28 (u32 lba, u16 *buffer) return 0; } + +u8 +ata_read_sectors28 (u32 lba, u16 *buffer, u16 count) +{ + u16 sector; + + if (count == 0u) + return 1; + + for (sector = 0; sector < count; ++sector) + { + if (ata_read_one_sector28 (lba, buffer) != 0) + return 1; + + lba++; + buffer += 256; + } + + return 0; +} diff --git a/mubios/include/bios.h b/mubios/include/bios.h index 29743e0..9c14a42 100644 --- a/mubios/include/bios.h +++ b/mubios/include/bios.h @@ -50,7 +50,7 @@ void ioapic_init (void); void ivt_init (void); -u8 ata_read_sector28 (u32 lba, u16 *buffer); +u8 ata_read_sectors28 (u32 lba, u16 *buffer, u16 count); struct bios_regs; diff --git a/mubios/services/int13.c b/mubios/services/int13.c index 078fa03..e5cef43 100644 --- a/mubios/services/int13.c +++ b/mubios/services/int13.c @@ -79,8 +79,9 @@ int13_service (struct bios_regs *regs) { packet = get_edd_packet (regs); - if (packet->size != 0x10u || packet->count != 1u - || packet->lba_high != 0u || packet->lba_low > 0x0FFFFFFFu) + if (packet->size != 0x10u || packet->count == 0u || packet->count > 127u + || packet->lba_high != 0u + || packet->lba_low > 0x10000000u - (u32)packet->count) { int13_fail (regs); return; @@ -89,7 +90,9 @@ int13_service (struct bios_regs *regs) buffer_address = ((u32)packet->buffer_segment << 4) + packet->buffer_offset; - if (ata_read_sector28 (packet->lba_low, (u16 *)buffer_address) != 0) + if (ata_read_sectors28 (packet->lba_low, (u16 *)buffer_address, + packet->count) + != 0) { int13_fail (regs); return; -- cgit v1.2.3