diff options
| author | Richard Qin <richard.qin.x@gmail.com> | 2026-11-08 07:49:23 +0800 |
|---|---|---|
| committer | Richard Qin <richard.qin.x@gmail.com> | 2026-11-08 07:49:23 +0800 |
| commit | bb20921d00c770cb30bb85a300423d9062a94d91 (patch) | |
| tree | 047e61340edaa3c3d4bf0e9d01ba7786bfda5368 | |
| parent | 9bfc57c3684f7aebba0f6865a1ea248f576b947f (diff) | |
| download | rcc-project-bb20921d00c770cb30bb85a300423d9062a94d91.tar.gz rcc-project-bb20921d00c770cb30bb85a300423d9062a94d91.tar.xz | |
[mubios] Multi-sector INT 13h AH=42h
Signed-off-by: Richard Qin <richard.qin.x@gmail.com>
| -rw-r--r-- | mubios/core/post.c | 2 | ||||
| -rw-r--r-- | mubios/drivers/ata.c | 24 | ||||
| -rw-r--r-- | mubios/include/bios.h | 2 | ||||
| -rw-r--r-- | mubios/services/int13.c | 9 |
4 files changed, 30 insertions, 7 deletions
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; |
