Page 1 of 1

Read next sector of a virtual disk

Posted: Sun Jun 17, 2012 4:58 pm
by alexbnc
I have posted this question to a general-programming forum and they redirected me to this forum, so I hope my question is complicated enough to deserve its place on a professional developers forum.
Well, my questions goes here:

As any programmer in the world at least once in his/her life, I am trying to create my "revolutionary", the new and only one operating system. :D
Well, I am using a virtual emulator (Oracle VM Virtual Box), for which I created a new unknwon operating system, with a vmdk disk. I like vmdk because they are just plain files, so I can paste my boot-loader over the first 512 bytes of the virtual hard disk.
Now, I am trying to read the next sector of this virtual disk, on which I would paste a simple kernel that would display a message.
I have two questions:
  • Am I reading the second segment (the first -512 bytes- is occupied by the bootloader) correctly?

    Code: Select all

    ; bootloader
    ; some code here...
    ReadDisk:
        mov bx, 0x8000  ; segment
        mov es, bx
        mov bx, 0x0000  ; offset
    
        mov ah, 0x02  ; read function
        mov al, 0x01  ; sectors - this might be wrong, trying to read from hd
        mov ch, 0x00  ; cylinder
        mov cl, 0x02  ; sector
        mov dh, 0x00  ; head
        mov dl, 0x80  ; drive - trying to read from hd
        int 0x13   ; disk int
        jc ReadDisk
        jmp [es:bx]   ; buffer
    ; some code here...
    
    So, the sector is read correctly, as I don't get any error. I checked that with

    Code: Select all

    int 13, 01h
    and also with

    Code: Select all

    js ShowError
    , where ShowError is a procedure displaying an error message
  • Am I pasting my simple kernel in the correct place inside the vmdk? What I do is pasting it after the 512th byte of the file, the first 512 bytes, as I said, are the boot-loader. The file would look like this:

    Code: Select all

    BE 45 7C E8 16 00 EB FE B4 0E B7 00 B3 07 CD 10 <- First sector
    C3 AC 08 C0 74 05 E8 EF FF EB F6 C3 B4 00 B2 80
    CD 13 BE 5D 7C 72 F5 BB 00 80 8E C3 BB 00 00 B4 
    02 B0 06 B5 00 B1 01 B6 00 B2 07 CD 13 BE 4E 7C 
    72 CF 26 FF 27 57 65 6C 63 6F 6D 65 21 00 52 65 
    61 64 69 6E 67 20 65 72 72 6F 72 21 00 52 65 73 
    65 74 74 69 6E 67 20 65 72 72 6F 72 21 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA <- Boot-loader signature
    B4 0E B0 2E CD 10 EB FE 00 00 00 00 00 00 00 00 <- Start of the second sector
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    [/size]
    So, this is the way I am trying to add the kernel to the second sector. What do you think is wrong with this? Thanks!
O.K. I don't get any error now, but I don't see the loaded kernel being executed. It should display a point character on the window:

Code: Select all

; tiny kernel
[org 0x8000]
[bits 16]

main:
      mov ah, 0x0E  ; print function
      mov al, '.'   ; ascii char
      int 0x10   ; IO int

      jmp $    ; hang
Well, I hope somebody can give some answer to my question, I hope they are not fool questions, I hope they can help anybody else. Thanks in advance!

Re: Read next sector of a virtual disk

Posted: Sun Jun 17, 2012 8:11 pm
by thepowersgang
Ok, first off - thanks for the well posted question.

Two things, your ORG statement isn't where you're actually loading to.
You load to 0x80000 (ES=0x8000 -> linear 0x80000), but the program is linked to 0x8000 (a factor of 16 lower). But that isn't the problem.

The only problem with the loading code is the final jump. It jumps to the address located at ES:BX, not ES:BX (so, in this case it would do a near jump to 0x0EB4) Change the instruction to "jmp 0x8000:0x0000" and it should work.

[edit] Fixed assumption

Re: Read next sector of a virtual disk

Posted: Wed Jun 20, 2012 6:11 am
by Ready4Dis
--- Edit ---
Oops, mis-read something. Post deleted.

Re: Read next sector of a virtual disk

Posted: Wed Jun 20, 2012 4:24 pm
by turdus
What thepowersgang said plus
alexbnc wrote:I checked that with

Code: Select all

int 13, 01h
and also with

Code: Select all

js ShowError
No, you haven't checked. All BIOS functions sets carry flag, not sign flag on error (see RBIL Int 13/AH=01h).

Re: Read next sector of a virtual disk

Posted: Wed Jun 27, 2012 10:27 am
by alexbnc
Thanks to everyone for comprehension and help. Yet, I can't make it work.
As I said, I build the disk image by pasting chunks of 512 bytes (1 sector). First 512 are the boot-loader, second 512 are the "kernel". It should display a (.) character on the screen. Following your instruction, I just changed the jump to the "kernel's" location:

