Hello world boot sector doesn't work...
Hello world boot sector doesn't work...
Hi everyone. This has been bugging me for ages. I always wanted to load straight from GRUB and bypass the tortured 16-bit real mode booting method with BIOS, etc. But anyway I couldn't help myself. It doesn't work and I can't figure out why. Any help? Thanks in advance. This is killing me!
[BITS 16]
[ORG 0x7C00]
start:
jmp 0x7C0:realstart
realstart:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, stacktop
; Load 64KB here, which is 1024B x 64 = 65536B = 128 sectors
mov si, datapkt
mov ah, 0x42
mov dl, 0
mov cx, WORD 5
read_floppy:
int 0x13
jc die
dec cx
cmp cx, WORD 0
je die
jmp read_floppy
; Just hang for now...
die:
mov si, floppy_read_failed
call write_string
hang:
hlt
jmp hang
load_ok:
; Off we go!
mov si, success_msg
call write_string
jmp hang
; jmp 0x100:0000
; write_string
; updates cursor and scrolls as necessary
; si = pointer to asciz string
write_string:
push bp ; work around buggy BIOS that trashes bp if screen scrolls
mov ah, 0xE
mov bh, 0
mov bl, 7
.putc:
lodsb
or al, al
jz .done
int 0x10
jmp .putc
.done:
pop bp
ret
datapkt:
db 0x10 ; length of this packet
db 0 ; reserved
dw 0x80 ; 128 sectors, or 64KB
dd 0x1000 ; store here, at 4KB
; start at absolute block/sector number 2. This is a 64-bit int
dd 0x00000002
dd 0x00000000
floppy_read_failed:
db "Error! Failed to load kernel.\r\n",0
success_msg:
db "Success! Loaded kernel!\r\n",0
stack:
times 64 db 0
stacktop:
times 510-($-$$) db 0
dw 0xAA55
[BITS 16]
[ORG 0x7C00]
start:
jmp 0x7C0:realstart
realstart:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, stacktop
; Load 64KB here, which is 1024B x 64 = 65536B = 128 sectors
mov si, datapkt
mov ah, 0x42
mov dl, 0
mov cx, WORD 5
read_floppy:
int 0x13
jc die
dec cx
cmp cx, WORD 0
je die
jmp read_floppy
; Just hang for now...
die:
mov si, floppy_read_failed
call write_string
hang:
hlt
jmp hang
load_ok:
; Off we go!
mov si, success_msg
call write_string
jmp hang
; jmp 0x100:0000
; write_string
; updates cursor and scrolls as necessary
; si = pointer to asciz string
write_string:
push bp ; work around buggy BIOS that trashes bp if screen scrolls
mov ah, 0xE
mov bh, 0
mov bl, 7
.putc:
lodsb
or al, al
jz .done
int 0x10
jmp .putc
.done:
pop bp
ret
datapkt:
db 0x10 ; length of this packet
db 0 ; reserved
dw 0x80 ; 128 sectors, or 64KB
dd 0x1000 ; store here, at 4KB
; start at absolute block/sector number 2. This is a 64-bit int
dd 0x00000002
dd 0x00000000
floppy_read_failed:
db "Error! Failed to load kernel.\r\n",0
success_msg:
db "Success! Loaded kernel!\r\n",0
stack:
times 64 db 0
stacktop:
times 510-($-$$) db 0
dw 0xAA55
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Hello world boot sector doesn't work...
RIP.kernel64_lazy wrote: Thanks in advance. This is killing me!
Code: Select all
[BITS 16]
[ORG 0x7C00]
Code: Select all
start:
jmp 0x7C0:realstart
So better have "jmp 0x0000:realstart" instead of what you have: that'll give better result
Re:Hello world boot sector doesn't work...
Thanks Pype!
I have thoroughly misunderstood the segment:offset thing. I was under the impression that jmp 0x7C0:realstart would make the bootsector be at 0x7C00:realstart, with IP there properly. So how would I assert that cs = 0x7C00, and make IP go to the right place?
But I suppose it doesn't matter, because IP will never overflow since I never get the chance to churn through enough instructions to go over 64K, and I hope to jmp 0x100:0000 eventually (0x1000:0000), i.e. kernel loads at 4KB.
I want to write an assembler file to pick up at 0x1000, which then calls kmain() in the C code. I'm using the bcc 16-bit C compiler.
I have thoroughly misunderstood the segment:offset thing. I was under the impression that jmp 0x7C0:realstart would make the bootsector be at 0x7C00:realstart, with IP there properly. So how would I assert that cs = 0x7C00, and make IP go to the right place?
But I suppose it doesn't matter, because IP will never overflow since I never get the chance to churn through enough instructions to go over 64K, and I hope to jmp 0x100:0000 eventually (0x1000:0000), i.e. kernel loads at 4KB.
I want to write an assembler file to pick up at 0x1000, which then calls kmain() in the C code. I'm using the bcc 16-bit C compiler.
Re:Hello world boot sector doesn't work...
ORG is an assembler directive, it instructs the assembler that the code you are writing is located at CS:ORG (and DS:ORG), since you set CS to 0x7C0 you have effectively got 0x7C0:0x7C00 which is obviously not going to work. You want to either change the far jump to 0000:7C00 or change ORG to 0.
Re:Hello world boot sector doesn't work...
Thanks -- I fixed the ORG to 0 and now it works great. Now I am grappling with the floppy disk. It doesn't seem to work, no matter what method I use. I would like to use int 0x13 EXTENDED READ, but no go. I also tried int 0x13 READ SECTORS but that doesn't want to work either.
I know it's possible to read a whole track at a time. Should I do that rather than trying to read in all the sectors I want at once with a single extended read?
I've also seen that if I wanted to read a sector at a time, the head changes each track. So let me see, there are two sides on 3.5in 1.44MB floppies, which means two heads. So in CHS terms, I have 18 sectors per track (or per cylinder), where the head changes for the next track for another 18 sectors, and so on until 80 tracks have been read. That's 512 bytes per sector * 18 sectors per track * 2 heads * 80 double-sided tracks in total.
What a confusing mess! Is that the same way CHS is used in hard disks? When I look at the BIOS-provided geometry of my hard disk, is it roughly the same thing, with more heads and more tracks? So if I want to read all the sectors on a hard disk, I have to read n sectors per track, times x heads, then keep going for however many tracks/cylinders there are?
Thanks ... ???
I know it's possible to read a whole track at a time. Should I do that rather than trying to read in all the sectors I want at once with a single extended read?
I've also seen that if I wanted to read a sector at a time, the head changes each track. So let me see, there are two sides on 3.5in 1.44MB floppies, which means two heads. So in CHS terms, I have 18 sectors per track (or per cylinder), where the head changes for the next track for another 18 sectors, and so on until 80 tracks have been read. That's 512 bytes per sector * 18 sectors per track * 2 heads * 80 double-sided tracks in total.
What a confusing mess! Is that the same way CHS is used in hard disks? When I look at the BIOS-provided geometry of my hard disk, is it roughly the same thing, with more heads and more tracks? So if I want to read all the sectors on a hard disk, I have to read n sectors per track, times x heads, then keep going for however many tracks/cylinders there are?
Thanks ... ???
Re:Hello world boot sector doesn't work...
If you look at the specs carefully the extended read only works on drive numbers >=0x80, ie. floppies are only compatible with the old read method. Also be aware that the extended read/write features were only added around 1997, computers before then will likely not support it (not that it matters since I assume your OS is 64bit, and all 64bit computers are newer than that)
The geometry of floppies (1.44MB) is a known constant (2 heads, 18 sectors per track, 2880 sectors in total, 512 bytes per sector). The CHS read method is simple enough, you read all the sectors on the current track, increase current head, read it again, so on, when current head above number of heads, increment cylinder, reset current head to 0, repeat.
The geometry of floppies (1.44MB) is a known constant (2 heads, 18 sectors per track, 2880 sectors in total, 512 bytes per sector). The CHS read method is simple enough, you read all the sectors on the current track, increase current head, read it again, so on, when current head above number of heads, increment cylinder, reset current head to 0, repeat.
Re:Hello world boot sector doesn't work...
Where are the specs? Ralf Brown's interrupt list doesn't mention anything about only working for drives >= 0x80. Maybe it's because I'm looking at an HTML version that doesn't include everything the original RBIL docs have. If it doesn't mention these things then it's incomplete and needs to be fixed. Also it doesn't say what a disk block is (I can only assume it's a sector.) And it doesn't say where disk blocks begin (0 or 1). Very annoying...AR wrote: If you look at the specs carefully the extended read only works on drive numbers >=0x80, ie. floppies are only compatible with the old read method. Also be aware that the extended read/write features were only added around 1997, computers before then will likely not support it (not that it matters since I assume your OS is 64bit, and all 64bit computers are newer than that)
But thanks for that. I'll continue using READ SECTORS ah = 0x2. For some reason it's still not working. I'll have a few more goes and post code here as a last resort.
Re:Hello world boot sector doesn't work...
It does say on the Check for Extension support interrupt: http://www.ctyme.com/intr/rb-0706.htm (You do check whether it is actually supported first? )
I downloaded a PDF doc from Phoenix: http://www.phoenix.com/en/Customer+Services/White+Papers-Specs/pc+industry+specifications.htm (Enhanced Disk Drive Specification)
I downloaded a PDF doc from Phoenix: http://www.phoenix.com/en/Customer+Services/White+Papers-Specs/pc+industry+specifications.htm (Enhanced Disk Drive Specification)
Re:Hello world boot sector doesn't work...
Oops. Ah-ha! Thanks a thousand times ;D ;D ;DAR wrote: It does say on the Check for Extension support interrupt: http://www.ctyme.com/intr/rb-0706.htm (You do check whether it is actually supported first? )
I downloaded a PDF doc from Phoenix: http://www.phoenix.com/en/Customer+Services/White+Papers-Specs/pc+industry+specifications.htm (Enhanced Disk Drive Specification)