flat assembler
Message board for the users of flat assembler.

Index > Main > [RESOLVED]: HOW TO LOAD A FILE INTO MEMORY??

Author
Thread Post new topic Reply to topic
delta67



Joined: 18 Jul 2012
Posts: 19
delta67
Hi all,
I want to load a file "MYFILE.EXT" from floppy into memory at adress "0000:XXXX".
We assume the following:
- The 14 sectors of root directory are loaded at adress "0000:YYYY".
- The 9 sectors of FAT table are loaded at adress "0000:ZZZZ".
1) How to search for the NAME of myfile into root directory and define it's size and it's first sector?
2) How to load it into memory at adress "0000:XXXX"?

many thanks


Last edited by delta67 on 17 Aug 2012, 13:01; edited 1 time in total
Post 15 Aug 2012, 09:14
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
delta67,
  1. Do yourself a favor and read the specification for the FAT file system. ;-)
  2. Scan that root directory for pattern like "MYFILE__EXT" (here underscore denote space symbol, i.e. codepoint 0x20) at addresses like 0:YYYY+0x20*i for i in [0, 16*14).
  3. At the particular offsets from the match you'll find just everything you'd know about that file (e. g. its size and starting cluster number).
  4. Given the starting cluster number, you'll proceed to parse FAT (it's already "File Allocation Table", hence "FAT table" is misleading somewhat -- if it's so fat, pineapples may help ;-). Since you've mentioned 14 sectors per root, it's FAT12 probably, then some nibble fiddling can help.
  5. After determining the file extents' locations you may actually read its content. Even load it to 0:XXXX ;-)
Post 15 Aug 2012, 20:16
View user's profile Send private message Reply with quote
delta67



Joined: 18 Jul 2012
Posts: 19
delta67
baldr wrote:
delta67,
  1. Do yourself a favor and read the specification for the FAT file system. Wink
  2. Scan that root directory for pattern like "MYFILE__EXT" (here underscore denote space symbol, i.e. codepoint 0x20) at addresses like 0:YYYY+0x20*i for i in [0, 16*14).
  3. At the particular offsets from the match you'll find just everything you'd know about that file (e. g. its size and starting cluster number).
  4. Given the starting cluster number, you'll proceed to parse FAT (it's already "File Allocation Table", hence "FAT table" is misleading somewhat -- if it's so fat, pineapples may help Wink. Since you've mentioned 14 sectors per root, it's FAT12 probably, then some nibble fiddling can help.
  5. After determining the file extents' locations you may actually read its content. Even load it to 0:XXXX Wink


Thanks baldr for ur reply.
Yes, I'm reading the FAT specs. Now, I can search for "MYFILE EXT" and define it's first cluster:

Code:

     ; browse root directory for MYFILE.EXT
         mov   cx, 224                 ;  loop counter
       mov  di, YYYY                 ; locate first root entry
     .LOOP:
          push  cx
    mov  cx, 0x000B               ; eleven character name
       mov si, FileName              ; image name to find
          push di
          rep  cmpsb                       ; test for entry match
        pop     di
          je      FOUND                 ; file founded
        pop     cx
          add     di, 0x0020            ; queue next directory entry
          loop    .LOOP
       jmp     not_found             ; not founded



  

   FOUND:  ;file found
  
         add di,1Ah                       ;point at first cluster number
  
         mov ax,[di]                     ;ax - number of the first cluster
         .........
        ????TODO ????
         ........
    


Last edited by delta67 on 16 Aug 2012, 06:56; edited 1 time in total
Post 15 Aug 2012, 23:33
View user's profile Send private message Reply with quote
delta67



Joined: 18 Jul 2012
Posts: 19
delta67
How to use the FAT table to find the sectors of "MYFILE" and load them in memory?
I use FAT12.
Post 15 Aug 2012, 23:35
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
delta67,

FAT can be interpreted as a linked list (actually a collection of lists): FAT[cluster_number] is a number of the next cluster allocated for the file, unless it's a special value denoting the end of list. There are special lists, notably (0), the unallocated cluster, and (0xFF7), cluster containing bad sector(s).

Anyway, fatgen103.doc gives most of the technicalities related to the FAT FS.

Also, you may find OS Construction useful, scan/search it for bootloaders. There is some meat for Google to chew, especially OSDev.org. Alex Frounze wrote pretty bootprog that properly loads and starts .Com/.Exe files.
Post 16 Aug 2012, 12:27
View user's profile Send private message Reply with quote
delta67



Joined: 18 Jul 2012
Posts: 19
delta67
Thanks a lot baldr for the links.
I'm progressing ............. !!!
Post 16 Aug 2012, 16:33
View user's profile Send private message Reply with quote
delta67



Joined: 18 Jul 2012
Posts: 19
delta67
PROBLEM RESOLVED
Finally I get the working code to load a file in memory WOOOOOWWW!!
Thanks baldr and others.
Here is the code I use with my 8088 SBC:

Code:


;*********************************************
;       A Simple FAT12 Bootloader
;*********************************************

use16                                            ; we are in 16 bit real mode

org 7C00h                                   ; This code is loaded at 0000:7C00h     

start:  jmp     main                    ; jump to start of bootloader
               nop                     ; BPB Begins 3 bytes from start.
                                    ; If you use a short jump, add a "nop" after it to offset the 3rd byte.
                                   ;  or do a far jump, which is 3 bytes in size.

