I'm developing a small OS that works in protected mode, but executes entirely below 1mb. For acquire this purpose, I've wrote my own bootloader that loads for now, a small kernel of test that print a 'a' on screen.
The main problem is that when I emulate the "OS Project.img" with Virtual box the character 'a' is not printed on screen and nothing happens!
Can anyone give a hand with this?
I'm developing this OS in a Ubuntu system without a floppy drive, using nasm, a i586-elf-gcc compiler and dd command.
bootloader.asm
Code: Select all
;=====================================NASM HEADERS========================================
%define KSEG 0x0800 ; kernel segment
%define KOFF 0x0000 ; kernel offset
%define KSEC 2 ; kernel sector
%define GDT_LOCATION 0x00007E00
%define GDT_SIZE 0x0100
;=========================================================================================
use16
org 0x7C00
jmp 0x0000:start
start:
sti ; enable bios interrupts
; read kernel to memory
mov ah, 0x02 ; interrupt subfunction: read disk
mov dl, 0 ; drive ( 00h = A: )
mov dh, 0 ; head
mov ch, 0 ; cylinder
mov cl, KSEC ; sector
mov al, 9 ; number of sectors to be read
mov bx, KSEG ; es:bx points to memory buffer's location
mov es, bx
mov bx, KOFF ; 0x0800:0x0000
int 13h ; disk interrupt
use32
cli ; disable BIOS interrupt
; initializates GDT
mov ax, GDT_SIZE
mov word[cs:gdtr], ax ; load GDT size
mov eax, GDT_LOCATION
mov dword[cs:gdtr + 2], eax ; load GDT offset
lgdt [gdtr] ; load GDT register
; Load GDT entries
mov ebx, dword[cs:gdtr + 2]
mov edx, gdt
mov ecx, 6
fillgdt:
mov eax, [cs:edx]
mov [cs:ebx], eax
add ebx, 4
add edx, 4
loop fillgdt
; enter protected mode
mov eax, cr0
or al, 1
mov cr0, eax
; Load Kernel Code and Data Descriptors
mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
jmp 0x08:0x0000 ; now kernel have control of system
;======================================VARIABLES==========================================
gdtr dw 0x0000 ; GDT size
dd 0x00000000 ; GDT location
gdt dw 0x0000, 0x0000, 0x0000, 0x0000 ; GDT entry null
dw 0x004F, 0x9A00, 0x8000, 0xFFFF ; GDT entry kernel code
dw 0x004F, 0x9200, 0x0500, 0xFFFF ; GDT entry kernel data
;====================================NASM DIRECTIVES======================================
; fill the end of sector with signature's boot
times 510-($-$$) db 0
db 0x55
db 0xAA
Code: Select all
void kmain ()
{
unsigned char *videoram = (unsigned char *) 0xb8000;
videoram[0] = 65; /* character 'A' */
videoram[1] = 0x07; /* forground, background color. */
for (;;);
}
Code: Select all
ENTRY (kmain)
SECTIONS
{
. = 0x00008000;
.text : { *(.text) }
. = 0x00000500;
.data : { *(.data) }
.bss : { *(.bss) }
}
Code: Select all
#!/bin/sh
PATH=/usr/local/cross/bin:$PATH
#clean
cd ..
cd Compiled
rm -f "bootloader.bin" "kernel.bin" "kernel.o"
cd ..
cd Image
rm -f "OS Project.img"
cd ..
#make
nasm "Source/boot/bootloader.asm" -f bin -o "Compiled/bootloader.bin"
i586-elf-gcc -o "Compiled/kernel.o" -c "Source/kernel/kernel.c"
i586-elf-ld -T "Source/kernel/kernel_linker.ld" -o "Compiled/kernel.bin" "Compiled/kernel.o"
dd if="Compiled/bootloader.bin" of="Image/OS Project.img" bs=512 count=1 seek=0
dd if="Compiled/kernel.bin" of="Image/OS Project.img" bs=512 count=9 seek=1
dd if="/dev/zero" of="Image/OS Project.img" bs=512 count=2870 seek=10