Code: Select all

jmp 0x8000:0x0000
Maybe the problem lies in the way I am trying to emulate this. :-k I should need some tools to see how the code is executed and emulated by Oracle VM, to see from where and what memory address is being called. Starting to handle with the hard disk is really a great step. ](*,)

Re: Read next sector of a virtual disk

Posted: Wed Jun 27, 2012 1:42 pm
by DavidCooper
BE 45 7C E8 16 00 EB FE B4 0E B7 00 B3 07 CD 10 <- First sector
C3 AC 08 C0 74 05 E8 EF FF EB F6 C3 B4 00 B2 80
CD 13 BE 5D 7C 72 F5 BB 00 80 8E C3 BB 00 00 B4
02 B0 06 B5 00 B1 01 B6 00 B2 07 CD 13 BE 4E 7C
72 CF 26 FF 27 57 65 6C 63 6F 6D 65 21 00 52 65
61 64 69 6E 67 20 65 72 72 6F 72 21 00 52 65 73
65 74 74 69 6E 67 20 65 72 72 6F 72 21 00 00 00
The B2 07 part of that is loading DL with 7 instead of the intended drive number 80h. Your source code is right, but there's an error in the hex version of it. I doubt that same error will occur in subsequent attempts, but I'd like to see the hex of the version you're using now, particularly to see how you're doing the jump to kernal now. Post your source code too, but I want to see the hex as it doesn't hide anything.

Re: Read next sector of a virtual disk

Posted: Wed Jun 27, 2012 3:10 pm
by alexbnc
O.K. This is how my vmdk looks like in its first 512 + 512 bytes now

Code: Select all

E8 1D 00 B4 0E B7 00 B3 07 CD 10 C3 AC 08 C0 74 <-- first sector
05 E8 EF FF EB F6 C3 B4 00 B2 80 CD 13 72 F8 C3 
E8 F4 FF BB 00 80 8E C3 BB 00 00 B4 02 B0 01 B5 
01 B1 02 B6 00 B2 80 CD 13 72 E5 EA 00 00 00 80 
52 65 61 64 69 6E 67 20 65 72 72 6F 72 21 00 52 
65 73 65 74 74 69 6E 67 20 65 72 72 6F 72 21 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA 
B4 0E B0 2E CD 10 EB FE 00 00 00 00 00 00 00 00 <-- second sector
.......... and 128 Mb of 00 to the end ................

Thanks!

Note: I emulated the second's sector code (B4 0E B0 2E CD 10 EB FE 00) in emu8086 and I see that it starts at 0100:0000 in memory. emu8086 understands org instruction and even if I clearly specify where to be loaded (0x8000) it loads it at 0.

Re: Read next sector of a virtual disk

Posted: Wed Jun 27, 2012 3:22 pm
by Griwes
org is not an instruction, it's an assembly directive, telling assembler for what address it should link the code...

Re: Read next sector of a virtual disk

Posted: Wed Jun 27, 2012 3:43 pm
by DavidCooper
E8 1D 00 B4 0E B7 00 B3 07 CD 10 C3 AC 08 C0 74 <-- first sector
05 E8 EF FF EB F6 C3 B4 00 B2 80 CD 13 72 F8 C3
E8 F4 FF BB 00 80 8E C3 BB 00 00 B4 02 B0 01 B5
01
B1 02 B6 00 B2 80 CD 13 72 E5 EA 00 00 00 80
52 65 61 64 69 6E 67 20 65 72 72 6F 72 21 00 52
65 73 65 74 74 69 6E 67 20 65 72 72 6F 72 21 00
B5 01 is loading CH with 1, but you want track 0.

The jump is correct, so once you fix the track number it looks as if it should work.

[Edit: I notice another difference between the original hex and source code where the source code shows CL being loaded with 2 while the hex shows CL being loaded with 1. If you aren't making these mistakes, maybe you're using a faulty assembler.]

[Edit 2: If it still doesn't work, you should store DL to a variable right at the start and use that for the drive number every time instead of just assuming it's 80h, which it might not be - the BIOS always passes control to your code with the right drive number in DL on booting.]

Re: Read next sector of a virtual disk

Posted: Wed Jun 27, 2012 6:30 pm
by alexbnc
Holy crap! It works! Finally! =D>
I have created 3D engines with C++ but I have never been so satisfied like now. I can make a computer display a dot on the screen. Is it normal to behave like this? :D :lol: :D
I have been trying to figure out this for a month. Well, now I can release my first O.S. Ha ha, just kidding. Now I understand why it will take so much, specially for someone quite new in this world of development.
Well, thanks to everybody, I know where I can post my questions and problems now. Let's continue our journey!


P.S.
I took a look over the Windows boot-loader and it looks like it loads the second boot-loader from the 64th sector. Why would that be so?