64 bit Kernel Setup Code - init.asm


This source code is part of the BCOS project at http://bcos.hopto.org.

Copyright © Brendan Trotter 2005

This material is provided by Brendan Trotter as a service to interested parties on an "as-is" basis, for informational purposes only. Brendan Trotter assumes no responsibility for any errors and omissions. Brendan Trotter does not make, and expressly disclaims any, representations or warranties, express or implied, regarding this web page and the host web site, including, without limitation, any implied warranties of merchantability or fitness for a particular purpose.

Under no circumstances shall Brendan Trotter, or any associated contributors, volunteers or representatives be liable for any damages, whether direct, indirect, special or consequential damages for lost revenues, lost profits, or otherwise, arising from or in connection with this web page, the host web site, or the materials contained herein.

All materials contained on this web page are protected by copyright laws, and may not be reproduced, republished, distributed, transmitted, displayed, broadcast or otherwise exploited in any manner without the express prior written permission of Brendan Trotter. You may make one copy of this web page for your personal and non-commercial use only, without altering or removing this copyright notice or any other notice.




Initialization Code


Entry Point

;Input
; esi	Address of module list
; ebp	Number of AP CPUs present

        MARK

START:


Setup Segment Registers and The Stack

According to the "Boot Loader Specification"), the boot loader leaves most of the CPUs registers in an undefined state, and therefore it's a good idea to set them to a defined state.

        clr ax
        mov ss,ax
        mov esp,STACK_TOP
        mov ds,ax
        mov es,ax
        mov fs,ax


Initialize The BSS Section

This code just fills the BSS section with zeros.

        mov ecx,(BSS_END - BSS_START) / 4               ;ecx = size of BSS in dwords
        mov edi,BSS_START
        clr eax
        cld
        rep stosd


Find Total Amount Of Address Space To Identity Map

        CALL_BOOT_API 0x6C                              ;Get address of byte after highest used page
        test eax,eax                                    ;Was there an error?
        jne .getMemTopFailed                            ; yes
        mov [identityMapTop],ebx


Allocate Page For Temporary PML4

        CALL_BOOT_API 0x68                              ;Allocate a page for the PML4
        test eax,eax                                    ;Was there an error?
        jne .getPageFailed                              ; yes
        mov edx,ebx                                     ;edx = physical address of PML4


Allocate Page For Temporary Page Directory Pointer Table

        CALL_BOOT_API 0x68                              ;Allocate a page for the PML4
        test eax,eax                                    ;Was there an error?
        jne .getPageFailed                              ; yes

        mov ecx,ebx                                     ;ecx = physical address of PDPT
        or bl,00000111b                                 ;Set present, read/write and user flags
        mov [gs:edx],ebx                                ;Put PDPT into PML4


Allocate Page For Temporary Page Directory

        CALL_BOOT_API 0x68                              ;Allocate a page for the page directory
        test eax,eax                                    ;Was there an error?
        jne .getPageFailed                              ; yes

        mov ebp,ebx                                     ;ebp = physical address of page directory
        or bl,00000111b                                 ;Set present, read/write and user flags
        mov [gs:ecx],ebx                                ;Put page directory into PDPT


Allocate Temporary Page Tables And Fill Them

        mov ecx,[identityMapTop]                        ;ecx = number of bytes to identity map
        clr esi                                         ;esi = starting address for identity mapping
        shr ecx,12                                      ;ecx = number of pages to identity map

.nextPageTable:
        CALL_BOOT_API 0x68                              ;Allocate a page for the page table
        test eax,eax                                    ;Was there an error?
        jne .getPageFailed                              ; yes

        mov edi,ebx                                     ;edi = physical address of page table
        or bl,00000111b                                 ;Set present, read/write and user flags
        mov [gs:ebp],ebx                                ;Put page table into page directory
        add ebp,8                                       ;Increase next address in page directory

        lea eax,[esi+00000111b]                         ;eax = first page table entry with present, read/write and user flags
.nextPage:
        mov [gs:edi],eax                                ;Put next page into page table
        add eax,0x00001000                              ;eax = next page table entry
        add esi,0x00001000                              ;esi = next address to identity map
        add edi,8                                       ;edi = physical address for next page table entry
        sub ecx,1                                       ;ecx = number of pages left to identity map
        je .doneMapping                                 ;Done if no pages left to identity map
        test edi,0xFFFFF000                             ;Has this page table been filled?
        je .nextPageTable                               ; yes, get another page table
        jmp .nextPage                                   ; no, identity map another page

.doneMapping:


Enable Long Mode

        mov eax,10100000b                               ;eax = PAE and PGE flags set
        mov cr4,eax                                     ;Enable PAE and PGE

        mov cr3,edx                                     ;Set address of PML4

        mov ecx,0xC0000080                              ;ecx = MSR for EFER
        rdmsr                                           ;Enable long mode in the EFER MSR
        or eax,0x00000100
        wrmsr                                           ;Enable long mode in the EFER MSR

        mov ebx,cr0                                     ;ebx = cr0
        or ebx,0x80000001                               ;eax = cr0 with paging and protection enabled
        mov cr0,ebx                                     ;Enable long mode

        lgdt [GDT]

        jmp 0x18:.startLongMode                         ;Load CS with 64 bit segment and flush the instruction cache


Make Some Stripes In Long Mode

        BITS 64

.startLongMode:

        mov edi,0xA0000
        mov ecx,480/2
        mov rax,0x5501550155015501
        mov rbx,0xAA80AA80AA80AA80
.l1:
        mov [edi],rax
        mov [edi+0x08],rax
        mov [edi+0x10],rax
        mov [edi+0x18],rax
        mov [edi+0x20],rax
        mov [edi+0x28],rax
        mov [edi+0x30],rax
        mov [edi+0x38],rax
        mov [edi+0x40],rax
        mov [edi+0x48],rax
        mov [edi+0x50],rbx
        mov [edi+0x58],rbx
        mov [edi+0x60],rbx
        mov [edi+0x68],rbx
        mov [edi+0x70],rbx
        mov [edi+0x78],rbx
        mov [edi+0x80],rbx
        mov [edi+0x88],rbx
        mov [edi+0x90],rbx
        mov [edi+0x98],rbx
        add edi,0x000000A0
        sub ecx,1
        jne .l1

        jmp $

        BITS 16


Error Handling

.getMemTopFailed:
.getPageFailed:
        mov eax,0xDEADBEEF
        jmp $                                           ;Lock up (no video access)



Generated on Mon Nov 14 03:59:31 2005.