Hello world boot sector doesn't work...

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
kernel64_lazy

Hello world boot sector doesn't work...

Post by kernel64_lazy »

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
User avatar
Pype.Clicker
Member
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...

Post by Pype.Clicker »

kernel64_lazy wrote: Thanks in advance. This is killing me!
RIP.

Code: Select all

[BITS 16]
[ORG 0x7C00]
The BIOS could be running your bootsector with "JMP 0000:7C00" or "JMP 07C0:0000". Here you tell the assembler to organize code so that it will be located at offset 7C00 within the current segment.

Code: Select all

start:
   jmp 0x7C0:realstart
Now, you enforce CS=07C0, IP=5+ORG_value, so you'll be jumping to 0xE800 or something instead of expected 0x7C00 ...

So better have "jmp 0x0000:realstart" instead of what you have: that'll give better result :)
kernel64_lazy

Re:Hello world boot sector doesn't work...

Post by kernel64_lazy »

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.
AR

Re:Hello world boot sector doesn't work...

Post by AR »

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.
kernel64_lazy

Re:Hello world boot sector doesn't work...

Post by kernel64_lazy »

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 ... ???
AR

Re:Hello world boot sector doesn't work...

Post by AR »

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.
kernel64

Re:Hello world boot sector doesn't work...

Post by kernel64 »

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)
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...

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.
AR

Re:Hello world boot sector doesn't work...

Post by AR »

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)
kernel64

Re:Hello world boot sector doesn't work...

Post by kernel64 »

AR 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)
Oops. Ah-ha! Thanks a thousand times ;D ;D ;D
Post Reply