Page 4 of 4

Re: booting FAT12 revisited

Posted: Thu Mar 11, 2021 3:19 pm
by Schol-R-LEA
Octocontrabass wrote:Is CS 0?
Yes. I've confirmed this by adding a redirect FAR jump to the start: label to force CS to zero. I behaves the same as before, going through everything and jumping to the second stage correctly.

Code: Select all

;;; entry - the entrypoint to the code. Make a short jump past the BPB.
entry:
        jmp short redirect
        nop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; FAT12 Boot Parameter Block - required by FAT12 filesystem

boot_bpb:
%include "fat-12-data.inc"

redirect:
        jmp boot_base:start


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; start
;;; This is the real beginning of the code. The first order of
;;; business is clearing the interrupts, then setting the
;;; segment registers and the stack pointer.  

start:
Where

Code: Select all

;;; constants
boot_base                 equ 0x0000      ; the segment base:offset pair for the
boot_offset               equ 0x7C00      ; boot code entrypoint

Re: booting FAT12 revisited

Posted: Thu Mar 11, 2021 6:03 pm
by Octocontrabass
At this point I'm not sure what else to suggest without debugging it myself. Got a disk image? (I don't have Linux installed anywhere convenient for building it.)

Re: booting FAT12 revisited

Posted: Thu Mar 11, 2021 7:19 pm
by Schol-R-LEA
Octocontrabass wrote:At this point I'm not sure what else to suggest without debugging it myself. Got a disk image? (I don't have Linux installed anywhere convenient for building it.)
Yes, I've attached what should be a suitable .ZIP archive. Note that I've been expanding upon the stage two code, but that shouldn't interfere with debugging the boot loader itself.

Re: booting FAT12 revisited

Posted: Thu Mar 11, 2021 8:51 pm
by Octocontrabass
It's amazing the things you don't see until you're stepping through it in a debugger.

This does not match this.

Re: booting FAT12 revisited

Posted: Thu Mar 11, 2021 9:25 pm
by Schol-R-LEA
Octocontrabass wrote:It's amazing the things you don't see until you're stepping through it in a debugger.

This does not match this.
Image

Yeah, that would definitely be a problem. Changing to .SYS across the board seems to resolve the issue.

Re: booting FAT12 revisited

Posted: Fri Mar 12, 2021 11:13 am
by Schol-R-LEA
Now that my first stage boot loader seemed to be working (emphasis on 'seemed'), I turned my attention to the second stage, which I intend to take the steps needed to load a 32-bit ELF kernel and switch to protected mode before jumping to said kernel.

At the moment, my focus is on activating the A20 Gate, and I have been following the approaches given in that page. However I came across an odd problem.

I have a number of messages which are meant to print as the activation proceeds, but as I added code to the second stage, these messages seemed to disappear, in reverse order of their definition.

What appears to be happening is that only the first sector of the second stage is actually being loaded. Since the print routine expects a null-delimited string, once it hits a 'string' which is zeroed out, the printing silently fails.

@Octocontrabass, could you please tell me what you used for debugging the real mode code? I don't really have any tool suitable for that right now.

Re: booting FAT12 revisited

Posted: Fri Mar 12, 2021 12:53 pm
by Octocontrabass
I used the Bochs built-in debugger.

QEMU with GDB would have worked too.

Re: booting FAT12 revisited

