unexpected memory corruption in baremetal environment [SOLVED]

94 Views Asked by At

i have a simple 32 bit kernel which gets loaded succesfully by a bootloader shown below

[org 0x7c00]
; we can also alter the data segment register (ds) accordingly:
; mov ds, 0x7c0 (it will be 0x7c00 because address bus is 20-bit)

KERNEL_LOCATION equ 0x1000
BOOT_DISK equ 0

; setting up the stack and tiny memory model
xor ax, ax
mov es, ax
mov ds, ax
mov bp, 0x8000
mov sp, bp


; loading the kernel in memory location 0x1000
call read_disk

; ; Set up VESA graphics mode (example: mode 0x101 - 640x480, 16 colors)
; mov ax, 0x4F02     ; VESA function to set video mode
; mov bx, 0x101      ; Mode number for desired resolution/color depth
; int 0x10           ; Call BIOS interrupt to set the video mode

; initialize protected mode
init_pm:

    ; clear the screen using bios before disabling it
    mov ax, 0x0003 
    int 10h

    ; clear interrupts
    mov bx,suc
    ;call print_string
    
    ; some delay just for looking cool :)
    ;call delay
    ;mov ax, 0x0003
    ;int 10h
 
    cli
    ; this instruction loads the gdt location and size into the gdtr (gdt register) in the cpu
    lgdt [GDT_descriptor]

    ; changing the first bit of cr0 register (0th control register) which corresponds to [ Protected Mode Enable ]
    mov eax, cr0
    or eax, 1
    mov cr0, eax

    ; far jump!!
    jmp CODE_SEG:start_protected_mode

%include "gdt.asm"
%include "read_disk.asm"
;%include "print_string.asm"
%include "delay.asm"

; this tells the assembeler (in this case nasm) to compile the
; code to 32 bit machine code now on
[bits 32]
start_protected_mode:

    ; changing stack and memory segments model
    mov eax, DATA_SEG
    mov ds, eax
    mov ss, eax
    mov es, eax
    mov fs, eax
    mov gs, eax

    mov ebp, 0x90000        ; 32 bit stack base pointer
    mov esp, ebp

    jmp KERNEL_LOCATION

suc:
    db "entering 32-bit mode...",0
jmp $



times 510-($-$$) db 0
dw 0xaa55

my problem is that my kernel .text section will overwrite other parts of my kernel therefore leading to random behaviors

here is the kernel code written in c:

#include "std/stdout.h"
#include "terminal/terminal.h"



void func1(){
        for (int i = 0; i < 33; i++)
    {
        /* code */
    }
}
void func2(){
        for (int i = 0; i < 33; i++)
    {
        /* code */
    }
}
void func3(){
        for (int i = 0; i < 33; i++)
    {
        /* code */
    }
}
void func4(){
    for (int i = 0; i < 33; i++)
    {
        /* code */
    }
    
}


void kernel_start(){
    prepare_terminal();
    background_color = 32;
}

NOTE: somehow only having 3 of those funcs doesnt cause the problem so i suspect adding one more is exceeding some kind of limit

i tried changing the linker script to add alignments as i suspected its due to the limited size of each section but it didnt helped or maybe i did it wrong

here is my current linker script:

ENTRY(_start)

SECTIONS {
    . = 0x1000;

    .text : {
        *(.text)
    }
    
    .data : {
        *(.data)
    }

    .bss : {
        *(.bss)
    }
}

broken code: normal

normal: broken code

1

There are 1 best solutions below

0
alireza On

So, it turned out my problem was because I was only reading 10 sectors from the disk, which caused the program to stop halfway and create some unexpected issues.

What I did was increase the number of sectors to be read:

read_disk:

    ; bios read functions
    mov ah, 0x02

    ; number of sectors to be read
    ; mov al, 10                    <========! HERE
    mov al, 40    

    ; chs addressing
    mov ch, 0x00 ; cylender
    mov dh, 0x00 ; head
    mov cl, 0x02 ; sector (reading the first sector after the boot sector sectors start at 1)


    ; setting the bx to the address we want to load our read disk
    mov bx, KERNEL_LOCATION

    mov dl, BOOT_DISK

    int 0x13  
    ; jump to error handler if c flag is one
    ; jc disk_error

    ; returning to the caller address
    ret

; error handler
disk_error:
    mov bx, error_msg
    ;call print_string
    jmp $

error_msg:
    ; null terminating string :)
    db "error reading disk",0

and it solved my problem :)