Using int 0x13 to write to disk

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
kurmasz
Posts: 19
Joined: Tue Apr 04, 2017 2:37 pm

Using int 0x13 to write to disk

Post by kurmasz »

When I use BIOS int 0x13 to write to disk, I get an error, unless the sector number is 1 or 2.

I am using VirtualBox and booting from a virtual floppy disk. When I query for the drive parameters, ch=0x4f and cl=0x12; but, when I set cl=0x3 when writing, I get an error and al=1. Am I misinterpreting the results of the query?

Code: Select all

       
       // "initialization" code is also included below, but removed here for clarity
       // at this point, dl is unchanged from its initial value.

        mov $0x08, %ah
        int $0x13

        PUTC $'c
        PRINT_HEX <%ch>
        PUTC
        PRINT_HEX <%cl>
        PRINT_NEWLINE

        mov initial_dl, %dl

        // test write                                                                                                                                    
        mov $0x03, %ah
        mov $1, %al
        mov $end_of_s1, %bx
        mov $0, %ch
        mov $0x3, %cl
        mov $0x00, %dh
        int $0x13

        jc is_error

        PUTC $'n
        PUTC $'o
        jmp finish

is_error:
        PUTC $'e
        PUTC $'r

finish:
        PRINT_HEX <%ah>
        PUTC
        PRINT_HEX <%al>
        PRINT_NEWLINE

        jmp .

end_of_s1:
        .asciz "MESSAGE at end of Stage 1"


This is the complete coe

Code: Select all

.code16
.section .boot
        /*******************************************************************                                     
         *                                                                                                       
         * Initial set up (including the stack)                                                                  
         *                                                                                                       
         ******************************************************************/

        // disable interrupts                                                                                    
        cli

        /* Set %cs to 0. (If I understand this correctly, in real                                                
        mode, the ljmp instruction sets both the CS (code segment)                                               
        register as well as the EIP. $1f is the next label with a                                                
        value of "1", which appens to be on the next line. Thus, this                                            
        instrucion assures that the CS register is set to the segment                                            
        containing the code we are currently running                                                             
        */
        ljmp $0, $1f
        1:

        /* Sets %ax to 0.  (I'm not sure why we're not using mov.) */
        xor %ax, %ax

        /* Set all the segment registers to 0, just so we know for sure                                          
        what's going on. */
        mov %ax, %ds
        mov %ax, %es
        mov %ax, %fs
        mov %ax, %gs

        mov %ax, %bp
        mov %ax, %ss
        mov %bp, %sp


        /* Store the initial dl to load stage 2 later on. */
        mov %dl, initial_dl
        jmp after_locals
initial_dl: .byte 0
after_locals:


        PUTC $'g
        PRINT_HEX <%dl>
        PRINT_NEWLINE

        mov $0x08, %ah
        int $0x13

        PUTC $'c
        PRINT_HEX <%ch>
        PUTC
        PRINT_HEX <%cl>
        PRINT_NEWLINE

        mov initial_dl, %dl

        // test write                                                                                            
        mov $0x03, %ah
        mov $1, %al
        mov end_of_s1, %bx
        mov $0, %ch
        mov $0x3, %cl
        mov $0x00, %dh
        int $0x13

        jc is_error

        PUTC $'n
        PUTC $'o
        jmp finish

is_error:
        PUTC $'e
        PUTC $'r

finish:
       PRINT_HEX <%ah>
        PUTC
        PRINT_HEX <%al>
        PRINT_NEWLINE

        jmp .

end_of_s1:
        .asciz "MESSAGE at end of Stage 1"
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Using int 0x13 to write to disk

Post by Brendan »

kurmasz wrote:When I use BIOS int 0x13 to write to disk, I get an error, unless the sector number is 1 or 2.

I am using VirtualBox and booting from a virtual floppy disk. When I query for the drive parameters, ch=0x4f and cl=0x12; but, when I set cl=0x3 when writing, I get an error and al=1. Am I misinterpreting the results of the query?
If it works for sectors 1 and 2, but doesn't work for sector 3 when everything else is the same; then I'd assume you're using a floppy disk image in an emulator that is only 1024 bytes or 2048 bytes. To fix that use something (e.g. dd, NASM, etc) to create a 1440 KiB file with your code at the start and the rest full of zeros.

A better idea is to write a custom tool that creates floppy images to suit your OS. For example, mine takes several command line arguments (the type of the floppy disk and the file names for things my OS needs - boot loader, "initial RAM disk", etc) and does some calculations to figure out which sectors each thing should use, then generates a correct BPB to suit the type of floppy disk (and a little more info that my boot loader uses). Of course my boot loader uses the fields in the BPB (so it can get LBA to CHS conversion right). This makes it fairly trivial for me to generate (working) floppy disk images for any standard floppy disk format (1680 KiB, 1200 KiB, 1440 KiB, ..., 160 KiB).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
kurmasz
Posts: 19
Joined: Tue Apr 04, 2017 2:37 pm

Re: Using int 0x13 to write to disk

Post by kurmasz »

That was it, thank you. (I thought the VM would just expand the .img file, if necessary.)

So, now the "OS" runs and writes data to the virtual floppy; but, it writes the wrong data to the floppy (and I can't tell where the data that is being written is coming from). Again, the code works on a real machine, just not on the VM. (However, the real machine is booting from a USB stick, not a floppy.) Are there any other beginner mistakes I should look for?
User avatar
SpyderTL
Member
Member
Posts: 1074
Joined: Sun Sep 19, 2010 10:05 pm

Re: Using int 0x13 to write to disk

Post by SpyderTL »

Code: Select all

ljmp $0, $1f
I'd be suprised if this actually works.

Try changing your label to "start:" and change your ljmp statement to match. You shouldn't need the $.
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Post Reply