Posted: Sun Mar 14, 2021 9:45 pm
by Schol-R-LEA
Unfortunately, I am for some reason having a lot of trouble getting Bochs to run from my image files at all, and I am pretty sure that using GDB with QEMU would only work for p-mode or long mode code (though I haven't checked).

I was trying fix the issue with the second stage loader only loading the first sector, and in the process made several changes which broke it further. I did eventually push the modified code to the repo, but I am not sure at this point if it makes sense to roll back a few days and simply lose the work I've done since the last mostly-working version, or if I can salvage the redesigns I've been working on since my last post in this thread.

The main problem right now seems to be in the routine fat_to_file, but I cannot for the life of me figure out where it is breaking, or why.

Re: booting FAT12 revisited

Posted: Sun Mar 14, 2021 11:54 pm
by Octocontrabass
Schol-R-LEA wrote:I am pretty sure that using GDB with QEMU would only work for p-mode or long mode code (though I haven't checked).
It works, but you have to tell it that you're running 16-bit code.
Schol-R-LEA wrote:The main problem right now seems to be in the routine fat_to_file, but I cannot for the life of me figure out where it is breaking, or why.
The first sector of the data area is the first sector of cluster 2, you need to take that into account when calculating the LBA. You need to keep track of the cluster number so you can look up the next cluster in the FAT. You need to calculate the LBA from the cluster on each loop iteration.

This magic number is the number of sectors per cluster, right? (Although on a floppy disk, multi-sector reads can be problematic if they happen to cross a track or cylinder boundary...)

If part of a file happens to occupy LBA 0xFFFE, you'll stop reading there. (But a floppy disk doesn't have that many sectors.)

The cluster number in the FAT is the cluster you want to read.

This function clobbers SI, but you didn't document it.

Re: booting FAT12 revisited

Posted: Mon Mar 15, 2021 1:53 am
by iansjack
SimNow from AMD is also good for debugging real mode code.

Re: booting FAT12 revisited

Posted: Mon Mar 15, 2021 11:07 am
by Schol-R-LEA
EDIT: I ended up moving the recent changes to a branch and reverting the master branch to the last semi-working version.
Octocontrabass wrote: This magic number is the number of sectors per cluster, right? (Although on a floppy disk, multi-sector reads can be problematic if they happen to cross a track or cylinder boundary...)
Actually, it is the number of clusters (or at least sectors, but for a floppy disk those are equivalent) to read from the given LBA location. One of the changes I made was to make read_LBA_sector (now read_LBA_sectors) able to read multiple sectors at once. I did not take the cross-track boundaries into account, however, which could be part of the problem - thank you for pointing that out.
Octocontrabass wrote:If part of a file happens to occupy LBA 0xFFFE, you'll stop reading there. (But a floppy disk doesn't have that many sectors.)
True, but as you said, this won't apply to a floppy, and I have decided to forego any further versions of this boot loader for larger disks. I have concluded that using FAT with a hard drive image using legacy BIOS would not be worth the effort, even as an exercise.
/headdesk OK, that's a rather absurd error on my part, I'm not sure just how I ended up doing that. I have been getting turned around in my own code.
OK, good point, I will add that to the function documentation, or possibly find a way to avoid this problem.

Re: booting FAT12 revisited

Posted: Mon Mar 15, 2021 2:43 pm
by Octocontrabass
Schol-R-LEA wrote:EDIT: I ended up moving the recent changes to a branch and reverting the master branch to the last semi-working version.
This earlier version of the code looks a bit better.

You need to preserve BX since it's a parameter to extract_next_fat12_entry. You need to increment the buffer address on each iteration of the loop.

Perhaps you wanted CMP/JAE instead of TEST/JZ here? Most clusters will have at least one of the bits in the mask set. (And while I'm at it, the "end of cluster" values are 0xFF8 through 0xFFF; 0xFF0 to 0xFF6 are valid cluster numbers. Of course a floppy disk will not have that many clusters.)

This function still clobbers the pointer to its buffer without documenting it, and fat_to_file doesn't preserve the pointer either.

Re: booting FAT12 revisited

Posted: Tue Mar 16, 2021 2:08 pm
by Schol-R-LEA
I've done that now.
Octocontrabass wrote:You need to increment the buffer address on each iteration of the loop.
OK, I could have sworn I was doing that, but you're right, I did need to fix that.
Octocontrabass wrote:Perhaps you wanted CMP/JAE instead of TEST/JZ here? Most clusters will have at least one of the bits in the mask set.
That's odd; you're right in pointing that out, but when I change it to your suggested comparison, the loop never terminates. I seem to recall that I had tried something like that earlier which hadn't worked, and I had thrashed about a bit before trying to use TEST, which seemed to work. Clearly, it wasn't really working at all.
Octocontrabass wrote: (And while I'm at it, the "end of cluster" values are 0xFF8 through 0xFFF; 0xFF0 to 0xFF6 are valid cluster numbers. Of course a floppy disk will not have that many clusters.)
I'm not sure if that had been a typo, or if I was simply confused at the time - probably the latter - but thank you for pointing that out.
I've guarded the changes to DI with a push/pop pair, which isn't really how I'd like to do it, but it should do the trick.

Re: booting FAT12 revisited

Posted: Mon Mar 22, 2021 9:56 am
by Schol-R-LEA
Just as a quick update, the boot loader does seem to be working now, and I have pushed the working version to the experiment2 branch. I'll merge it to the Master branch shortly.