Page 1 of 2

Paging Fault During ATA Read/Write

Posted: Mon Jan 13, 2025 1:58 pm
by IlanVinograd
Hello, everyone,

I'm encountering a paging fault in my custom OS when attempting to perform ATA read and write operations in my

Code: Select all

updateDir 
function. I've identified that the issue occurs within the following block of code from my updateDir function:

Code: Select all

// Read the current directory entries from the disk
uint8_t dir_buffer[MAX_DIR * 16] = {0};

ata_identify(ATA_PRIMARY_IO, ATA_MASTER);
ata_read(ATA_PRIMARY_IO, ATA_MASTER, START_DIR, 1, dir_buffer);

// Copy the DirEntry struct into the directory buffer at the correct position
memcpy(&dir_buffer[pos * 16], &entry, sizeof(DirEntry));

// Write the updated directory entries back to the disk
ata_identify(ATA_PRIMARY_IO, ATA_MASTER);
ata_write(ATA_PRIMARY_IO, ATA_MASTER, START_DIR, MAX_DIR * 16 / 512, dir_buffer);
When this code runs, the CPU reports a paging fault with the following debug output:

Code: Select all

CR2=00000000
EIP=c01015d0
Full Context
Here's the full function where the problematic code resides:

Code: Select all

bool_t updateDir(char* filename) {
    DirEntry entry = {0};
    strncpy((char *)entry.name, filename, sizeof(entry.name) - 1);
    entry.size = 0;

    int pos = -1;

    // Find the first available directory slot
    for (int i = 0; i < MAX_DIR; i++) {
        if (dir[i] == 0) {
            dir[i] = 1;
            entry.fat_entry = i;
            pos = i;
            break;
        }
    }

    if (pos == -1) {
        printf("Error: No free directory entry found\n");
        return false;
    }

    uint8_t dir_buffer[MAX_DIR * 16] = {0};

    ata_identify(ATA_PRIMARY_IO, ATA_MASTER);
    ata_read(ATA_PRIMARY_IO, ATA_MASTER, START_DIR, 1, dir_buffer);

    memcpy(&dir_buffer[pos * 16], &entry, sizeof(DirEntry));

    ata_identify(ATA_PRIMARY_IO, ATA_MASTER);
    ata_write(ATA_PRIMARY_IO, ATA_MASTER, START_DIR, MAX_DIR * 16 / 512, dir_buffer);

    return true;
}
ata.c:

Code: Select all

#include "../Includes/ata.h"

void ata_initialize(uint16_t io_base, uint8_t drive) {
    outPort(io_base + 6, drive);
    outPort(io_base + 2, 0);
    outPort(io_base + 3, 0);
    outPort(io_base + 4, 0);
    outPort(io_base + 5, 0);
    outPort(io_base + 7, 0xEC);

    uint8_t status = inPort(io_base + 7);

    // Wait for BSY to clear
    while ((status & 0x80) != 0) {
        status = inPort(io_base + 7);
    }
}

static void ata_wait_bsy(uint16_t io_base) {
    while (inPort(io_base + 7) & 0x80); // Wait for BSY to clear
}

static void ata_wait_drq(uint16_t io_base) {
    while (!(inPort(io_base + 7) & 0x08)); // Wait for DRQ to set
}

void ata_read(uint16_t io_base, uint8_t drive, uint32_t lba, uint8_t sectors, uint8_t* buffer) {
    if (!buffer || sectors == 0) {
        return;
    }

    if (sectors > 256) {
        return;
    }

    // Select drive and LBA
    outPort(io_base + 6, 0xE0 | (drive << 4) | ((lba >> 24) & 0x0F));
    outPort(io_base + 2, sectors);
    outPort(io_base + 3, (uint8_t)(lba));
    outPort(io_base + 4, (uint8_t)(lba >> 8));
    outPort(io_base + 5, (uint8_t)(lba >> 16));
    outPort(io_base + 7, 0x20); // Read command

    for (uint8_t i = 0; i < sectors; i++) {
        ata_wait_bsy(io_base);
        if (inPort(io_base + 7) & 0x01) { // Check for error
            printf("ATA read error on sector %u.\n",RED_ON_BLACK_WARNING, lba + i);
            return;
        }

        ata_wait_drq(io_base);

        for (uint16_t j = 0; j < ATA_SECTOR_SIZE / 2; j++) {
            ((uint16_t*)buffer)[j] = inPort16(io_base);
        }
        buffer += ATA_SECTOR_SIZE;
    }
}