;*********************************************
;       BIOS Parameter Block  "BPB"
;*********************************************
bpbOEM                               db "My OS   "                 ; OEM identifier (Cannot exceed 8 bytes!)
bpbBytesPerSector:     DW 512
bpbSectorsPerCluster:     DB 1
bpbReservedSectors: DW 1                                    ; Only the boot sector
bpbNumberOfFATs:  DB 2
bpbRootEntries:     DW 224
bpbTotalSectors:  DW 2880
bpbMedia:                        DB 0xf8  
bpbSectorsPerFAT:      DW 9
bpbSectorsPerTrack: DW 18
bpbHeadsPerCylinder:       DW 2
bpbHiddenSectors:   DD 0
bpbTotalSectorsBig: DD 0
bsDriveNumber:              DB 0
bsUnused:                   DB 0
bsExtBootSignature: DB 0x29
bsSerialNumber:  DD 0xa0a1a2a3
bsVolumeLabel:             DB "MOS FLOPPY "
bsFileSystem:         DB "FAT12   "

;**********************************************

main:

;load FAT into memory

    mov ax,1                ; First copy of FAT  satrts at sector Nbr 1
 call LBACHS
 mov ah,2
    mov al,9                ; FAT length is 9 sectors
   mov bx,3FFFh            ; we load FAT at 0000:3FFFh
     int 13h

;load root 
  
    mov ax,19               ; ROOT dir starts at sector 19
      call LBACHS
 mov ah,2
    mov al,14               ; and it is 14 sectors length
       mov bx,500h             ; we load ROOT  at 0000:0500h
   int 13h

; browse root directory for "KERNEL.BIN"
   mov       cx, 224               ;  loop counter(Nbr of entries)
     mov       di, 500h              ; locate first root entry
Next_Entry:
        push      cx
        mov       cx, 0x000B    ; eleven characters name
    mov       si, FileName  ; File name to find
 push      di
    rep  cmpsb                  ; test for entry match
      pop       di
        je        found                 ; file found
        pop       cx
        add       di, 0x0020    ; ( di +32) = queue next directory entry
    loop      Next_Entry  ; LOOP instrcution decrements CX, so if CX =/= 0  we continue searching
       jmp       not_found             ; Else, file not found
        
found:
            ; di = entry of our file, so  we add 1Ah to point first byte (byte 26) of file's first cluster Nbr
 mov ax, word [di + 1Ah] ; get Nbr of first cluster (word)
   mov bx, 500h            ; we load our file at 0000:0500h

load_file:
  push ax
     call CLUST_LBA  ; convert cluster Nbr to LBA
        mov ax,0201h    ; read 1 sector
     int 13h                 ;load cluster (sector) into memory
  add bx,512              ; offset of next sector into memory
 
    ; compute next cluster Nbr
  ;In FAT12 3 bytes hold information about 2 clusters
 
    pop ax                  ; recover current cluster number
    push ax                 ; save again, we need it later
      mov cx,3
    mul cx                   ;multiply current cluster number by 3
      shr ax,1                 ;and divide by 2: Now ax = offset from begening of FAT
 mov si,ax               ;
   mov dx, word [si+3FFFh]  ; get word at that address
 pop ax                  ; recover current cluster number
    test ax,0x0001  ;odd cluster?  
     jz is_even              ; No, jump
  mov cl,4                ;yes, shift 4 bits right
    shr dx,cl                
   jmp result
is_even:
  and dx,0FFFh     ;no, and 0FFFh
result:
      mov ax,dx               ;result  (Nbr of next cluster) ----> ax
  cmp ax,0FF7h    ;if > 0FF7h, end reading
 ja DONE
     jmp load_file
  
DONE:

        jmp 0000:0500h       ;jump to 0000:0500 (where the file was loaded)


not_found:
       mov al, 0x3F
        out 0x01, al
        hlt
 
;---------------------------    
CLUST_LBA:  
    add ax, 31              ; Nbr of (logical) sector =  cluster + 31
LBACHS:
    push bx         ; We need bx in calculation here, so save it
  ; Calculate cylinder, head and sector:
  ; Cylinder = (LBA / SectorsPerTrack) / NumHeads
  ; Sector   = (LBA mod SectorsPerTrack) + 1
  ; Head     = (LBA / SectorsPerTrack) mod NumHeads
    
    mov       bx, 18        ;  sectors per track
        xor       dx, dx
    div       bx            ; Divide (dx:ax/bx to ax,dx)
                                ; Quotient (ax) =  LBA / SectorsPerTrack
                                    ; Remainder (dx) = LBA mod SectorsPerTrack
      inc       dx             ; Add 1 to remainder, since sector 
        mov       cl, dl         ; Store result in cl for int 13h call.
  
       mov       bx, 2          ;  number of heads
 xor       dx, dx
    div       bx             ; Divide (dx:ax/bx to ax,dx)
                                ; Quotient (ax) = Cylinder
                                  ; Remainder (dx) = head
        mov       ch, al         ; ch = cylinder                      
      xchg  dl, dh    ; dh = head number
  pop bx
      ret

;----------------------------
FileName db 'KERNEL  BIN'
    
       TIMES 510-($-$$) DB 0
       DW 0xAA55
    
Post 17 Aug 2012, 13:00
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
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 vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.