Also ich stimme da bitmaster irgendwie zu, aber es ist ja auch erstmal egal.
Ich hab jetzt einen bootloader gefunden (und auch groesstenteils verstanden, ich muss mir trotzdem nochmal einen selbst bauen), aber der funktioniert noch nicht ganz. [bits 16]
[org 0x7C00]
jmp boot
;-------------Data
;-------------GDT Table
GDTR:
GDTsize DW GDT_END-GDT-1
GDTbase DD 0x500
GDT:
NULL_SEL EQU $-GDT ; null descriptor is required (64bit per entry)
DD 0x0
DD 0x0
CODESEL EQU $-GDT ; 4GB Flat Code at 0x0 with max 0xFFFFF limit
DW 0xFFFF ; Limit(2):0xFFFF
DW 0x0 ; Base(3)
DB 0x0 ; Base(2)
DB 0x9A ; Type: present,ring0,code,exec/read/accessed (10011000)
DB 0xCF ; Limit(1):0xF | Flags:4Kb inc,32bit (11001111)
DB 0x0 ; Base(1)
DATASEL EQU $-GDT ; 4GB Flat Data at 0x0 with max 0xFFFFF limit
DW 0xFFFF ; Limit(2):0xFFFF
DW 0x0 ; Base(3)
DB 0x0 ; Base(2)
DB 0x92 ; Type: present,ring0,data/stack,read/write (10010010)
DB 0xCF ; Limit(1):0xF | Flags:4Kb inc,32bit (11001111)
DB 0x0 ; Base(1)
GDT_END:
;-------------GDT Table End
;-------------Variables
start_s DB 0 ; starting sector [0x1-0x12]
total DB 0 ; number of sector [max 2880]
track DB 0 ; track number [max 160]
head DB 0 ; head number [max 2]
drive DB 0 ; boot drive number [usually 0]
bseg DB 0 ; memory address segment
boff DW 0 ; and offset to load into
loadmsg db "bootsector loaded",13,10,0
;-------------Variables End
;-------------Functions
print: ; print string
lodsb ; load character
or al, al ; check if 0
jz short print_e
mov ah, 0x0e ; print
mov bx, 0x0007
int 0x10
jmp print ; next char
print_e:
ret
wkc:
xor al, al ; set al to 0
in al, 0x64 ; get kbd status through input port 0x64
test al, 2 ; check if second bit is clear
jnz wkc
ret
wkf:
xor cx, cx
in al, 0x64 ; get kbd status
test al, 1 ; check if first bit is clear
jz wkf
ret
halt: ; halt on error
mov byte [gs:0], al
mov byte [gs:1], 0x04
cli
hlt
;-------------Funtions End
;-------------Data End
boot:
mov [drive], dl
cli ; no interrupts
mov ax, cs
mov ds, ax
mov es, ax
mov fs, ax
mov ax, 0x1d0 ; stack address
mov ss, ax ; align stack
mov sp, 0x200 ; 512 byte stack
mov ax,0xb800 ; setup video segment
mov gs,ax
sti ; enable interrupts
jmp init
init:
; enable a20
cli
call wkc ; wait for kbd buffer to clear
mov al, 0xd1 ; write 0xd1
out 0x64, al ; to status
call wkc
mov al, 0xdf ; set settings in kdb (to enable a20)
out 0x60, al ; send the value
call wkc
mov cx, 0x10
kbdwait:
xor ax, ax ; do something
out 0xe0, ax ; more useless stuff
loop kbdwait
; is a20 enabled?
mov al, 0xd0
out 0x64, al
call wkf
in al, 0x60
test al, 2
jnz a20on
mov al, 'A'
call halt
a20on:
sti
; load kernel.bin from floppy at to 0x100000
read:
xor ax, ax ; Floppt reset BIOS function
mov dl, [drive] ; select floppy that was booted from
int 0x13
jc read
mov ax, 0xffff
mov es, ax ; data buffer for file
mov bx, 0x10 ; start of segment
mov ah, 2 ; BIOS function
mov al, 17 ; number of sector to read
mov ch, 1 ; track
mov cl, 1 ; sector
mov dh, 1 ; head
int 0x13 ; call BIOS read dist function
mov dx, 0x3f2 ; stop the motor
mov al, 0x0c ; from spinning
out dx, al
; move GDT to 0x500
xor ax, ax
mov ds, ax
mov es, ax
mov si, GDT ; Move from [ds:si]
mov di, [GDTbase] ; Move to [es:di]
mov cx, [GDTsize] ; size of GDT
cld ; clear the direction flag
rep movsb ; move it
; enter pmode
cli
mov eax, cr0
or al, 1
mov cr0, eax
; load gdt
lgdt[GDTR]
; clear cs/ip/eip
jmp CODESEL:FLUSH
[BITS 32]
FLUSH:
; refresh all segment registers
mov eax, DATASEL
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
mov ss, eax
mov esp, 0xffff
mov eax, 0xb8000
mov byte [eax], 'b'
inc eax
mov byte [eax], 7
;jmp $
jmp CODESEL:0x100000
; stop here
;hlt
times 512-($-$$)-2 db 0
dw 0x0AA55
So sieht er aus.
Fast am Ende gebe ich 'b' aus. Aber wie springe ich jetzt in den Kernel? Der ist also genau nach dem bootsector.
Wenn mir das jetzt noch jemand sagt, hab ich endlich wieder ein Erfolgserlebnis und ich kann weitermachen.
Edit: Also ich hab irgendwie noch ein bisschen rumgespielt...es geht jetzt...Jetzt faengt die Arbeit an.