also hier der minimalistische bootloader
%include "config32.asm"
[BITS 16]
org 0x7c00
init:
xor ax, ax
mov ds, ax
mov es, ax
mov ax, 0100h
mov ss, ax
mov ax, stack
mov sp, ax ; relative adressing to stack segment
mov [bootdrv], dl
call load ; load kernel
;; jump to kernel
mov ax, KERNEL_ADR
push ax
xor ax, ax
push ax
retf
;; kernel-loading routine
load:
push ds
mov ax, 0 ; reset function
mov dl, [bootdrv] ; what drive?
int 13h ; interrupt
pop ds
jc load
.loop0:
mov ax, KERNEL_ADR
mov es, ax ; buffer address for reading
xor bx, bx ; offset = 0
;; read in sectors
mov ah, 2 ; read function
mov al, 1 ; 1 sectors
mov cx, 2 ; cylinder = 0, sector = 2
xor dx, dx ; head = 0, drive = 0
int 13h ; es:bx = 0x1000 (internal multiplication with 16)
jc .loop0
ret
bootdrv db 0
;; little realmode stack
resd 64
stack:
times 510-($-$$) db 0
dw 0aa55h
;; size = 512B
und hier der relevante teil vom kernel
%include "config32.asm"
[BITS 16]
start:
;; setup stack
xor ax, ax
mov ds, ax
mov es, ax
mov ds, ax
mov esp, stack
;; set gdt
cli
lgdt [gdt_desc]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp dword gdt_code:pmode ; far jump reloads the cs register and flushes
; the real-mode instructions from the prefetch queue
[BITS 32]
pmode:
;; all register except of cs still contain 16bit values
;; -> put valid selectors into ds, ss and es
;; setup stack
mov ax, gdt_data
mov ds, ax
mov ss, ax
mov es, ax
mov esp, stack
lidt [idt_desc] ; load idt
;; ...
jmp $
;; ---------------------------
;; interrupt service routines
;; ---------------------------
void_isr
mov eax, FRAME_BUFFER
mov dword [eax], ':-( '
jmp $
isr_test:
mov eax, FRAME_BUFFER
mov dword [eax], ':-) '
iret
msg db "test message ..."
;; kernel stack
resd 1024
stack:
;; ------------------------
;; global descriptor table
;; ------------------------
;; 8B/descriptor, 8192 descriptors maximum -> 64KB max size
gdt:
dd 0
dd 0
gdt_code equ $-gdt
dw 0ffffh ; limit 0:15
dw 0 ; base 0:15
db 0 ; base 16:23
db 10011010b ; present, ring 0 priv(2bit), code segment, executable, non-conforming, readable
db 11001111b ; page-granular, 32-bit, ..., limit 16:19(1111)
db 0 ; base 24:31
gdt_data equ $-gdt
dw 0ffffh
dw 0
db 0
db 10010010b ; data segment(bit4)
db 11001111b
db 0
gdt_end:
;; gdt descriptor
gdt_desc:
dw gdt_end-gdt-1
dd gdt
;; ---------------------------
;; interrupt descriptor table
;; ---------------------------
;; idt descriptor
idt_desc:
dw idt_end-idt-1
dd idt
idt:
%rep 32
dw void_isr
dw gdt_code ; gdt selector
db 0 ; always zero
db 8eh ; access, attributes
dw 0 ; void_isr >> 16 == 0
%endrep
dw isr_test
dw gdt_code
db 0
db 8eh
dw 0
idt_end:
times ((2880*512-512)-($-$$)) db 0 ; complete floppy disk for bochs
der far-jump in den protected mode hat einen triple-fault zur folge.
00000904030e[CPU ] fetch_raw_descriptor: GDT: index (f)1 > limit (0)
00000904030e[CPU ] interrupt(): gate descriptor is not valid sys seg
00000904030e[CPU ] interrupt(): gate descriptor is not valid sys seg
00000904030i[CPU ] protected mode
00000904030i[CPU ] CS.d_b = 16 bit
00000904030i[CPU ] SS.d_b = 16 bit
00000904030i[CPU ] | EAX=00000011 EBX=00000000 ECX=00130002 EDX=00000000
00000904030i[CPU ] | ESP=00001137 EBP=00000000 ESI=000088f0 EDI=0000ffde
00000904030i[CPU ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00000904030i[CPU ] | SEG selector base limit G D
00000904030i[CPU ] | SEG sltr(index|ti|rpl) base limit G D
00000904030i[CPU ] | CS:1000( 1e00| 0| 0) 00010000 0000ffff 0 0
00000904030i[CPU ] | DS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00000904030i[CPU ] | SS:0100( 0000| 0| 0) 00001000 0000ffff 0 0
00000904030i[CPU ] | ES:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00000904030i[CPU ] | FS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00000904030i[CPU ] | GS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00000904030i[CPU ] | EIP=00000020 (00000020)
00000904030i[CPU ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00000904030i[CPU ] | CR3=0x00000000 CR4=0x00000000
00000904030i[CPU ] >> jmp far 0008:00000028 : 66EA280000000800
00000904030e[CPU ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00000904030i[SYS ] bx_pc_system_c::Reset(SOFTWARE) called
00000904030e[CPU ] CPU_LOOP bx_guard.interrupt_requested=1
Next at t=904030
(0) [0x00010020] 1000:0020 (unk. ctxt): jmp far 0008:00000028 ; 66ea280000000800