OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Mar 29, 2024 6:08 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post subject: My bootloader crashes while reading the root directory
PostPosted: Thu Jan 11, 2018 2:20 am 
Offline

Joined: Fri Jul 08, 2016 8:44 pm
Posts: 14
Hello, after loading the to size of the root directory size and start into cx, ax respectively, i face a problem while trying to read it using readSector proc. the bootloader crashes and give me this error and QEMU closes.


Image

this is my code and make file

Code:
        jmp entery_point
;*********************************************
;           BIOS Parameters Block
;********************************************
        bytesPerSector       dw      512
        sectorsPerCluster    db      1
        reservedSectors      dw      1
        numberOfFATs         db      2
        rootEntries          dw      244
        totalSectors         dw      2880
        media                db      0xF0
        sectorsPerFAT        dw      9
        sectorsPerTrack      dw      18
        headsPerCylinder     dw      2
        hiddenSectors        dd      0
        totalSectorsBig      dd      0
        driveNumber          db      0
        unused               db      0
        extBootSignature     db      0x29
        serialNumber         dd      0xa0a1a1a6
        volumeLabel          db      "MY   FLOPPY"
        fileSystem           db      "FAT   12"

;********************************************
;           FUNCTIONS AND PROCS
;*******************************************

regs_init:
        ;;setting up the stack
        cli
        xor ax, ax
        mov ss, ax
        mov sp, 0xFFFF
        sti

        ;;setting up the segment registers
        mov ax, 0x07C0
        mov ds, ax
        mov es, ax
        jmp back


        ;;print procedure
print:
        lodsb
        or al, al
        jz done
        mov ah, 0x0E
        int 0x10
        jmp print
        done:
        ret


        ;;disk reset function
disk_reset:
        mov ah, 0       ;resetting function code
        mov dl, 0       ;drive to reset. 0 represents the floppy drive
        int 0x13
        ret


load_root_dir:
        ;;  computing the root directory size
        ;;  its equals to [rootEntries*the size of each entery (32 byte)] / the size of one sector
        xor dx, dx
        xor cx, cx
        mov ax, 0x0020
        mul WORD [rootEntries]
        div WORD [bytesPerSector]
        ;mov WORD [rootDirSize], ax
        xchg ax, cx

        ;;  computing the first cluster of the root directory
        ;;  according to the geometry of FAT12, the rootdir comes after
        ;;  the FAT tabels, the reserved and the hidden sectors
        ;;  thus its equal to numberOfFATs*sectorsPerFAT + reservedSectors + hiddenSectors
        mov al, BYTE [numberOfFATs]
        mul WORD [sectorsPerFAT]
        add ax, WORD [reservedSectors]
;        add ax, WORD [hiddenSectors]
        mov WORD [rootDirStart], ax
;        add ax, WORD [rootDirSize]
        mov WORD [dataSectionStart], ax
        add WORD [dataSectionStart], cx
        ret


;********************************************************
;       READ SECTORS FUNCTION
;       CX = NUMBER OF SECTORS TO READ
;       AX = NUMBER OF SECTORS TO READ
;       ES:BS = BUFFER TO READ TO, DEFAULT FOR INT 0x13
;*********************************************************
readSectors:
        main_read_loop:
            mov di, 0x0003          ;try 3 times before returning failure
        sector_read_loop:
            push ax
            push cx
            push bx
            call LBAtoCHS
            mov ah, 0x02                     ;function code for reading a sector
            mov al, 0x01                     ;read one sector
            mov ch, BYTE [CHSTrack]          ;track to read
            mov cl, BYTE [CHSSector]         ;sector to read
            mov dh, BYTE [CHSHead]           ;head to read
            mov dl, BYTE [driveNumber]       ;drive number to read from, refer the BPB
            int 0x13                         ;call the function
            jnc read_done
            call disk_reset                  ;if there is an error, reset the disk and try again
            dec di                           ;decrese the trial counter by 1
            pop ax
            pop cx
            pop bx
            jnz sector_read_loop
        read_done:
            pop ax
            pop cx
            pop bx
            add bx, WORD [bytesPerSector]    ;move the saving buffer into a new unused memory address
            inc ax                           ;increase the sector to be read
            loop main_read_loop
        ret


