thank you
It is what I need, but I can't get it working. I'm doing something wrong in my paging tables. The error lies between the 2 "load CR3 with PML4".
I don't understand exactly what you are doing between line 60 and line 93. Can you give me some explications, please?
To make it simple I have also pasted the MBR code with loads and jumps to this part.
Code: Select all
INITSEG = 0x07e0
INITOFF = 0x0000
.section .rodata
gdt:
# Null Descriptor
.word 0x0000, 0x0000
.byte 0x00, 0b00000000, 0b00000000, 0x00
# Code Descriptor
.word 0xffff, 0x0000
.byte 0x00, 0b10011010, 0b11001111, 0x00
# Data Descriptor
.word 0xffff, 0x0000
.byte 0x00, 0b10010010, 0b11001111, 0x00
gdt_end:
gdt32ptr:
.word (gdt_end - gdt - 1)
.long (gdt + INITSEG * 0x10 + INITOFF)
gdt64ptr:
.word (gdt_end - gdt - 1)
.quad (gdt + INITSEG * 0x10 + INITOFF)
.section .text
.globl Start
Start:
.code16
# Load Global Descriptor Table
lgdt gdt32ptr
# Load Control Register CR0
# Enable Protected Mode (Bit0 in CR0)
# Store Control Register CR0
movl %cr0, %eax
orl $(1<<0), %eax
movl %eax, %cr0
# Setup all Segment Registers
# and reload Code Segment, Instruction Pointer
movw $0x0010, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
ljmp $0x0008, $(JumpToPM + INITSEG * 0x10 + INITOFF)
JumpToPM:
.code32
#----------------- load CR3 with PML4 -----------------------------------------------
# Clear the first 0xE000 bytes following 0x1000000.
movl $0x01000000, %edi
movl %edi, %cr3
clrl %eax
movl $0x0000e000, %ecx
rep stosl
movl %cr3, %edi
# Set the initial page tables.
# Note that we OR with 0x7 here to allow user-space access, except in the
# first 2 MiB. We also do this with 0x200 to allow forking the page.
# Page-Map Level 4
movl $0x01002000, (%edi)
addl $0x00001000, %edi
# Page-Directory Pointer Table
movl $0x01004000, (%edi)
addl $0x00001000, %edi
# Page-Directory (no user-space access here)
movl $0x01006000, (%edi) # (First 2 MiB)
movl $0x01008000, 8(%edi) # (Second 2 MiB)
addl $0x1000, %edi
# Page-Table
# Memory map the first 4 MiB.
clrl %ebx
movl $1024, %ecx
SetEntry:
mov %ebx, (%edi)
add $0x1000, %ebx
add $8, %edi
loop SetEntry
#----------------- load CR3 with PML4 -----------------------------------------------
# Load Control Register CR4
# Enable Physical Address Extension (Bit5 in CR4)
# Store Control Register CR4
movl %cr4, %eax
orl $(1<<5), %eax
movl %eax, %cr4
# Use Model Specific Register 0xC0000080
# Read from Model Specific Register
# Enable Long Mode (Bit8)
# Write to Model Specific Register
movl $0xc0000080, %ecx
rdmsr
orl $(1<<8), %eax
wrmsr
#-------------------- stop before error -----------------------------------------------
hlt
#-------------------- stop before error -----------------------------------------------
# Load Control Register CR0
# Enable Paging (Bit31 in CR0)
# Store Control Register CR0
movl %cr0, %eax
orl $(1<<31), %eax
movl %eax, %cr0
.code64
# Reload Global Descriptor Table
lgdt gdt64ptr
# Enter into the kernel
call kmain
Hang:
# Halt the CPU
# Infinit loop if Halt doesn't work
hlt
jmp Hang
Code: Select all
BOOTSEG = 0x07c0
INITSEG = 0x07e0
INITOFF = 0x0000
.section .rodata
msg:
.asciz "loading system..."
msgend:
msglen:
.word (msgend - msg)
errmsg:
.asciz "boot error!"
errmsgend:
errmsglen:
.word (errmsgend - errmsg)
lba:
# LBA packet size, always 0
.byte 0x10, 0x00
# sectors to read, always 0
.byte 0xff, 0x00
# load address
.long (INITSEG * 0x10 + INITOFF)
# start read from 2nd sector
.long 0x00000001
.section .text
.globl Start
Start:
.code16
# Disable Interrupts during setup
cli
# Setup all Segment Registers
# and reload Code Segment, Instruction Pointer
movw $BOOTSEG, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
ljmp $BOOTSEG, $ReloadCSIP
ReloadCSIP:
# Setup Stack
# Save Boot Device to Stack
movw $0x0200, %sp
movw %sp, %bp
pushw %dx
# Enable Interrupts temporarily
sti
# Set Video Mode AH=0x00
# 80x25 Mode AL=0x03
# Video Interrupt INT=0x10
clrb %ah
movb $0x03, %al
int $0x10
# Clear Screen AH=0x06
# Lines to scroll (0 is entire window) AL=0x00
# Color attributes (0F is Black and White) BH=0x0F
# Upper Left Corner CH=00/CL=00
# Lower Right Corner DH=25/DL=80
# Video Interrupt INT=0x10
movb $0x06, %ah
clrb %al
movb $0x0f, %bh
clrw %cx
movb $25, %dh
movb $80, %dl
int $0x10
# String to print ES:BP
# Print String AH=0x13
# Char only - Cursor moved AL=0x01
# Page Number BH=0x00
# Color attributes (0F is Black and White) BL=0x0F
# Message Length CX
# Row DH=0
# Column DL=0
# Video Interrupt INT=0x10
movw $BOOTSEG, %ax
movw %ax, %es
movw $msg, %bp
movb $0x13, %ah
movb $0x01, %al
clrb %bh
movb $0x0f, %bl
movw msglen, %cx
movb $0, %dh
movb $0, %dl
int $0x10
# Enable A20 Gate AX=0x2401
# System Interrupt INT=0x15
movw $0x2401, %ax
int $0x15
jc Error
# Reset Disk AH=0x00
# Drive Number DL=(from stack)
# Disk Interrupt INT=0x13
clrb %ah
popw %dx
int $0x13
jc Error
# Extension Test AH=0x41
# BX=0x55AA
# Drive Number DL=(from stack)
# Disk Interrupt INT=0x13
movb $0x41, %ah
movw $0x55aa, %bx
int $0x13
jc Error
# LBA Packet DS:SI
# Extended Read AH=0x42
# Drive Number DL=(from stack)
movw $lba, %si
movb $0x42, %ah
int $0x13
jc Error
# Disable Interrupts before jumping to 2nd stage bootloader
cli
# Setup all Segment Registers
# and jump to 2nd stage bootloader
movw $INITSEG, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
ljmp $INITSEG, $INITOFF
Error:
# String to print ES:BP
# Print String AH=0x13
# Char only - Cursor moved AL=0x01
# Page Number BH=0x00
# Color attributes (0F is Black and Red) BL=0x04
# Message Length CX
# Row DH=1
# Column DL=0
# Video Interrupt INT=0x10
movw $BOOTSEG, %ax
movw %ax, %es
movw $errmsg, %bp
movb $0x13, %ah
movb $0x01, %al
clrb %bh
movb $0x04, %bl
movw errmsglen, %cx
movb $1, %dh
movb $0, %dl
int $0x10
# Disable Interrupts before Halt
cli
Hang:
# Halt the CPU
# Infinit loop if Halt doesn't work
hlt
jmp Hang