First off - great site!!!!
I am an assembly beginner, I can seem to work out what's wrong with the bootloader listed below. I used to use just a simple call to int 0x13 to load in the sectors (ignoring track's etc..) until the kernel size got to about 50 sectors - it would no longer work :-)
Having looked at various bootloaders out there I have changed it to load in a track at a time - but this does not work - anyone any ideas??
%define KERNEL_SIZE 60
[BITS 16]
[ORG 0]
jmp short start
nop
driveSectors db 18
driveHeads db 1
start: cli ; disable interrupts
mov ax, 0x7c0 ; BIOS sticks us here
mov ds, ax ;
mov ax, 0x9000 ; setup stack
mov ss, ax
sti ; enable interrupts
mov [bootdrive], dl ; save the bootdrive
mov si, bootmsg ; display bootmsg
call writechars
mov ah, 0
int 0x13
jc reseterror
startloadKernel:
mov ax, KERNEL_SIZE
div byte [ds:driveSectors]
mov si, ax
and si, 0xff
inc si
mov ax, 0x200 ; kernel load addr
mov es, ax
xor bx, bx
mov al, [ds:driveSectors] ; number of sectors to read
mov cx, 0x0002
loadKernel:
mov ah, 2
mov dl, [bootdrive]
int 0x13
jc loadKernel
dec si ; sectors to read --
jz readDone ; are we finished?
mov bx, es ;
add bx, 9216
mov es, bx
mov al, [ds:driveSectors]
xor bx, bx
readNextTrack:
mov cl, 1 ; reset back to sector 1
cmp dh, [ds:driveHeads]
je resetHeads
inc dh ; head++
jmp loadKernel
resetHeads:
xor dh, dh ; back to head 0, inc track
inc ch ; track++
jmp loadKernel
readDone:
mov si, kernelmsg ; display kernel loaded msg
call writechars
mov al, 0xff ; disable all irq's
out 0x21, al ; write to PIC controller
lgdt [gdt_ptr]
mov eax, cr0 ; get into protected mode
or al, 1
mov cr0, eax
mov ax, datasel ; setup segments to new selector
mov ds, ax
mov es, ax
mov fs, ax
mov ss, ax
mov gs, ax
jmp codesel:0x2000 ; jump into prot mode
jmp $
reseterror:
mov si, reseterrormsg
call writechars
jmp $
writechars:
lodsb
or al, al
jz .done
mov ah, 0x0e
mov bx, 7 ; write text
int 0x10
jmp writechars
.done:
ret
; data section
bootmsg db 0dh, 0ah, "Booting..", 00h
kernelmsg db 0dh, 0ah, "Kernel loaded", 00h
resetfloppymsg db 0dh, 0ah, "Reset Floppy", 00h
reseterrormsg db 0dh, 0ah, "Reset error", 00h
loaderrormsg db 0dh, 0ah,"Unable to load operating system kernel.", 0dh, 0ah, 00h
dotmsg db "."
bootdrive db 0
gdt_ptr
dw end_gdt - start_gdt - 1
dd start_gdt
start_gdt
dd 0x00000000 ; dummy selector
dd 0x00000000
codesel equ $-start_gdt
code0
dw 0xffff ; segment limit
dw 0x0000 ; base address
db 0x00 ;
db 0x9a ; priv level 0, code
db 0xcf ; granurlarity
db 0x00 ; base address
datasel equ $-start_gdt
data0
dw 0xffff ; segment limit
dw 0x0000 ; base address
db 0x00 ;
db 0x92 ; priv level 0, data
db 0xcf ; gran
db 0x00 ; base address
stacksel equ $-start_gdt
stack0
dw 0xffff ; segment limit
dw 0x0000 ; base address
db 0x00 ;
db 0x92 ; 0, data
db 0xcf ; gran
db 0x00 ; base address
end_gdt
; pad out sector
outside: times (510-($-$$)) db 0
; boot signature (last 2 bytes)
dw 0x55AA
Protected Mode - Bootloader
Re: Protected Mode - Bootloader
1st off you dont really need a stack selector.First off - great site!!!!
I am an assembly beginner, I can seem to work out what's wrong with the bootloader listed below. I used to use just a simple call to int 0x13 to load in the sectors (ignoring track's etc..) until the kernel size got to about 50 sectors - it would no longer work
Having looked at various bootloaders out there I have changed it to load in a track at a time - but this does not work - anyone any ideas??
you can just use the data selector.
at first glance the code looks fine to me. I'd really have to test it to make sure.
basically you just need to read, what, mm... 18 sectors, flip the head, 18 sectors, reset head, increment track/cylinder.
quite basic stuff.
erugh. your reading in at 0x2000, your boot sector is running at 0x7c00, so if your kernel is really big, your going to read code in over the top of your self and crash.
you can either relocate the boot sector code at runtime to down to like 0x600, or read your kernel in at say 0x8000 instead of 0x2000
i'm sure if there is an error in your code, someone else will spot it and post here for you!
-- Stu --
Re: Protected Mode - Bootloader
I think it would help a lot if you recalibrated your floppy disc drive before you execute a read operation (and that is everytime before you execute a read operation).
Re: Protected Mode - Bootloader
I don't think this is necessary. BIOS does calibration before it loads the bootsector. If it did not, you won't be able to boot up off the floppy disk sometimes.I think it would help a lot if you recalibrated your floppy disc drive before you execute a read operation (and that is everytime before you execute a read operation).
Re: Protected Mode - Bootloader
DF is right, let's do the math here:
- boot code at 0x7c00
- start of kernel code at 0x2000
- 50 sectors * 512 b/s = 25KB (~0x6000)
?0x2000
+0x6000
======
0x8000
Somewhere between sectors 49 and 50, you're overwriting your boot code. ?When the proc. jumps to the next instruction, WHAMMO! It's crash time. ?You could do this:
[tt]
mov ax, 0x07c0 ? ? ? ?; Source Segment
mov ds, ax
mov ax, 0x9000 ? ? ? ?; Dest segment
mov es, ax
xor si, si ? ? ? ? ? ? ? ? ?; Zero offset
xor di, di ? ? ? ? ? ? ? ? ?; Ditto
mov cx, 0x200 ? ? ? ? ?; 512 Bytes
cld ? ? ? ? ? ? ? ? ? ? ? ? ?; Clear the direction flag
rep movsb ? ? ? ? ? ? ? ?; move it!
; New segments for everything
mov es, ax
mov ds, ax
; JMP!
jmp 0x9000:there ; or JMP FAR 0x9000:there if you have to
there:
; Blah blah blah - Rest of Really New Nifty OS (TM) goes here
[/tt]
That was off the top of my head, but should be more or less correct
HTH (Even though you've probably fixed this by now),
Breckin
- boot code at 0x7c00
- start of kernel code at 0x2000
- 50 sectors * 512 b/s = 25KB (~0x6000)
?0x2000
+0x6000
======
0x8000
Somewhere between sectors 49 and 50, you're overwriting your boot code. ?When the proc. jumps to the next instruction, WHAMMO! It's crash time. ?You could do this:
[tt]
mov ax, 0x07c0 ? ? ? ?; Source Segment
mov ds, ax
mov ax, 0x9000 ? ? ? ?; Dest segment
mov es, ax
xor si, si ? ? ? ? ? ? ? ? ?; Zero offset
xor di, di ? ? ? ? ? ? ? ? ?; Ditto
mov cx, 0x200 ? ? ? ? ?; 512 Bytes
cld ? ? ? ? ? ? ? ? ? ? ? ? ?; Clear the direction flag
rep movsb ? ? ? ? ? ? ? ?; move it!
; New segments for everything
mov es, ax
mov ds, ax
; JMP!
jmp 0x9000:there ; or JMP FAR 0x9000:there if you have to
there:
; Blah blah blah - Rest of Really New Nifty OS (TM) goes here
[/tt]
That was off the top of my head, but should be more or less correct
HTH (Even though you've probably fixed this by now),
Breckin