void ata_write(uint16_t io_base, uint8_t drive, uint32_t lba, uint8_t sectors, const uint8_t* buffer) {
    outPort(io_base + 6, 0xE0 | (drive << 4) | ((lba >> 24) & 0x0F));
    outPort(io_base + 2, sectors);
    outPort(io_base + 3, (uint8_t)(lba));
    outPort(io_base + 4, (uint8_t)(lba >> 8));
    outPort(io_base + 5, (uint8_t)(lba >> 16));
    outPort(io_base + 7, 0x30);

    for (uint8_t i = 0; i < sectors; i++) {
        ata_wait_bsy(io_base);
        ata_wait_drq(io_base);

        for (uint16_t j = 0; j < ATA_SECTOR_SIZE / 2; j++) {
            outPort16(io_base, ((uint16_t*)buffer)[j]);
        }
        buffer += ATA_SECTOR_SIZE;
    }

    ata_wait_bsy(io_base);
    outPort(io_base + 7, 0xE7);
    ata_wait_bsy(io_base);
}

void ata_identify(uint16_t io_base, uint8_t drive) {
    outPort(io_base + 6, drive);
    outPort(io_base + 2, 0);
    outPort(io_base + 3, 0);
    outPort(io_base + 4, 0);
    outPort(io_base + 5, 0);
    outPort(io_base + 7, 0xEC);

    ata_wait_bsy(io_base);

    uint8_t status = inPort(io_base + 7);
    if (status == 0) {
        printf("No ATA device detected.\n", COLOR_BLACK_ON_WHITE);
        return;
    }

    uint16_t buffer[256];
    for (uint16_t i = 0; i < 256; i++) {
        buffer[i] = inPort16(io_base);
    }
}
What I've Tried:

1. Verified that the dir_buffer array is allocated correctly.
2. Checked the ata_identify and ata_read/ata_write functions, and they seem to work in other contexts.
3. Confirmed that the START_DIR address is within the expected range.

Any help or suggestions would be greatly appreciated!

Thank you in advance.

https://github.com/IlanVinograd/OS_32Bi ... keyboard.c

Re: Paging Fault During ATA Read/Write

Posted: Mon Jan 13, 2025 3:06 pm
by Octocontrabass
IlanVinograd wrote: Mon Jan 13, 2025 1:58 pm

Code: Select all

CR2=00000000
EIP=c01015d0
What values are in the other registers? Which instruction does EIP point to?

Re: Paging Fault During ATA Read/Write

Posted: Mon Jan 13, 2025 3:22 pm
by IlanVinograd
Octocontrabass wrote: Mon Jan 13, 2025 3:06 pm
IlanVinograd wrote: Mon Jan 13, 2025 1:58 pm

Code: Select all

CR2=00000000
EIP=c01015d0
What values are in the other registers? Which instruction does EIP point to?

Code: Select all

QEMU 8.2.2 monitor - type 'help' for more information
(qemu) info registers

CPU#0
EAX=0000000e EBX=00000874 ECX=000003d5 EDX=000003d4
ESI=0000000e EDI=000003d4 EBP=c0106cfe ESP=c0404088
EIP=c01015c0 EFL=00000006 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0028 c01081c0 00000067 00408900 DPL=0 TSS32-avl
GDT=     c0108240 0000002f
IDT=     c0108280 000007ff
CR0=80000011 CR2=00000000 CR3=00110000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
EFER=0000000000000000
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=0000000000000000 0000000000000000 XMM01=0000000000000000 0000000000000000
XMM02=0000000000000000 0000000000000000 XMM03=0000000000000000 0000000000000000
XMM04=0000000000000000 0000000000000000 XMM05=0000000000000000 0000000000000000
XMM06=0000000000000000 0000000000000000 XMM07=0000000000000000 0000000000000000
(qemu) 
I'm not sure where the EIP points to exactly because it seems to change every time I encounter the issue. Here's the full register dump for reference:

Re: Paging Fault During ATA Read/Write

Posted: Mon Jan 13, 2025 3:40 pm
by Octocontrabass
IlanVinograd wrote: Mon Jan 13, 2025 3:22 pm

Code: Select all

(qemu) info registers
Huh? Why aren't you taking the register dump from your exception handler or from QEMU's interrupt log?
IlanVinograd wrote: Mon Jan 13, 2025 3:22 pmI'm not sure where the EIP points to exactly because it seems to change every time I encounter the issue.
Does it change every time you run your code, or only when you compile your code?

Re: Paging Fault During ATA Read/Write

Posted: Mon Jan 13, 2025 3:48 pm
by IlanVinograd
Octocontrabass wrote: Mon Jan 13, 2025 3:40 pm
IlanVinograd wrote: Mon Jan 13, 2025 3:22 pm

Code: Select all

(qemu) info registers
Huh? Why aren't you taking the register dump from your exception handler or from QEMU's interrupt log?
IlanVinograd wrote: Mon Jan 13, 2025 3:22 pmI'm not sure where the EIP points to exactly because it seems to change every time I encounter the issue.
Does it change every time you run your code, or only when you compile your code?
It works like this: I run the project, and then I type touch file.txt. Sometimes it works as expected, creating the file on the hard disk without issues. However, other times, it throws a page fault and crashes.

If there’s no page fault, everything behaves as expected—the file is created and placed on the hard disk correctly. The behavior seems random, like: works, works, works, doesn't work, doesn't work, works. I haven’t found a consistent pattern to the failures yet.

Let me know if this helps clarify the issue or if I should provide more information!

Re: Paging Fault During ATA Read/Write

Posted: Mon Jan 13, 2025 3:52 pm
by Octocontrabass
The register dump from QEMU's interrupt log ("-d int") and a disassembly of the code around the instruction that causes the fault would be very helpful.

Re: Paging Fault During ATA Read/Write

Posted: Mon Jan 13, 2025 4:51 pm
by IlanVinograd
Octocontrabass wrote: Mon Jan 13, 2025 3:52 pm The register dump from QEMU's interrupt log ("-d int") and a disassembly of the code around the instruction that causes the fault would be very helpful.
https://github.com/IlanVinograd/OS_32Bi ... t/qemu.log

here -d int

Re: Paging Fault During ATA Read/Write

Posted: Mon Jan 13, 2025 5:16 pm
by Octocontrabass
Why is there more than one exception? You should halt the CPU when you can't recover from an exception.

This log shows the CPU attempting to execute code outside your kernel. You have a memory corruption bug somewhere.

How big is your stack? How big are the local variables you're allocating on the stack?

Re: Paging Fault During ATA Read/Write

Posted: Mon Jan 13, 2025 5:35 pm
by IlanVinograd
Octocontrabass wrote: Mon Jan 13, 2025 5:16 pm
Why is there more than one exception? You should halt the CPU when you can't recover from an exception.

This log shows the CPU attempting to execute code outside your kernel. You have a memory corruption bug somewhere.

How big is your stack? How big are the local variables you're allocating on the stack?
The stack is 8 KB for the kernel stack

Re: Paging Fault During ATA Read/Write

Posted: Mon Jan 13, 2025 5:35 pm
by IlanVinograd
IlanVinograd wrote: Mon Jan 13, 2025 5:35 pm
Octocontrabass wrote: Mon Jan 13, 2025 5:16 pm
Why is there more than one exception? You should halt the CPU when you can't recover from an exception.

This log shows the CPU attempting to execute code outside your kernel. You have a memory corruption bug somewhere.

How big is your stack? How big are the local variables you're allocating on the stack?
The stack is 8 KB for the kernel stack
what is mean memorty corruption bug and how to resolve it>?

Re: Paging Fault During ATA Read/Write

Posted: Mon Jan 13, 2025 6:02 pm
by Octocontrabass
IlanVinograd wrote: Mon Jan 13, 2025 5:35 pmThe stack is 8 KB for the kernel stack
Are you sure?
IlanVinograd wrote: Mon Jan 13, 2025 5:35 pmwhat is mean memorty corruption bug and how to resolve it>?
A memory corruption bug is a bug where memory gets corrupted. You fix it the same way you fix any bug.

Re: Paging Fault During ATA Read/Write

Posted: Mon Jan 13, 2025 6:04 pm
by IlanVinograd
Octocontrabass wrote: Mon Jan 13, 2025 5:16 pm
Why is there more than one exception? You should halt the CPU when you can't recover from an exception.

This log shows the CPU attempting to execute code outside your kernel. You have a memory corruption bug somewhere.

How big is your stack? How big are the local variables you're allocating on the stack?

Code: Select all


(gdb) info registers
eax            0x9      9
ecx            0x71     113
edx            0x70     112
ebx            0xc04061ec       -1069522452
esp            0xc04061b0       0xc04061b0
ebp            0x0      0x0
esi            0x0      0
edi            0x0      0
eip            0xc01015c9       0xc01015c9 <outPort+9>
eflags         0x292    [ AF SF IF ]
cs             0x8      8
ss             0x10     16
ds             0x10     16
es             0x10     16
fs             0x10     16
gs             0x10     16
fs_base        0x0      0
gs_base        0x0      0
k_gs_base      0x0      0
cr0            0x80000011       [ PE ET PG ]
cr2            0x0      0
cr3            0x110000 [ #16 #20 ]
cr4            0x0      [ ]
cr8            0x0      0
efer           0x0      [ ]
xmm0           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>},
  v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0},
  uint128 = 0x00000000000000000000000000000000}
