User:Imate900/32-bit assembler bare bones

From OSDev.wiki
Revision as of 00:22, 21 April 2009 by osdev>Troy martin (32-bit assembler bare bones moved to User:Imate900/32-bit assembler bare bones: No sense in teaching noobs something completely incorrect. For one, your GDT and GDTR are completely borked. Moved to your user namespace.)
Jump to navigation Jump to search
Difficulty level

Medium
Kernel Designs
Models
Other Concepts

This tutorial will teach you how to make a 32-bit assembler kernel.

GRUB

All we need is something like this (GNU as):

.global loader # making entry point visible to linker

# setting up the Multiboot header - see GRUB docs for details
.set ALIGN, 1<<0 # align loaded modules on page boundaries
.set MEMINFO, 1<<1 # provide memory map
.set FLAGS, ALIGN | MEMINFO # this is the Multiboot 'flag' field
.set MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header
.set CHECKSUM, -(MAGIC + FLAGS) # checksum required

.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM

_start:
# Write the kernel here
jmp _start

Link with:

as -o kernel.o kernel.s
ld --oformat binary -o kernel.bin kernel.o

For NASM:

global loader ; making entry point visible to linker

; setting up the Multiboot header - see GRUB docs for details
ALIGN equ 1<<0 ; align loaded modules on page boundaries
MEMINFO equ 1<<1 ; provide memory map
FLAGS equ ALIGN | MEMINFO ; this is the Multiboot 'flag' field
MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header
CHECKSUM equ -(MAGIC + FLAGS) ; checksum required

mboot:
dd MAGIC
dd FLAGS
dd CHECKSUM

_start:
; Write the kernel here
jmp _start

Link with:

nasm -f bin kernel.asm

Make sure you have a GRUB entry...

title Assembler Barebones
kernel (hd0,0)/boot/kernel.bin

Now, reboot, and enjoy!

Without GRUB

Starting In Protected Mode

If your bootloader loads flat binary images and gives you protected mode for you, use this code as a basis:

_start:
 ; Write kernel here. It might be good to load a new GDT. I include the GDT business here nevertheless.
 lgdt [kern_gdtr]
 jmp 0x08:normalize_regs
normalize_regs:
 mov ax, 0x10 ; 0x10 points at the new data selector
 mov ds, ax
 mov es, ax
 mov fs, ax
 mov gs, ax
 mov ss, ax
 jmp kernel

kernel:
 ; After all that tricky business! Write your kernel here, anyway.
 jmp kernel

kern_gdt:
 db 0, 0, 0 ; null entry
 db 0, 0xffffffff, 0x9A
 db 0, 0xffffffff, 0x92

kern_gdtr DW 0 ; For limit storage
          DD 0 ; For base storage

Starting In Real Mode

Usually (in most FAT bootloaders), you must first switch to Protected Mode in order to write a 32-bit kernel if your kernel starts in Real Mode. For reference, this code is enough (GDT is composed of null entry, a code entry and a data entry:)

BITS 16
cli
lgdt [kern_gdtr]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp 0x08:normalize_regs
BITS 32
normalize_regs:
 mov ax, 0x10 ; 0x10 points at the new data selector
 mov ds, ax
 mov es, ax
 mov fs, ax
 mov gs, ax
 mov ss, ax
 jmp kernel

kernel:
 ; After all that tricky business! Write your kernel here, anyway.
 jmp kernel

kern_gdt:
 db 0, 0, 0 ; null entry
 db 0, 0xffffffff, 0x9A
 db 0, 0xffffffff, 0x92

kern_gdtr DW 0 ; For limit storage
          DD 0 ; For base storage