Как мне в самостоятельном ядре записать файл на диск?

Я пишу ядро на Си и NASM. Требуется реализовать простую файловую систему. Код загрузчика:

bits 32
section .text
        ;multiboot spec
        align 4
        dd 0x1BADB002              ;magic
        dd 0x00                    ;flags
        dd - (0x1BADB002 + 0x00)   ;checksum. m+f+c should be zero

global start
global keyboard_handler
global read_port
global write_port
global load_idt

extern kmain        ;this is defined in the c file
extern keyboard_handler_main

read_port:
    mov edx, [esp + 4]
            ;al is the lower 8 bits of eax
    in al, dx   ;dx is the lower 16 bits of edx
    ret

write_port:
    mov   edx, [esp + 4]    
    mov   al, [esp + 4 + 4]  
    out   dx, al  
    ret

load_idt:
    mov edx, [esp + 4]
    lidt [edx]
    sti                 
    ret

keyboard_handler:                 
    call    keyboard_handler_main
    iretd
    

start:
    cli                 
    mov esp, stack_space
    call kmain
    hlt                 

section .bss
resb 8192; 8KB for stack
stack_space:

А вот код самой системы:

#include "keyboard_map.h"
#include "types.h"
#include <string.h>
#include <stdint.h>
#include <math.h>
#include <stdarg.h>

extern unsigned char keyboard_map[128];
extern void keyboard_handler(void);
extern char read_port(unsigned short port);
extern void write_port(unsigned short port, unsigned char data);
extern void load_idt(unsigned long *idt_ptr);

unsigned int current_loc = 0;
char *vidptr = (char*)0xb8000;
unsigned int lines = 0; // Переменная для отслеживания количества строк
unsigned char current_color = 0x07; // Устанавливаем начальный цвет текста

struct IDT_entry {
    unsigned short int offset_lowerbits;
    unsigned short int selector;
    unsigned char zero;
    unsigned char type_attr;
    unsigned short int offset_higherbits;
};

struct IDT_entry IDT[IDT_SIZE];

int atoi(const char *str) {
    int result = 0;
    int sign = 1;

    while (*str == ' ') str++;

    if (*str == '-' || *str == '+') {
        if (*str == '-') sign = -1;
        str++;
    }

    while (*str >= '0' && *str <= '9') {
        int digit = *str - '0';
        if (result > (INT_MAX - digit) / 10) {
            return (sign == 1) ? INT_MAX : INT_MIN;
        }
        result = result * 10 + digit;
        str++;
    }

    return sign * result;
}

void print(const char *str) {
    unsigned int i = 0;
    while (str[i] != '\0') {
        if (str[i] == '\n') {
            current_loc += 80 - (current_loc % 80);
            lines++; // Увеличиваем количество строк
        } else {
            vidptr[current_loc * 2] = str[i];
            vidptr[current_loc * 2 + 1] = 0x07;
            current_loc++;
        }

        if (current_loc >= 80 * 25) {
            current_loc = 0;
        }
        i++;
    }

    // Проверяем количество строк
    if (lines >= LINES) {
        clear_screen(); // Очищаем экран, если строк больше 0
        lines = 0; // Сбрасываем счетчик строк
    }
}

void printn(int num) {
    char buffer[32]; 
    int i = 0, isNegative = 0;

    if (num < 0) {
        isNegative = 1;
        num = -num;
    }

    do {
        buffer[i++] = (num % 10) + '0';
        num /= 10;
    } while (num > 0);

    if (isNegative) {
        buffer[i++] = '-';
    }

    // Обратный порядок
    for (int j = i - 1; j >= 0; j--) {
        vidptr[current_loc * 2] = buffer[j];
        vidptr[current_loc * 2 + 1] = 0x07;
        current_loc++;

        if (current_loc >= 80 * 25) {
            current_loc = 0;
        }
    }
    
    // Проверяем количество строк
    if (lines >= LINES) {
        clear_screen(); // Очищаем экран, если строк больше 0
        lines = 0; // Сбрасываем счетчик строк
    }
}

void kprint_newline(void) {
    current_loc += (80 - (current_loc % 80));
    lines++; // Увеличиваем количество строк
}

void clear_screen(void) {
    unsigned int i = 0;
    while (i < SCREENSIZE) {
        vidptr[i++] = ' ';
        vidptr[i++] = 0x07;
    }
    current_loc = 0;
    lines = 0; // Сбрасываем количество строк
}