;**********************************************************************
;           LBA TO CHS CONVERSION
;           AX = LBA TO BE CONVERTED
;       CHSTrack = (LBA SECTOR / sectorsPerTrack) / + 1
;       CHSHead  = (LBA SECTOR / sectorsPerTrack) % headsPerCylinder
;       CHSSector= (LBA SECTOR / [sectorsPerTrack * headsPerCylinder])
;************************************************************************
LBAtoCHS:
        xor dx, dx          ;reset dx and prepare it to save the value bx:ax
        div WORD [sectorsPerTrack]      ;divide the value in ax by sectors per track and store the result at bx:ax
        inc dl                          ;add one to dl
        mov BYTE [CHSSector], dl
        xor dx, dx
        div WORD [headsPerCylinder]
        mov BYTE [CHSHead], dl
        mov BYTE [CHSTrack], al
        ret



;***************************************************
;           CHS TO LBA CONVERSION
;           LBA = (CLUSTER - 2) * sectorsPerCluster
;***************************************************

ClustersLBA:
        sub ax, 0x0002                       ;subtract 2 from the cluster number
        mov cx, 0x0000                       ;clear cx
        mov cl, BYTE [sectorsPerCluster]
        mul cx                               ;multiply cx by ax and store the value in ax
        add ax, WORD [dataSectionStart]       ;adds the start of the data sector to the LBA address
        ret


;*****************************************************
;              THE BOOTLOADER BODY
;****************************************************
entery_point:
       
        jmp regs_init
        back:
       
        call disk_reset     ;resets the disk and make it ready for reading
       
;       #############################################
;               STAGE 1, LOAD THE ROOT DIR
;       ############################################

        call load_root_dir       ;load the root directory
                                 ;the root dir info are stored at rootDirSize, rootDirStart
        ;;move the valuse of the root dir info into register AX, CX to read the root dir using readSectors function
;        mov cx, WORD [rootDirSize]
;        mov ax, WORD [dataSectionStart]

        ;;Load the root directory into ES:BX
        ;;ES is 0x7C00, set BX to be 0x0020
        mov bx, 0x0200
        call readSectors

;the execution never reaches this line

        mov si, msgd
        call print
;       ###########################################
;               STAGE 2, FIND THE NEXT STAGE
;       ##########################################

;       now the root dir contents are loaded, all i have to do is to look for the second stage name
;       cmpsb's logic is cmp (DS:SI), (ES:DI)

        mov cx, WORD [rootEntries]
        mov di, 0x0020              ;where our root dir is loaded
            search_stage2_loop:
                push cx
                mov cx, 0x000B      ;11 character for the file name
                mov si, fileName
                push di
                rep cmpsb
                pop di
                je loadFAT
                pop cx
                add di, 0x0020      ;32 byte entry, move to the next entry
                loop search_stage2_loop
        jmp stage2_not_found

loadFAT:
    mov si, msgd
    call print
    jmp exit
stage2_not_found:
    mov si, msgd
    call print

exit:
        cli
        hlt

;*******************************************************
;               VARIABELS SECTION
;*******************************************************

        CHSTrack                db      0
        CHSSector               db      0
        CHSHead                 db      0
        dataSectionStart        dw      0
        fileName                db      "NDBOOT  SYS"
        kernelStartingSector    dw      0
        rootDirSize             dw      0
        rootDirStart            dw      0
        msgd                     db      "Finally ",0

        times 510 - ($-$$) db 0

        dw 0xAA55



Code:
ASM = nasm
INPUT = "bootloader.nasm"
BIN = "loader.bin"
IMG = "img.img"
STAGE2 = "NDBOOT.SYS"

Bootloader: create_bin create_floppy
   dd if=$(BIN) bs=512 of=$(IMG) conv=notrunc

create_bin:
   $(ASM) -f bin $(INPUT) -o $(BIN) -g

create_floppy:
   dd if=/dev/zero bs=512 count=2880 of=$(IMG)
   mkdosfs $(IMG)
   mcopy -i $(IMG) $(STAGE2) ::/$(STAGE2)
   mdir -i img.img

run:
   qemu-system-i386 -fda $(IMG)

clean:
   rm img.img loader.bin


the execution never reaches the line after calling readSector procedure. Whats wrong?


Top
 Profile  
 
 Post subject: Re: My bootloader crashes while reading the root directory
PostPosted: Thu Jan 11, 2018 3:33 am 
Offline
Member
Member
User avatar

