D Bare Bones
From OSDev Wiki
| Difficulty level |
|---|
Beginner |
| Kernel Designs |
|---|
| Models |
| Other Concepts |
In this Tutorial we will write a kernel in the D language and boot it.
WAIT! Have you read Getting Started, Beginner Mistakes, and some of the related OS theory?
Contents |
Preface
The following tutorial assumes basic knowledge of a compiler, linker and assembler toolchain. It also of course assumes prior knowledge of the D programming language.
Overview
In this tutorial we will create a simple D kernel that prints 'D' on to the screen. The basic setup will consist of three files:
- start.asm
- kernel.main.d
- linker.ld
start.asm
global start extern main ; Allow main() to be called from the assembly code extern start_ctors, end_ctors, start_dtors, end_dtors MODULEALIGN equ 1<<0 MEMINFO equ 1<<1 FLAGS equ MODULEALIGN | MEMINFO MAGIC equ 0x1BADB002 CHECKSUM equ -(MAGIC + FLAGS) section .text ; Next is the Grub Multiboot Header align 4 MultiBootHeader: dd MAGIC dd FLAGS dd CHECKSUM STACKSIZE equ 0x4000 ; 16k if you're wondering static_ctors_loop: mov ebx, start_ctors jmp .test .body: call [ebx] add ebx,4 .test: cmp ebx, end_ctors jb .body start: mov esp, STACKSIZE+stack push eax push ebx call main static_dtors_loop: mov ebx, start_dtors jmp .test .body: call [ebx] add ebx,4 .test: cmp ebx, end_dtors jb .body cpuhalt: hlt jmp cpuhalt section .bss align 32 stack: resb STACKSIZE
Assemble that with:
nasm -f elf -o start.o start.asm
kernel.main.d
module kernel.main; extern(C) void main(uint magic, uint addr) { int ypos = 0; //Starting points of the cursor int xpos = 0; const uint COLUMNS = 80; //Screensize const uint LINES = 24; ubyte* vidmem = cast(ubyte*)0xFFFF8000000B8000; //Video memory address for (int i = 0; i < COLUMNS * LINES * 2; i++) { //Loops through the screen and clears it volatile *(vidmem + i) = 0; } volatile *(vidmem + (xpos + ypos * COLUMNS) * 2) = 'D' & 0xFF; //Prints the letter D volatile *(vidmem + (xpos + ypos * COLUMNS) * 2 + 1) = 0x07; //Sets the colour for D to be light grey (0x07) for (;;) { //Loop forever. You can add your kernel logic here } }
You then compile that with:
gdc -nostdlib -nodefaultlibs -g -c -o kernel.main.o kernel.main.d
linker.ld
OUTPUT_FORMAT(elf32-i386)
ENTRY (start)
SECTIONS{
. = 0x00100000;
.text :{
code = .; _code = .; __code = .;
*(.text)
*(.rodata)
}
.rodata ALIGN (0x1000) : {
*(.rodata)
}
.data ALIGN (0x1000) : {
data = .; _data = .; __data = .;
*(.data)
start_ctors = .; *(.ctors) end_ctors = .;
start_dtors = .; *(.dtors) end_dtors = .;
}
.bss : {
sbss = .;
bss = .; _bss = .; __bss = .;
*(COMMON)
*(.bss)
ebss = .;
}
end = .; _end = .; __end = .;
}
Now finally you can link all of that with:
ld -T linker.ld -o kernel.bin start.o kernel.main.o
Your kernel is now kernel.bin, and can now be booted by grub.
Keep in mind that to add other classes, functions, enums, etc. You must add the D runtime.
Hopefully this has gotten you started on writing your operating system in the D programming language.
