3

Problem

I am programming a basic kernel in C with a little bit of assembly. I want to change the video mode to 0x13, but when I call int 0x10, QEMU gets stuck in a booting from ROM loop where it appears to repeatedly execute the kernel.


Files

kernel.asm

bits 32
global start
extern _kmain

section .text

        align 4
        dd 0x1BADB002
        dd 0x00
        dd -(0x1BADB002 + 0x00)

start:
        mov ah, 0x00
        mov al, 0x13
        int 0x10
        call _kmain
        hlt

kernel.c

void print(int x, int y, int colour, char* text) {
    char* video = (char*)0xb8000;
    unsigned int a = 0;
    unsigned int b = 0;

    a = ((y - 1) * 160) + ((x - 1) * 2);

    while (text[b] != '\0') {
        video[a] = text[b];
        video[a + 1] = colour;
        ++b;
        a = a + 2;
    }

    return;
}

void clear(int colour) {
    char* video = (char*)0xb8000;
    for (int a = 0; a < 4000; a = a + 2) {
        video[a] = ' ';
        video[a + 1] = colour;
    }

    return;
}

void kmain() {
    clear(0xff);
    print(1, 1, 0xf0, "Some text...");

    return;
}

link.ld

OUTPUT_FORMAT(pei-i386)
ENTRY(start)

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

I compile and run the kernel using the following commands:

nasm -f elf32 kernel.asm -o ka.o
gcc -m32 -c kernel.c -o kc.o -ffreestanding -nostdlib -nostdinc
ld -T link.ld -o kernel ka.o kc.o
objcopy -O elf32-i386 kernel kernel.elf

qemu-system-i386 -kernel kernel.elf

Screenshots

With C kmain function call and int 0x10 interrupt

QEMU booting from ROM loop

With only C kmain function call

QEMU with only the C kmain function

With only int 0x10 interrupt

With only the int 0x10 interrupt

Daemon Beast
  • 2,794
  • 3
  • 12
  • 29
  • Are you sure that restarting is because of `int 0x10` and not because of your `main` function? – Tsyvarev Jan 11 '20 at 23:51
  • If I removed the call to the C `kmain` function, it would still loop. – Daemon Beast Jan 12 '20 at 09:03
  • Instead of just `hlt` you should use something like `haltloop:` \ `hlt` \ `jmp haltloop`. Not sure whether that fixes your issue though. – ecm Feb 10 '20 at 20:48
  • 1
    Another problem is that you do not set up an IDT, nor do you drop into Real or Virtual 86 Mode to run your interrupt 10h call, as you would need to use the video BIOS service. – ecm Feb 10 '20 at 20:54

0 Answers0