Joined: Thu Nov 16, 2006 12:01 pm
Posts: 7612
Location: Germany
At StackOverflow, I'd make the following remarks:

  • It is much preferred to provide output as text, not screenshots. (Especially not screenshots of a terminal window, where copy & paste should be trivial.)
  • Your code sample is definitely not "minimal". You just dumped all your code on us and expect us (every single one of us trying to tackle the problem) to do all the debugging. What have you tried to narrow down the problem?
  • There is nothing (apparent to me) that indicates that your code even gets as far as readSectors. "Trying to execute code outside RAM or ROM at 0x000a0000" looks like a more substantial failure of your setup. Add dummy outputs to prove that your code actually works up to that point.

Generally speaking, the first thing you want your bootloader to do is to print "Hello" or somesuch to indicate that your code actually gets to execute... not reading from disk. Get to the point where your bootloader compiles, loads, and executes. Then make the next (small) step.

-1, vote to close.

StackOverflow wrote:
Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable example.

_________________
Every good solution is obvious once you've found it.


Top
 Profile  
 
 Post subject: Re: My bootloader crashes while reading the root directory
PostPosted: Thu Jan 11, 2018 3:56 am 
Offline

Joined: Fri Jul 08, 2016 8:44 pm
Posts: 14
Solar wrote:
At StackOverflow, I'd make the following remarks:

  • It is much preferred to provide output as text, not screenshots. (Especially not screenshots of a terminal window, where copy & paste should be trivial.)
  • Your code sample is definitely not "minimal". You just dumped all your code on us and expect us (every single one of us trying to tackle the problem) to do all the debugging. What have you tried to narrow down the problem?
  • There is nothing (apparent to me) that indicates that your code even gets as far as readSectors. "Trying to execute code outside RAM or ROM at 0x000a0000" looks like a more substantial failure of your setup. Add dummy outputs to prove that your code actually works up to that point.

Generally speaking, the first thing you want your bootloader to do is to print "Hello" or somesuch to indicate that your code actually gets to execute... not reading from disk. Get to the point where your bootloader compiles, loads, and executes. Then make the next (small) step.

-1, vote to close.

StackOverflow wrote:
Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable example.


You pointed me to an important mistake i done, i shouldn't have posted the whole source code and expect you to do the work for me But i tried. im telling you that the execution crashes at readSector by intuition. I've been trying to solve the problem for more than 2 days and i've added dummy outputs more than you can ever imagine but i cleared it off before posting the code. i even tried to debug it but i couldn't becuase ive never used bochs debugger before.

so thanks for your reply but dont think that im asking you to do the job for me. I tried as hard as i can.


Top
 Profile  
 
 Post subject: Re: My bootloader crashes while reading the root directory
PostPosted: Thu Jan 11, 2018 4:03 am 
Offline
Member
Member
User avatar

Joined: Thu Nov 16, 2006 12:01 pm
Posts: 7612
Location: Germany
Disclaimer: I haven't ever dabbled in Assembly, except for the little work I did on my own bootloader back then (before switching to GRUB). So I might be missing the obvious. But this here...

Code:
readSectors:
        main_read_loop:
            mov di, 0x0003          ;try 3 times before returning failure
        sector_read_loop:
            ; ...
            jnc read_done
            ; ...
            jnz sector_read_loop
        read_done:
            ; ...
            loop main_read_loop
        ret


...looks as if it's missing a way to return...? (Please describe the exact way you think readSectors should reach the ret.)

_________________
Every good solution is obvious once you've found it.


Top
 Profile  
 
 Post subject: Re: My bootloader crashes while reading the root directory
PostPosted: Thu Jan 11, 2018 4:52 am 
Offline
Member
Member

Joined: Tue Mar 04, 2014 5:27 am
Posts: 1108
The dump is kinda bad. EIP is >= 64KB. SP is too small (didn't you want 0xFFFF?). DS is 0 (didn't you want 0x7C0?).

One thing I'm seeing is your pushes and pops. Find the inconsistencies.

Got print? If so, debug your stuff.

And for the time being limit reads to 1 sector. If your calculations are screwed up, you may be overwriting something important in memory.


Top
 Profile  
 
 Post subject: Re: My bootloader crashes while reading the root directory
PostPosted: Thu Jan 11, 2018 8:55 am 
Offline
Member
Member
User avatar

