sixty nine
sixty nine

Reputation: 17

Guru meditation in vbox while using custom bootloader and kernel

I made this simple bootloader in asm and kernel in C. Below are the code

boot.asm

[org 0x7C00]                ; Set the origin to 0x7C00 (default for bootloader)

; --- Initial Setup ---
mov bp, 0x9000              ; Set up the base pointer for the stack
mov sp, bp                  ; Set the stack pointer to the base pointer

cli                         ; Clear interrupts to avoid unexpected IRQs during setup

; --- Set up the Global Descriptor Table (GDT) ---
lgdt [gdt_descriptor]       ; Load the GDT descriptor

; --- Enter Protected Mode ---
mov eax, cr0                ; Load CR0 register
or eax, 0x1                 ; Set the PE bit in CR0 to enable Protected Mode
mov cr0, eax                ; Write it back to CR0

jmp 0x08:init_pm            ; Jump to protected mode code, using the code selector (0x08)

[bits 32]                   ; Start using 32-bit mode

; --- Protected Mode Initialization ---
init_pm:
    ; Set up segment registers
    mov ax, 0x10            ; 0x10 is the selector for the code segment in the GDT
    mov ds, ax              ; Set DS to the code segment
    mov es, ax              ; Set ES to the code segment
    mov fs, ax              ; Set FS to the code segment
    mov gs, ax              ; Set GS to the code segment
    mov ss, ax              ; Set SS to the code segment (this is where stack starts)

    ; Set up the stack in protected mode
    mov esp, 0x9000         ; Set up the stack pointer to a safe location in protected mode

    ; --- Load Kernel from Disk ---
    ; Assuming the kernel is located at sector 2 and its size is less than 1MB.
    mov eax, 0x10000         ; Destination address to load the kernel (0x10000)
    mov cx, 1               ; Number of sectors to read (1 sector at a time)
    mov bx, 0x00            ; Drive 0 (floppy or hard disk)
    mov dl, 0x80            ; The first hard disk (if booting from hard disk)

load_kernel:
    ; BIOS interrupt to read a sector from the disk
    ; AH = 0x02 (read sectors), AL = number of sectors (1), CH = track (0), CL = sector (2), DH = head, DL = drive
    mov ah, 0x02            ; BIOS read sectors function
    mov al, 1               ; Read 1 sector
    mov ch, 0               ; Track 0
    mov cl, 2               ; Read sector 2
    mov dh, 0               ; Head 0
    mov dl, 0x80            ; Drive 0x80 (hard disk)
    int 0x13                ; Call BIOS interrupt

    jc disk_error           ; Jump to disk error if carry flag is set (error)

    ; Kernel loaded successfully, copy to the specified address
    ; The data is already at memory location 0x7E00, now copy it to 0x10000
    mov si, 0x7E00          ; Source address of the kernel data (after read)
    mov di, 0x10000         ; Destination address to load the kernel
    mov cx, 512             ; Number of bytes (1 sector = 512 bytes)
    rep movsb               ; Copy 512 bytes from source to destination

    ; --- Jump to the Kernel Entry Point ---
    jmp 0x08:0x10000        ; Jump to the kernel's entry point

disk_error:
    ; Handle disk read error (e.g., infinite loop to indicate failure)
    hlt                      ; Halt the system

[bits 16]                   ; Return to 16-bit mode for the GDT definition

; --- Global Descriptor Table (GDT) ---
GDT:
    ; Null descriptor
    dd 0x0
    dd 0x0

    ; Code descriptor (32-bit)
    dw 0xffff               ; Limit
    dw 0x0                  ; Base (low 16 bits)
    db 0x0                  ; Base (next 8 bits)
    db 0b10011010           ; Type and flags (code, executable, read/write, etc.)
    db 0b11001111           ; Limit (high 4 bits, flags)
    db 0x0                  ; Base (high 8 bits)

    ; Data descriptor (32-bit)
    dw 0xffff               ; Limit
    dw 0x0                  ; Base (low 16 bits)
    db 0x0                  ; Base (next 8 bits)
    db 0b10010010           ; Type and flags (data, read/write, etc.)
    db 0b11001111           ; Limit (high 4 bits, flags)
    db 0x0                  ; Base (high 8 bits)

; --- GDT Descriptor ---
gdt_descriptor:
    dw $ - GDT - 1           ; Size of the GDT (16-bit)
    dd GDT                   ; Address of the GDT

; --- Bootloader Padding ---
times 510 - ($ - $$) db 0   ; Fill the boot sector with zeroes
dw 0xAA55                  ; Boot signature

kernel.c

void _start() {
    // Basic initialization or a test message
    char *str = "Hello from the kernel!";
    unsigned short *video = (unsigned short*)0xB8000;
    
    // Print the string at the start of the video memory
    while (*str) {
        *video = *str | 0x0F00;  // White text on black background
        str++;
        video++;
    }
    while (1);  // Halt execution
}

Could like someone help me, and give me the reason why its causing this? My assumption is the VGA memory write is causing this. Everytime i try to run, my vbox goes into guru meditation, its very frustrating, Please help me. My log is attached here.

Upvotes: 0

Views: 64

Answers (0)

Related Questions