- Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathata.c
More file actions
Latest commit
72 lines (61 loc) · 2.32 KB
/
Copy pathata.c
File metadata and controls
72 lines (61 loc) · 2.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include"types.h"
#defineATA_PRIMARY_DATA 0x1F0
#defineATA_PRIMARY_ERR 0x1F1
#defineATA_PRIMARY_SECCOUNT 0x1F2
#defineATA_PRIMARY_LBA_LO 0x1F3
#defineATA_PRIMARY_LBA_MID 0x1F4
#defineATA_PRIMARY_LBA_HI 0x1F5
#defineATA_PRIMARY_DRIVE_HEAD 0x1F6
#defineATA_PRIMARY_COMM_REGSTAT 0x1F7
staticinlineuint8_tinb(uint16_tport) {
uint8_tret;
__asm__ __volatile__ ("inb %1, %0" : "=a"(ret) : "Nd"(port));
returnret;
}
staticinlinevoidoutb(uint16_tport, uint8_tval) {
__asm__ __volatile__ ("outb %0, %1" : : "a"(val), "Nd"(port));
}
staticinlineuint16_tinw(uint16_tport) {
uint16_tret;
__asm__ __volatile__ ("inw %1, %0" : "=a"(ret) : "Nd"(port));
returnret;
}
staticinlinevoidoutw(uint16_tport, uint16_tval) {
__asm__ __volatile__ ("outw %0, %1" : : "a"(val), "Nd"(port));
}
/**
* @brief Reads a 512-byte sector from disk into memory buffer
* @param lba Logical Block Address (Sector number on disk)
* @param buffer Output memory array (at least 512 bytes)
*/
voidata_read_sector(uint32_tlba, uint8_t*buffer) {
outb(ATA_PRIMARY_DRIVE_HEAD, 0xE0 | ((lba >> 24) &0x0F));
outb(ATA_PRIMARY_SECCOUNT, 1);
outb(ATA_PRIMARY_LBA_LO, (uint8_t)lba);
outb(ATA_PRIMARY_LBA_MID, (uint8_t)(lba >> 8));
outb(ATA_PRIMARY_LBA_HI, (uint8_t)(lba >> 16));
outb(ATA_PRIMARY_COMM_REGSTAT, 0x20); // 0x20 = Read Sectors Command
// Wait until disk controller is ready (DRQ bit set, BUSY bit clear)
while ((inb(ATA_PRIMARY_COMM_REGSTAT) &0x88) !=0x08);
// Read 256 16-bit words (512 bytes total)
uint16_t*ptr= (uint16_t*)buffer;
for (inti=0; i<256; i++) {
ptr[i] =inw(ATA_PRIMARY_DATA);
}
}
/**
* @brief Writes a 512-byte sector from memory buffer to disk
*/
voidata_write_sector(uint32_tlba, uint8_t*buffer) {
outb(ATA_PRIMARY_DRIVE_HEAD, 0xE0 | ((lba >> 24) &0x0F));
outb(ATA_PRIMARY_SECCOUNT, 1);
outb(ATA_PRIMARY_LBA_LO, (uint8_t)lba);
outb(ATA_PRIMARY_LBA_MID, (uint8_t)(lba >> 8));
outb(ATA_PRIMARY_LBA_HI, (uint8_t)(lba >> 16));
outb(ATA_PRIMARY_COMM_REGSTAT, 0x30); // 0x30 = Write Sectors Command
while ((inb(ATA_PRIMARY_COMM_REGSTAT) &0x88) !=0x08);
uint16_t*ptr= (uint16_t*)buffer;
for (inti=0; i<256; i++) {
outw(ATA_PRIMARY_DATA, ptr[i]);
}
}