我正在构建自己的操作系统,但是当我运行它时,我得到以下信息:启动失败:无法读取启动盘

问题描述 投票:0回答:1

enter image description here

当我运行我的操作系统时得到这个。

它说:启动失败:无法读取启动盘

但是在我的bootloader.asm中,我定义了这个来读取磁盘:

mov bx, 0x1000  ;Load the core
mov ah, 0x02    ;Bios func for read the disk

这是bootloarder.asm的代码:

; bootloader.asm
[org 0x7c00]            ; Le code commence à l'adresse 0x7C00 (adresse standard pour le bootloader)

start:
    cli                 ; Désactiver les interruptions
    mov ax, 0x07C0      ; Charger l'adresse du bootloader en mémoire
    add ax, 288         ; Ajuster le segment de pile
    mov ss, ax
    mov sp, 4096

    ; Afficher un caractère à l'écran (test)
    mov ah, 0x0E        ; Fonction BIOS pour afficher un caractère
    mov al, 'B'         ; Caractère à afficher
    int 0x10            ; Interruption vidéo BIOS

    ; Charger le noyau (1 secteur) à partir du disque
    mov bx, 0x1000      ; Charger le noyau à l'adresse 0x1000 en mémoire
    mov ah, 0x02        ; Fonction BIOS pour lire le disque
    mov al, 1           ; Lire 1 secteur
    mov ch, 0           ; Cylindre 0
    mov dh, 0           ; Tête 0
    mov cl, 2           ; Secteur 2 (le premier secteur est le bootloader)
    int 0x13            ; Interruption BIOS : lecture du disque

    jc disk_error       ; Si erreur (carry flag), sauter à la gestion d'erreur
    jmp 0x1000:0000     ; Sauter au noyau chargé en mémoire à l'adresse 0x1000

disk_error:
    ; Afficher un message d'erreur si le disque ne peut pas être lu
    mov ah, 0x0E
    mov al, 'E'
    int 0x10
    cli
    hlt

times 510 - ($-$$) db 0  ; Remplir jusqu'à 510 octets
dw 0xAA55                ; Signature du bootloader

这里是linker.ld

/* linker.ld */
ENTRY(kmain)

SECTIONS
{
    . = 0x1000;
    .text : {
        *(.text)
    }
    .data : {
        *(.data)
    }
    .bss : {
        *(.bss)
    }
}

这里是kernel.c

/* kernel.c */
#define VIDEO_MEMORY 0xb8000
#define SCREEN_WIDTH 80
#define SCREEN_HEIGHT 25
#define WHITE_ON_BLACK 0x07

int cursor_x = 35;  // Position du curseur dans le carré (horizontale)
int cursor_y = 12;  // Position du curseur dans le carré (verticale)

void clear_screen() {
    char *video_memory = (char *)VIDEO_MEMORY;
    for (int i = 0; i < SCREEN_WIDTH * SCREEN_HEIGHT * 2; i += 2) {
        video_memory[i] = ' ';
        video_memory[i + 1] = WHITE_ON_BLACK;
    }
}

void draw_square() {
    char *video_memory = (char *)VIDEO_MEMORY;

    // Dessiner un carré au centre de l'écran (10x5)
    for (int y = 10; y < 15; y++) {
        for (int x = 30; x < 50; x++) {
            int offset = (y * SCREEN_WIDTH + x) * 2;
            if (y == 10 || y == 14 || x == 30 || x == 49) {
                video_memory[offset] = '#';  // Bords du carré
            } else {
                video_memory[offset] = ' ';  // Intérieur du carré
            }
            video_memory[offset + 1] = WHITE_ON_BLACK;
        }
    }
}

void put_char(char c) {
    int offset = (cursor_y * SCREEN_WIDTH + cursor_x) * 2;
    char *video_memory = (char *)VIDEO_MEMORY;

    video_memory[offset] = c;
    video_memory[offset + 1] = WHITE_ON_BLACK;

    cursor_x++;
    if (cursor_x > 48) {
        cursor_x = 35;
        cursor_y++;
    }
}

void kmain() {
    clear_screen();
    draw_square();

    // Exemple d'écriture dans le carré
    put_char('H');
    put_char('e');
    put_char('l');
    put_char('l');
    put_char('o');
}

最后是markefile

# Définir les fichiers source
C_SOURCES = kernel.c
OBJECTS = $(C_SOURCES:.c=.o)

# Toutes les étapes : création de l'image OS et de l'image ISO
all: os-image myos.iso

# Combiner le bootloader et le noyau pour créer une image OS binaire
os-image: bootloader.bin kernel.bin
    cat bootloader.bin kernel.bin > os-image

# Assembler le bootloader (en binaire)
bootloader.bin: bootloader.asm
    nasm -f bin bootloader.asm -o bootloader.bin

# Compiler le noyau en fichier objet
kernel.o: kernel.c
    gcc -m32 -ffreestanding -c kernel.c -o kernel.o

# Lier le noyau (création de kernel.bin)
kernel.bin: kernel.o
    ld -m elf_i386 -T linker.ld -o kernel.bin kernel.o

# Créer l'image ISO bootable avec xorriso
.PHONY: myos.iso
myos.iso: os-image
    xorriso -as mkisofs -b os-image -no-emul-boot -boot-load-size 4 -boot-info-table -o myos.iso os-image


# Nettoyer les fichiers générés
clean:
    rm -f *.bin *.o os-image myos.iso

非常感谢大家的帮助!

我尝试用这个来阅读核心:

mov bx, 0x1000      ; Load the core
mov ah, 0x02        ; Read the disk with the BIOS
mov al, 1           ; Read sect 1
mov ch, 0           ; Cylinder 0
mov dh, 0           ; Head 0
mov cl, 2           ; Sect 2 (the first sect is the bootloader)
int 0x13            ; Interuption BIOS => for read the disk

但是还是不行

c assembly operating-system boot
1个回答
0
投票

可能是 xorriso -as mkisofs 选项 -boot-info-table 造成的。 它会导致 xorriso 覆盖启动映像中的字节 8 到 63。 较大的启动映像使用这些字节在光学上定位自己 启动介质并加载更多内容,而不仅仅是 4 个块 512 字节,他们相信任何 BIOS 都能够加载。

所以尝试 xorriso -as mkisofs 而不带选项 -boot-info-table。 最好也省略选项 -boot-load-size 4 ,直到您的引导映像变成 太大,无法被 BIOS 加载。 (那么你就必须学习 ISOLINUX 或 GRUB 为其编写和使用字节 8 至 63 中的 启动图像。)

© www.soinside.com 2019 - 2024. All rights reserved.