User:Imate900/32-bit assembler bare bones: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
Content deleted Content added
m Bot: Replace deprecated source tag with syntaxhighlight
 
(13 intermediate revisions by 6 users not shown)
Line 1: Line 1:
{{Rating|2}}{{Template:Kernel designs}}
<!--{{Rating|2}}{{Template:Kernel designs}}-->


''This tutorial will teach you how to make a 32-bit assembler kernel.''
''This tutorial will teach you how to make a 32-bit Assembly kernel.''
== Preface ==
Most OSes are in C, but you may consider it in Assembly. This is moderate-easy, and requires knowing GRUB and Assembly.


== GRUB ==
== GRUB ==
All we need is something like this (GNU as):
All we need is something like this (Nasm):
<syntaxhighlight lang="asm">
<pre>
%define MBOOT_MAGIC 0x1badb002
.global loader # making entry point visible to linker
%define MBOOT_FLAGS 0x00010002


bits 32
# setting up the Multiboot header - see GRUB docs for details
org 0x100000
.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
align 4, db 0
header:
.long MAGIC
dd MBOOT_MAGIC
.long FLAGS
dd MBOOT_FLAGS
.long CHECKSUM
dd 0 - MBOOT_MAGIC - MBOOT_FLAGS
dd header
dd __entry_point
dd end_of_file
dd end_of_file
dd __entry_point
align 0, db 0
__entry_point:
mov edi, 0xB8000
mov esi, string
mov ah, 0x0F
.displaying:
lodsb
stosw
or al, al
jnz .displaying
jmp short $
string: db "Hello world!", 0


align 4, db 0
_start:
end_of_file:
# Write the kernel here
</syntaxhighlight>
jmp _start
</pre>


Link with:
Link with:
<syntaxhighlight lang="bash">
as -o kernel.o kernel.s
ld --oformat binary -o kernel.bin kernel.o
nasm -f bin kernel.asm
</syntaxhighlight>


Make sure you have a GRUB entry...
For NASM:
<pre>
<pre>
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

</pre>

Link with:
nasm -f bin kernel.asm

Make sure you have a GRUB entry...
title Assembler Barebones
title Assembler Barebones
kernel (hd0,0)/boot/kernel.bin
kernel (hd0,0)/boot/kernel.bin
</pre>


Now, reboot, and enjoy!
Now, reboot, and enjoy!


== Without GRUB ==
== 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:
If your bootloader loads flat binary images and gives you protected mode for you, use this code as a basis:
<syntaxhighlight lang="asm">
<pre>
_start:
_start:
; Write kernel here. It might be good to load a new GDT.
; Write kernel here. It might be good to load a new GDT.
mov edi, 0xB8000
jmp _start
mov esi, string
</pre>
mov ah, 0x0F
.displaying:
lodsb
stosw
or al, al
jnz .displaying
jmp short $


string: db "Hello world!", 0
=== Starting In Real Mode ===
</syntaxhighlight>
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:
If you start out in real mode, remember to switch to [[Protected Mode]].
<pre>
BITS 16
cli
; Load GDT. Make sure to make one because the GDT was borked :(
lgdt [gdtr]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp 0x08:kernel
BITS 32


== Postface ==
kernel:
Good luck writing your 32-bit Assembly kernel! '''But''', there ''ARE'' catch-yas!
; reset ds, es, fs, gs here
*As soon as possible, load a new GDT.
mov ax,
*You must not depend on the BIOS to do everything for you. Most prominent are disk access, printing to the screen (this tutorial has a way to printing: writing to 0xb8000) and reading keys from the keyboard. No BIOS ints will help and only cause a GPF.

gdt:
; Don't remove the next line
db 0, 0, 0
; Make a GDT here

gdtr:
; dunno if OK, correct if needed...
db 0
db 0
</pre>

Latest revision as of 06:16, 9 June 2024


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

Preface

Most OSes are in C, but you may consider it in Assembly. This is moderate-easy, and requires knowing GRUB and Assembly.

GRUB

All we need is something like this (Nasm):

%define MBOOT_MAGIC 0x1badb002
%define MBOOT_FLAGS 0x00010002

bits 32
org 0x100000

align 4, db 0
header:
   dd MBOOT_MAGIC
   dd MBOOT_FLAGS
   dd 0 - MBOOT_MAGIC - MBOOT_FLAGS
   dd header
   dd __entry_point
   dd end_of_file
   dd end_of_file
   dd __entry_point
align 0, db 0
__entry_point:
   mov edi, 0xB8000
   mov esi, string
   mov ah, 0x0F
   .displaying:
   lodsb
   stosw
   or al, al
   jnz .displaying
   jmp short $
string: db "Hello world!", 0

align 4, db 0
end_of_file:

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

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.
   mov edi, 0xB8000
   mov esi, string
   mov ah, 0x0F
   .displaying:
   lodsb
   stosw
   or al, al
   jnz .displaying
   jmp short $

string: db "Hello world!", 0

If you start out in real mode, remember to switch to Protected Mode.

Postface

Good luck writing your 32-bit Assembly kernel! But, there ARE catch-yas!

  • As soon as possible, load a new GDT.
  • You must not depend on the BIOS to do everything for you. Most prominent are disk access, printing to the screen (this tutorial has a way to printing: writing to 0xb8000) and reading keys from the keyboard. No BIOS ints will help and only cause a GPF.