OSDev.org https://forum.osdev.org/ |
|
My bootloader crashes while reading the root directory https://forum.osdev.org/viewtopic.php?f=1&t=32682 |
Page 1 of 1 |
Author: | Mohamed007 [ Thu Jan 11, 2018 2:20 am ] |
Post subject: | My bootloader crashes while reading the root directory |
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. 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? |
Author: | Solar [ Thu Jan 11, 2018 3:33 am ] |
Post subject: | Re: My bootloader crashes while reading the root directory |
At StackOverflow, I'd make the following remarks:
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.
|
Author: | Mohamed007 [ Thu Jan 11, 2018 3:56 am ] |
Post subject: | Re: My bootloader crashes while reading the root directory |
Solar wrote: At StackOverflow, I'd make the following remarks:
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. |
Author: | Solar [ Thu Jan 11, 2018 4:03 am ] |
Post subject: | Re: My bootloader crashes while reading the root directory |
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.) |
Author: | alexfru [ Thu Jan 11, 2018 4:52 am ] |
Post subject: | Re: My bootloader crashes while reading the root directory |
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. |
Author: | TightCoderEx [ Thu Jan 11, 2018 8:55 am ] |
Post subject: | Re: My bootloader crashes while reading the root directory |
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. |
Author: | Solar [ Thu Jan 11, 2018 10:10 am ] |
Post subject: | Re: My bootloader crashes while reading the root directory |
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:
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. |
Author: | zaval [ Thu Jan 11, 2018 11:31 am ] |
Post subject: | Re: My bootloader crashes while reading the root directory |
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. |
Author: | TightCoderEx [ Thu Jan 11, 2018 4:10 pm ] |
Post subject: | Re: My bootloader crashes while reading the root directory |
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. |
Page 1 of 1 | All times are UTC - 6 hours |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |