BootLoader 4

If you are new to OS Development, plan on spending some time here first before going into the other forums.

Moderator:Moderators

Post Reply
Zig
Posts:10
Joined:Fri Feb 20, 2009 11:58 pm
BootLoader 4

Post by Zig » Thu Mar 05, 2009 8:06 am

hi guys,


As I promised from the other post, here are questions for bootloader 4.


1. We're trying to get to the start of the root directory. And this is the piece of code Mike wrote

Code: Select all

LOAD_ROOT:
     
     ; compute size of root directory and store in "cx"
     
          xor     cx, cx
          xor     dx, dx
          mov     ax, 0x0020                               ; 32 byte directory entry
          mul     WORD [bpbRootEntries]                    ; total size of directory
          div     WORD [bpbBytesPerSector]                 ; sectors used by directory
          xchg    ax, cx
          
     ; compute location of root directory and store in "ax"
     
          mov     al, BYTE [bpbNumberOfFATs]                ; number of FATs
          mul     WORD [bpbSectorsPerFAT]                   ; sectors used by FATs
          add     ax, WORD [bpbReservedSectors]             ; adjust for bootsector
          mov     WORD [datasector], ax                     ; base of root directory
          add     WORD [datasector], cx
          
     ; read root directory into memory (7C00:0200)
     
          mov     bx, 0x0200                                ; copy root dir above bootcode
          call    ReadSectors
As I understand, when we get to the line

Code: Select all

add ax, WORD [bpbReservedSectors]
, we already are at the start of the root directory. So what do the last 2 line do? If we add the start of the root with the length of it (stored in cx), shouldnt we be at the end of the root directory?

2. with the piece of code that find stage 2

Code: Select all

    ;----------------------------------------------------
     ; Find stage 2
     ;----------------------------------------------------

     ; browse root directory for binary image
          mov     cx, [bpbRootEntries]                ; the number of entrys. If we reach 0, file doesnt exist
          mov     di, 0x0200                          ; Root directory was loaded here
     .LOOP:
          push    cx
          mov     cx, 11                              ; eleven character name
          mov     si, ImageName                       ; compare the 11 bytes with the name of our file
          push    di
     rep  cmpsb                                       ; test for entry match
          pop     di
          je      LOAD_FAT                            ; they match, so begin loading FAT
          pop     cx
          add     di, 32                              ; they dont match, so go to next entry (32 bytes)
          loop    .LOOP
          jmp     FAILURE         
I thought we need to use "repe cmpsb" rather than "rep cmpsb". If we use "rep cmpsb", and after letting it run for 11 times, the flags just actually store the value of the last comparation?

Sorry guys, I know I know I am a pain. Bear with me plz. And sorry for quoting lots of the codes here, that makes it so messy

Thank guys

Andyhhp
Moderator
Posts:387
Joined:Tue Oct 23, 2007 10:05 am
Location:127.0.0.1
Contact:

Post by Andyhhp » Thu Mar 05, 2009 8:51 pm

1) At that point, you have worked out how many sectors the two (usually) FATs take up. However, the FATs are located at a certain number of sectors after the bootloader sector.

As a result, there is a parameter in the BPB that basically gives the sector offset of the first FAT - this being the bpbReservedSectors parameter. The bpbReservedSectors must be at least 1 to account for the bootsector, plus any extra reserved sectors you might want. In our case, the number of reserved sectors on top of the bootsector is 0 so the bpbReservedSectors value is mearly 1.

So overall, you are calculating the position of the root directory by finding the start of the FAT, then adding the total length of all the FATs, which gets you to the start of the Root Directory.

2) You have very good and correct point. It is a lucky quirk that it works.

According to the Intel documentation, certain versions of the 'rep' and 'repe' instructions have identical opcodes. The distinguishing feature is the command directly following it.

There are two subsets of the string commands (http://download.intel.com/design/proces ... 253667.pdf)
The REP prefix can be added to the INS, OUTS, MOVS, LODS, and STOS instructions, and the REPE, REPNE, REPZ, and REPNZ prefixes can be added to the CMPS and SCAS instructions. (The REPZ and REPNZ prefixes are synonymous forms of the REPE and REPNE prefixes, respectively.)
As a result, the specific command 'rep cmpsb' is not valid but has identical opcode to 'repe cmpsb'.

If you look at the disassembly of the bootloader binary, you will see that nasm automatically generates 'repe cmpsb' which results in the code working.

That is a point probably worth pointing out as a minor bugfix, even if it is just a matter of principle.


~Andrew
Image

Zig
Posts:10
Joined:Fri Feb 20, 2009 11:58 pm

Post by Zig » Thu Mar 05, 2009 9:10 pm

Thanks Andrew,

I was hoping you would answer :)

I understand that we need to work out how many sector teh 2 FAT take up.

I believe these do that

Code: Select all

  mov     al, BYTE [bpbNumberOfFATs]                ; number of FATs
          mul     WORD [bpbSectorsPerFAT]                   ; sectors used by FATs
now the number of sector is stored in ax,

Code: Select all

add     ax, WORD [bpbReservedSectors]             ; adjust for bootsector
this line basically give the total number of sectors the 2 FATs + reserved sectors

we have

[boot sector] [reserved sectors] [FAT 1] [FAT 2] [Root Directory] [...]

we know how many sectors this has

so if we add that number with 1 (the boot sector), I think we get the the start of the rrot directory. (that where we want to get to)


The last 2 lines confuse me

Code: Select all

          mov     WORD [datasector], ax                     ; ax = nomber fo sectors reserved sectors] [FAT 1] [FAT 2]
          add     WORD [datasector], cx			    ; cs = size of the root directory
by adding it, are we get to

[boot sector] [reserved sectors] [FAT 1] [FAT 2] [Root Directory] [...]
We are at the end of the root directory

:(

Andyhhp
Moderator
Posts:387
Joined:Tue Oct 23, 2007 10:05 am
Location:127.0.0.1
Contact:

Post by Andyhhp » Thu Mar 05, 2009 9:21 pm

Ahh - misunderstood your question.

Those last 2 lines are storing the start of the data sector for later use. The first bit of code

Code: Select all

     ; compute size of root directory and store in "cx"
     
          xor     cx, cx
          xor     dx, dx
          mov     ax, 0x0020                               ; 32 byte directory entry
          mul     WORD [bpbRootEntries]                    ; total size of directory
          div     WORD [bpbBytesPerSector]                 ; sectors used by directory
          xchg    ax, cx 
computes the length of the root directory. Despite the fact we are trying to search the root directory, this code is here to help us later on when locating the file.

As a result, those last two lines you are refering to are storing the first sector on the data sector so, when we have located a file, we can start loading it without having to do any more calculations (ish).


Hope this makes some sense

~Andrew
Image

Zig
Posts:10
Joined:Fri Feb 20, 2009 11:58 pm

Post by Zig » Thu Mar 05, 2009 9:29 pm

:o as always, got it now. Thanks Andrew

Post Reply