aboutsummaryrefslogtreecommitdiff
path: root/mubios
diff options
context:
space:
mode:
Diffstat (limited to 'mubios')
-rw-r--r--mubios/core/post.c2
-rw-r--r--mubios/drivers/ata.c24
-rw-r--r--mubios/include/bios.h2
-rw-r--r--mubios/services/int13.c9
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;