D Bare Bones: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content added Content deleted
(New page: {{Rating|1}}{{Template:Kernel Designs}} ''In this Tutorial we will write a kernel in the D language and boot it.'' <big><b>WAIT! Have you read Getting Started and [[Beginner Mistakes...)
 
No edit summary
Line 1: Line 1:
{{Rating|1}}{{Template:Kernel Designs}}
{{Rating|1}}{{Template:Kernel designs}}


''In this Tutorial we will write a kernel in the D language and boot it.''
''In this Tutorial we will write a kernel in the D language and boot it.''


<big><b>WAIT! Have you read [[Getting Started]] and [[Beginner Mistakes]]?</b></big>
<big><b>WAIT! Have you read [[Getting Started]], [[Beginner Mistakes]], and some of the related [[:Category:OS theory|OS theory]]?</b></big>


==Preface==
==Preface==
Line 9: Line 9:
The following tutorial assumes basic knowledge of a compiler, linker and assembler toolchain.
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.
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==

<pre>

global start
extern main ; Allow main() to be called from the assembly code

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

</pre>

Assemble that with:

<pre>
nasm -f elf -o start.o start.asm
</pre>

==kernel.main.d==
<pre>
module kernel.main;

extern(C) void main(uint magic, uint addr)
{
byte *videoram = cast( byte * ) 0xb8000; // Set up video memory
videoram[0] = 'D';
videoram[1] = 0x07;
}
</pre>

You then compile that with:

<pre>
gdc -nostdlib -nodefaultlibs -g -c -o kernel.main.o kernel.main.d
</pre>

==linker.ld==
<pre>
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)
__CTOR_LIST__ = .; LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) *(.ctors) LONG(0) __CTOR_END__ = .;
__DTOR_LIST__ = .; LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) *(.dtors) LONG(0) __DTOR_END__ = .;
}
}

.bss : {
sbss = .;
bss = .; _bss = .; __bss = .;
*(COMMON)
*(.bss)
ebss = .;
}
end = .; _end = .; __end = .;
}
</pre>

Now finally you can link all of that with:

<pre>
ld -T linker.ld -o kernel.bin start.o kernel.main.o
</pre>

Your kernel is now kernel.bin, and can now be booted by grub.

Hopefully this has gotten you started on writing your operating system in the D programming language.

Revision as of 18:20, 2 April 2009

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?

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

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)
{
        byte *videoram = cast( byte * ) 0xb8000; // Set up video memory
        videoram[0] = 'D';
        videoram[1] = 0x07;
}

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)
        __CTOR_LIST__ = .; LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) *(.ctors)   LONG(0) __CTOR_END__ = .;
        __DTOR_LIST__ = .; LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) *(.dtors) LONG(0) __DTOR_END__ = .;
    }
    }

    .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.

Hopefully this has gotten you started on writing your operating system in the D programming language.