Joined: Sun Jan 13, 2013 6:24 pm
Posts: 90
Location: Grande Prairie AB
Mohamed007 wrote:
i even tried to debug it but i couldn't becuase ive never used bochs debugger before.


What did you use to debug then, if you've never used BOCHs?

This seems like all your interested in is getting something to read a particular file from the FAT12 system and there is nothing wrong with that, but what you should do is peruse the internet for the dozens of working examples and use one of those. ...OR...

Solar wrote:
I haven't ever dabbled in Assembly, except for the little work I did on my own boot loader back then (before switching to GRUB).


That is a solution many use, especially for established file systems like FAT.


Top
 Profile  
 
 Post subject: Re: My bootloader crashes while reading the root directory
PostPosted: Thu Jan 11, 2018 10:10 am 
Offline
Member
Member
User avatar

Joined: Thu Nov 16, 2006 12:01 pm
Posts: 7612
Location: Germany
To back that up, there are two things I did not really consider myself back then before I tried GRUB.

Yes, it's cool to "do ASM" and get control as early as possible. But:

  • There is very little you can do in a homegrown bootloader that would set you apart from existing bootloaders. (After all, it's just for booting your kernel, a split-second affair at the beginning of the boot sequence...)
  • If you do anything "special" in your bootloader, you are forcing people to not only try your OS, but toss out their existing bootloader in the process. (CAN your bootloader boot their Linux and Windows as well?)

Virtually all Linux boxes have GRUB installed. Those who haven't will find plenty of documentation and help online, plus the reassurance that "this thing actually works as advertised".

And it will be much easier to convince someone to free a partition, install GRUB, and switch between your OS and their usual OS -- than convincing them to hand you the whole boot process. For safety, security, and other concerns.

The habitat of the hobby OS is a partition, not the whole hard drive. 8)

_________________
Every good solution is obvious once you've found it.


Top
 Profile  
 
 Post subject: Re: My bootloader crashes while reading the root directory
PostPosted: Thu Jan 11, 2018 11:31 am 
Offline
Member
Member
User avatar

Joined: Fri Feb 17, 2017 4:01 pm
Posts: 641
Location: Ukraine, Bachmut
I am about UEFI again and again. :) What is not very cool for me in things like GRUB (and MS does a very similar thing*) is that they duplicate functionality of the Boot Manager. It's it that should let people choose what they want to boot. It draws display, shows all possibilities for a user - where to boot from, what to configure etc. This is boot options and UI. Behind every boot option, some kind of bootloader should stand. And it should only do what is needed for this boot option (using FW interfaces and protocols, which simplifies a lot for it). It could be a "food processor" loader dealing with a bunch of options, but only this way - at the per option basis. Not intercepting control from FW and then deploying its monstrousity with even uglier than that of FW interface, demanding special partitions, its own half assed protocols, noone needs, for doing nothing more than the Boot Manager could do.
It's sad that instead of just supplying an easy efi app for loading their OS, people keep using all that bloat.

* - MS even calls this "Boot Manager" to add to the clarity. :lol:

_________________
ANT - NT-like OS for x64 and arm64.
efify - UEFI for a couple of boards (mips and arm). suspended due to lost of all the target park boards (russians destroyed our town).


Top
 Profile  
 
 Post subject: Re: My bootloader crashes while reading the root directory
PostPosted: Thu Jan 11, 2018 4:10 pm 
Offline
Member
Member
User avatar

Joined: Sun Jan 13, 2013 6:24 pm
Posts: 90
Location: Grande Prairie AB
I think what may need to be considered here is the impetus behind this question. Just a quick peruse of github and I found 5 incarnations of this code that were very similar to what was posted here. Even one where readSectors was identical other than it would eventually exit and stack operations were balanced.

Everything about this points toward being an assignment and that seems to be what a lot of posters lean toward, is trying to make it sound like they're into OS development. Fact is, nobody that is serious about OS development is going to screw around with floppies, much less FAT anything.
Mohamed007 wrote:
I tried as hard as i can.

I can relate to that, but as there are so many working invocations of FAT12, why are beating your head against the wall. You can even get preassembled images of FAT12, that all you'd have to do is copy it into sector 0 and your good to go.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: cloudapio, ErenJaeger, Majestic-12 [Bot] and 144 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group