xmm1           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>},
  v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0},
  uint128 = 0x00000000000000000000000000000000}
xmm2           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>},
  v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0},
  uint128 = 0x00000000000000000000000000000000}
xmm3           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>},
  v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0},
  uint128 = 0x00000000000000000000000000000000}
xmm4           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>},
  v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0},
  uint128 = 0x00000000000000000000000000000000}
xmm5           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>},
  v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0},
  uint128 = 0x00000000000000000000000000000000}
xmm6           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>},
  v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0},
  uint128 = 0x00000000000000000000000000000000}
xmm7           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>},
  v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0},
  uint128 = 0x00000000000000000000000000000000}
mxcsr          0x1f80   [ IM DM ZM OM UM PM ]
(gdb) disassemble 0xc01015c9
Dump of assembler code for function outPort:
   0xc01015c0 <+0>:     mov    0x4(%esp),%edx
   0xc01015c4 <+4>:     mov    0x8(%esp),%eax
   0xc01015c8 <+8>:     out    %al,(%dx)
=> 0xc01015c9 <+9>:     ret
End of assembler dump.
(gdb)

(gdb) x/4wx $esp
0xc04061b0:     0x07e91501      0x000003d5      0x00000000      0x00000000

(gdb) x/4wx $esp
0xc0405130:     0xc0106d10      0x00000104      0x00010000      0x00010000
(gdb)


(gdb) x/x 0x00010000
0x10000:        Cannot access memory at address 0x10000
(gdb) disassemble 0xc0106d10, 0xc0106d20
Dump of assembler code from 0xc0106d10 to 0xc0106d20:
   0xc0106d10:  inc    %ebp
   0xc0106d11:  jb     0xc0106d85
   0xc0106d13:  outsl  %ds:(%esi),(%dx)
   0xc0106d14:  jb     0xc0106d36
   0xc0106d16:  inc    %ebx
   0xc0106d17:  outsl  %ds:(%esi),(%dx)
   0xc0106d18:  fs cmp %fs:%gs:(%eax),%ah
   0xc0106d1c:  xor    %bh,0x25(%eax)
   0xc0106d1f:  jo     0xc0106d2b
End of assembler dump.
(gdb)

What do you think could probably be the issue? Could it be the port?

Re: Paging Fault During ATA Read/Write

Posted: Mon Jan 13, 2025 6:19 pm
by Octocontrabass
IlanVinograd wrote: Mon Jan 13, 2025 6:04 pmWhat do you think could probably be the issue?
I think the stack is 4kiB and your local variables are bigger than 4kiB.
IlanVinograd wrote: Mon Jan 13, 2025 6:04 pmCould it be the port?
Which port?

Re: Paging Fault During ATA Read/Write

Posted: Mon Jan 13, 2025 6:33 pm
by IlanVinograd
Octocontrabass wrote: Mon Jan 13, 2025 6:19 pm
IlanVinograd wrote: Mon Jan 13, 2025 6:04 pmWhat do you think could probably be the issue?
I think the stack is 4kiB and your local variables are bigger than 4kiB.
IlanVinograd wrote: Mon Jan 13, 2025 6:04 pmCould it be the port?
Which port?
Its could be because of this?

Code: Select all

uint8_t dir_buffer[MAX_DIR * 16] = {0};
.h file:

Code: Select all

#define OFFSET_BEGIN 0x10000
#define SECTOR_SIZE 512
#define START_FS (OFFSET_BEGIN / SECTOR_SIZE) // Here the file system start, it's like offset.
#define START_DIR ((OFFSET_BEGIN + 0x00200) / SECTOR_SIZE) // Here the file system start, it's like offset.
#define MAX_SECTORS 8192
#define MAX_DIR 256

Code: Select all

#include "../Includes/file_system.h"

SuperBlock SB;
bool_t dir[MAX_DIR - 1] =  {false};

void init_fs() {
    uint8_t buffer[SECTOR_SIZE] = {0};
    uint8_t dir_buffer[MAX_DIR * 16] = {0};

    // Read the SuperBlock from disk at the filesystem start
    ata_identify(ATA_PRIMARY_IO, ATA_MASTER);
    ata_read(ATA_PRIMARY_IO, ATA_MASTER, START_FS, 1, buffer);
    memcpy(&SB, buffer, sizeof(SuperBlock));

    // Read the Dir Entries from disk at the filesystem start
    ata_read(ATA_PRIMARY_IO, ATA_MASTER, START_DIR, MAX_DIR * 16 / 512, dir_buffer);
    
    for(int i = 0; i < MAX_DIR; i++) { // each dir is 16 byte
        dir[i] = (dir_buffer[i * 16] == 0 || dir_buffer[i * 16] == '?') ? 0 : 1; // read this byte if ? or 0 means dir free other wise is not.
    }

    printf("Filesystem initialized with the following parameters:\n",RED_ON_BLACK_WARNING);
    printf("Total sectors: %d\n",RED_ON_BLACK_WARNING, SB.total_sectors);
    printf("Sectors per cluster: %d\n",RED_ON_BLACK_WARNING,  SB.sectors_per_cluster);
    printf("Bytes per sector: %d\n",RED_ON_BLACK_WARNING, SB.bytes_per_sector);
    printf("Available sectors: %d\n",RED_ON_BLACK_WARNING, SB.available_sectors);
    printf("Filesystem label: %s\n", RED_ON_BLACK_WARNING, (const char *)SB.label);

    printf("Dir Status: ", RED_ON_BLACK_WARNING);
    for(int i = 0; i < MAX_DIR; i++){
        printf("%x", RED_ON_BLACK_WARNING, dir[i]);
    }
}

void create_file(char* filename) {
    if (strlen(filename) > 10) {
        printf("Error: Filename too long. Maximum length is 10 characters.\n",RED_ON_BLACK_WARNING);
        return;
    }

    if(!updateSB()) {
        printf("Error: updateSB.\n", RED_ON_BLACK_WARNING);
        return;
    }

    if(!updateDir(filename)) {
        printf("Error: updateDir.\n", RED_ON_BLACK_WARNING);
        return;
    }
}

bool_t updateSB() {
    uint32_t sectors = 1;
    if(!isAvaDir()) {
        printf("No Available Dir", YELLOW_ON_BLACK_CAUTION);
        return false;
    }

    if(!isAvaSec(sectors)) {
        printf("No Available Sec", YELLOW_ON_BLACK_CAUTION);
        return false;
    }
    updateDirAndSec(sectors);
    return true;
}

bool_t updateDir(char* filename) {
    DirEntry entry = {0}; // Zero-initialize the struct
    strncpy((char *)entry.name, filename, sizeof(entry.name) - 1);
    entry.name[sizeof(entry.name) - 1] = '\0';
    entry.size = 0;

    int pos = -1;

    // Find the first available directory slot
    for (int i = 0; i < MAX_DIR; i++) {
        if (dir[i] == 0) { // Check if the directory slot is free
            dir[i] = 1;    // Mark it as used
            entry.fat_entry = i; // Set the FAT entry to the index
            pos = i;       // Record the position
            break;
        }
    }

    if (pos == -1) {
        printf("Error: No free directory entry found\n", YELLOW_ON_BLACK_CAUTION);
        return false;
    }

    // Read the current directory entries from the disk
    
    uint8_t dir_buffer[MAX_DIR * 16] = {0};
    
    ata_identify(ATA_PRIMARY_IO, ATA_MASTER);
    ata_read(ATA_PRIMARY_IO, ATA_MASTER, START_DIR, MAX_DIR * 16 / 512, dir_buffer);
    
    // Copy the DirEntry struct into the directory buffer at the correct position
    memcpy(&dir_buffer[pos * 16], &entry, sizeof(DirEntry));

    // Write the updated directory entries back to the disk
    ata_identify(ATA_PRIMARY_IO, ATA_MASTER);
    ata_write(ATA_PRIMARY_IO, ATA_MASTER, START_DIR, MAX_DIR * 16 / 512, dir_buffer);

    return true;
}

bool_t isAvaDir() {
    return SB.available_direntries > 0;
}

bool_t isAvaSec(uint32_t sectors) {
    return SB.available_sectors >= sectors;
}

void updateDirAndSec(uint32_t sectors) {
    SB.available_direntries--;
    SB.available_sectors -= sectors * SB.sectors_per_cluster;

    uint8_t buffer[SECTOR_SIZE] = {0};
    memcpy(buffer, &SB, sizeof(SuperBlock));
    
    ata_identify(ATA_PRIMARY_IO, ATA_MASTER);
    ata_write(ATA_PRIMARY_IO, ATA_MASTER, START_FS, 1, buffer);
}
16*256 = 4096

Re: Paging Fault During ATA Read/Write

Posted: Mon Jan 13, 2025 6:37 pm
by Octocontrabass
Yeah, that's probably causing your stack to overflow.