Mohamed007 wrote:I wrote a simple bootloader and i tried it and it works very well but when i copy 2 files to the floppy drive the bootloader failed to catch the kernel I copy the kernel.bin file to the floppy drive then write the bootloader to the bootsector using debug command.
And this is the root directory and FAT setup, what's wrong?
How do you know it works very well with no files on the disk. You state that it doesn't work as soon as you copy a file (or two). Are there already files on the disk and then you try to copy your kernel.bin file to the disk, replacing an existing one? Do I take it as when you replace an existing kernel.bin file with a new one, then it stops working as expected? If this is the case, this would give a clue.
Anyway, my comments are as follows:
Code: Select all
;;; this assumes DS has been set up and usable.
MOV [BOOT_DEVICE], DL
;1- SETTING UP AND LOADING THE ROOT DIR.
MOV AH, 02H ;;; ah = read service
MOV AL, 14 ;;; al = count of sectors
MOV BX, TEMP ;;; offset to place read sector(s) (assumes ES has been set and usable)
MOV CH, 0 ;;; 7:0 of cylinder (first cylinder)
MOV CL, 2 ;;; 7:6 = 9:8 of cylinder, 5:0 are sector (2nd sector since sectors are 1 based)
MOV DH, 1 ;;; head (second head)
;;; so this means that, assuming 18 sectors per track, you are reading from LBA 19, yes?
;;; the second sector from the second side on track/cyl 0?
;;; how do you know the root directory starts there?
;;; Boot Sector = 1, FAT = 9, 2 FAT's
;;; ...okay LBA 19 it is.
;;; since the BIOS won't read past a 64k boundary *and* will probably error if (BX + (AL * 512)) > 0xFFFF
;;; what combination does your ES:BX hold?
PUSHA
;;; In my opinion, rather than PUSHA, why not just jump back up to ";1- SETTING UP...". Time is not
;;; really and issue here and you won't have to worry about restoring the stack later.
LOAD_RD:
INT 13H
JNC LOAD_RD_DONE
CALL RESET_DRIVE
;;; You might want to have a count down and then error if it is reached. If there is an error,
;;; you will infinitely loop here...
JMP LOAD_RD
LOAD_RD_DONE:
POPA
MOV DI, TEMP
MOV CX, 224
FIND_KERNEL:
PUSH CX
POP DX
;;; MOV DX,CX instead???
MOV SI, FILE_NAME
MOV CX, 11
REP CMPSB
;;; are ES and DS set correctly before the CMPSB above?
;;; for readability, maybe use 'REPZ' instead.
;;; Also, to come back to the clue I first stated above, what OS are you using to copy the
;;; files to the floppy? Does it use Long File Names? If so, they are probably lowercase
;;; now, where your FILE_NAME will probably be uppercase.
;;; (Note though that an uppercase entry will still exist)
JE FOUND_KERNEL
ADD AX, 32
MOV DI, TEMP
ADD DI, AX
PUSH DX
POP CX
LOOP FIND_KERNEL
;;; Since you are using the stack, I would suggest you save DI and add 32 to DI each
;;; time. Saves you a bit of code here.
; mov cx,224
; find_kernel:
; push di
; push cx
; mov si,file_name
; mov cx,11
; repz cmpsb
; pop cx
; pop di
; jz found_kernel
; add di,32
; loop find_kernel
MOV SI, FAILED_TO_LOAD_KERNEL
CALL ECHO
CLI
INT 18H
FOUND_KERNEL:
MOV AX, WORD [DI+15]
MOV [ENTERY_POINT], AX
;;; Just out of curiousity, what assembler are you using.
;;; Without sounding like I am pushing my assembler, I want to show you something.
;;; (I think FASM does this too)
;;;
;;; With NBASM, you can do the following:
;;; ASTRUCT struct
;;; member0 word
;;; member1 byte
;;; ...
;;; member6 dword
;;; ASTRUCT ends
;;;
;;; mov ax,word [DI+ASTRUCT->member0]
;;;
;;; which is the equivalent of
;;;
;;; mov ax,word [DI+0]
;;;
;;; now you can modify ASTRUCT as you wish and all of your code reflect the
;;; change without a single modification. I thing FASM does it like this:
;;;
;;; mov ax,word [DI+ASTRUCT.member0]
;;;
;;; anyway, this is a lot better to read than [DI+15] if you give the members
;;; descriptive names. For example, the word at offset 15 is not an entry point
;;; as your code above assumes it is. You probably want the word at 0x1A.
;;;
;;; my version of the loop above leave DI pointing to the start of the Directory Entry.
;;; yours does not. Is this why you use '+15' instead?
;;; If found, DI = (start of entry + 11). 11 + 15 = 26 (0x1A). Yep :-)
;;; I suggest you change that. Makes for bad assumptions...
MOV AX, 1
MOV BX, TEMP
CALL LOG_TO_HTS
;;; This is usually called LBA to CHS, not LOG to HTS (Head Track Sector?)
;;; Also, you use this conversion here (which I assume converts an LBA to CHS, i haven't
;;; gotten to the code below yet), why didn't you use it above at ";1- SETTING UP ..."
MOV AH, 2
MOV AL, 9
PUSHA
LOAD_FAT:
INT 13H
JNC LOAD_FAT_DONE
CALL RESET_DRIVE
JMP LOAD_FAT
LOAD_FAT_DONE:
;;; a comment: As soon as you have read the FAT to the memory pointed to by TEMP,
;;; you have overwritten your DIRectory ENTRY data. Except for assuming that you will
;;; stop reading at the first End of Cluster marker, how do you know how many bytes in
;;; size your kernel is.
MOV AH, 2
MOV AL, 1
PUSH AX
LOAD_SECTOR:
MOV AX, WORD [ENTERY_POINT]
ADD AX, 31
;;; 31 may be in error. Most 1.44 meg floppies are:
;;; 1 = boot sector, 9 + 9 = FAT, 14 = root
;;; that is 33. However, maybe you are accounting for the "LBA-2" before hand... ?
;;; (cutting corners is going to leave you with a round square really fast...)
;;; Am I missing some code here. You get to the point to read in the kernel file
;;; and you now convert AX to CHS and return.
LOG_TO_HTS:
PUSH BX
PUSH AX
MOV BX, AX
MOV DX, 0
DIV WORD[ALL_SECTORS]
ADD DL, 01H
MOV CL, DL
MOV AX, BX
MOV DX, 0
DIV WORD [ALL_SECTORS]
MOV DX, 0
DIV WORD[FACES]
MOV DH, DL
MOV CH, AL
POP AX
POP BX
MOV DL, BYTE [BOOT_DEVICE]
RET
;;; (I didn't check your LBA->CHS code above).
Can you please include your whole boot sector (loader) code so that we can see the setting of ES and DS too, among other things?
I hope my comments/suggestions have helped you a bit. Be sure to spend some time re-writing your code and see if it works. If not, come back and ask us again, this time (please) giving more details.
Thanks,
Ben
P.S. FASM can be found at
http://flatassembler.net/ while NBASM can be found at
http://www.fysnet.net/newbasic.htm.