void keyboard_handler_main(void) {
    unsigned char status;
    char keycode;

    write_port(0x20, 0x20);
    status = read_port(KEYBOARD_STATUS_PORT);

    if (status & 0x01) {
        keycode = read_port(KEYBOARD_DATA_PORT);
        if (keycode < 0) return;
        if (keycode == ENTER_KEY_CODE) {
            kprint_newline();
            return;
        }
        if (keycode == BACKSPACE_KEY_CODE) {
            if (current_loc > 0) {
                current_loc--;
                vidptr[current_loc * 2] = ' ';
                vidptr[current_loc * 2 + 1] = 0x07;
            }
            return;
        }
        if (keycode < 128) {
            char c = keyboard_map[keycode];
            if (c != 0) {
                vidptr[current_loc * 2] = c;
                vidptr[current_loc * 2 + 1] = 0x07;
                current_loc++;
            }
        }
    }
}

void input(char *buffer, int max_size) {
    unsigned int index = 0;
    while (index < max_size - 1) {
        unsigned char status = read_port(KEYBOARD_STATUS_PORT);
        if (status & 0x01) {
            unsigned char keycode = read_port(KEYBOARD_DATA_PORT);
            if (keycode == ENTER_KEY_CODE) {
                break;
            }
            if (keycode < 128) {
                char c = keyboard_map[keycode];
                if (c != 0) {
                    if (c == '\b') {
                        if (index > 0) {
                            index--;
                            vidptr[current_loc * 2 - 2] = ' ';
                            vidptr[current_loc * 2 - 1] = 0x07;
                            current_loc--;
                        }
                    } else {
                        buffer[index++] = c;
                        vidptr[current_loc * 2] = c;
                        vidptr[current_loc * 2 + 1] = 0x07;
                        current_loc++;
                    }
                }
            }
        }
    }
    buffer[index] = '\0';
    kprint_newline();
}

int inputn() {
    char buffer[MAX_INPUT_SIZE];
    input(buffer, MAX_INPUT_SIZE);
    return atoi(buffer);
}

void idt_init(void) {
    unsigned long keyboard_address;
    unsigned long idt_address;
    unsigned long idt_ptr[2];

    keyboard_address = (unsigned long)keyboard_handler;
    IDT[0x21].offset_lowerbits = keyboard_address & 0xffff;
    IDT[0x21].selector = KERNEL_CODE_SEGMENT_OFFSET;
    IDT[0x21].zero = 0;
    IDT[0x21].type_attr = INTERRUPT_GATE;
    IDT[0x21].offset_higherbits = (keyboard_address & 0xffff0000) >> 16;

    write_port(0x20, 0x11);
    write_port(0xA0, 0x11);
    write_port(0x21, 0x20);
    write_port(0xA1, 0x28);
    write_port(0x21, 0x00);
    write_port(0xA1, 0x00);
    write_port(0x21, 0x01);
    write_port(0xA1, 0x01);

    write_port(0x21, 0xff);
    write_port(0xA1, 0xff);

    idt_address = (unsigned long)IDT;
    idt_ptr[0] = (sizeof(struct IDT_entry) * IDT_SIZE) + ((idt_address & 0xffff) << 16);
    idt_ptr[1] = idt_address >> 16;
    load_idt(idt_ptr);
}

void kb_init(void) {
    write_port(0x21, 0xFD);
}

void decimal_to_binary(int n) {
    if (n == 0) {
        print("0");
        return;
    }
    char binary[32];
    int index = 0;
    while (n > 0) {
        binary[index++] = (n % 2) + '0';
        n /= 2;
    }
    for (int i = index - 1; i >= 0; i--) {
        vidptr[current_loc * 2] = binary[i];
        vidptr[current_loc * 2 + 1] = 0x07;
        current_loc++;
    }
}

int strcmp(const char *s1, const char *s2) {
    while (*s1 && (*s1 == *s2)) {
        s1++;
        s2++;
    }
    return *(unsigned char *)s1 - *(unsigned char *)s2;
}

// Рандом
unsigned int rand() {
    static unsigned int seed = 12345; // Начальное значение
    seed = (seed * 1103515245 + 12345) & 0x7fffffff;
    return seed % 3; // Получаем число от 0 до 2
}

// Задержка
void delay(unsigned int count) {
    for (volatile unsigned int i = 0; i < count; i++);
}

// Задать цвет текста в консоли
void color(unsigned char text_color) {
    if (text_color > 15) {
        return; 
    }

    current_color = text_color; // Устанавливаем цвет текста
}

void bgcolor(unsigned char bg_color) {
    // Проверяем, что цвет фона находится в допустимых пределах (0-15)
    if (bg_color > 15) {
        return; 
    }

    // Обновляем цвет фона для всех символов на экране
    for (unsigned int i = 0; i < SCREENSIZE; i += 2) {
        // Устанавливаем фон в старший ниббл
        vidptr[i + 1] = (vidptr[i + 1] & 0x0F) | (bg_color << 4); 
    }
}
void kmain(void) {
    clear_screen();
    print("PRoX kernel v 1.0 \n");
    print("OS booted!\n");
    kprint_newline();
}

В types.h определены некоторые переменные


Ответы (0 шт):