⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bbu_fat.s

📁 关于PXA310的最小系统的程序,初级学习阶段会有所帮助,汇编语言编写的
💻 S
📖 第 1 页 / 共 5 页
字号:
;*******************************************************************************
;
;     COPYRIGHT (C) 2007 Marvell International Ltd. All Rights Reserved.
;
;   The information in this file is furnished for informational use only,
;   is subject to change without notice, and should not be construed as
;   a commitment by Marvell. Marvell assumes no responsibility or liability
;   for any errors or inaccuracies that may appear in this software or any
;   documenation that may be provided in association with this software.
;
;*******************************************************************************
;
;                                 bbu_FAT.s
;     Subroutines to support File Allocation Tables and DOS-like directories
;     Only 8.3 format file names are supported since support for long file
;     names would require licensing from Microsoft.
;
;
BBU_FAT_BUFSZ   EQU     6       ; Should be a multiple of 3 - (Sector count) 3K
BBU_DIR_BUFSZ   EQU     8       ; Directory buffer size in sectors (4KB)
;
;  NOTE FAT Buffer size should be a multiple of 3 so FAT12 entries never span
;       a buffer boundry.
;

        GLOBAL  BBU_FAT_BOOT_SEC        ; Boot sector validate / decode routine
        GLOBAL  BBU_DISP_DIR            ; List the contents of the cur directory
        GLOBAL  BBU_FIND_FILE           ; Locate a file in the directory
        GLOBAL  BBU_FAT_NEXT_CLUS       ; Get the next cluster # in the file
        GLOBAL  BBU_READ_FILE           ; Read file (given cluster number)
        GLOBAL  BBU_SET_DIR             ; Set default directory
        GLOBAL  BBU_NAME_83             ; Format file/dir names in 8.3 format
;
;       Global variables
;
        GLOBAL  BBU_FAT_TYPE            ; FAT type saved here
        GLOBAL  BBU_SEC_CLUS            ; Sectors per cluster count

        EXTERN  BBU_MMC_Read            ; Read from the MMC
        EXTERN  BBU_putchr              ; Output a character to the UART
        EXTERN  BBU_putstr              ; Output an ASCII string to the UART
        EXTERN  BBU_crlf                ; New line
        EXTERN  BBU_UDecToAscii         ; Output a number in decimal format
        EXTERN  BBU_MMC_Read            ; Read from MMC device
        EXTERN  BBU_U32Divide           ; Unsigned 32-bit divide routine
        EXTERN  BBU_CMD_ASCII           ; Command ASCII string        

        AREA  |text|,CODE,READONLY

;
;*******************************************************************************
;
;       ********************
;       *                  * 
;       * BBU_FAT_BOOT_SEC * BBU FAT Boot Sector decode
;       *                  *
;       ********************
;
;       Checks to make sure a valid boot sector was read in and if so, saves
;       off various bits of information that will be referenced by other
;       subroutines in this file.
;
; PARAMETER PASSING:
;
;       INPUT:
;
;         r0 - Address where boot sector data starts in memory
;
;       OUTPUT:
;
;         r0 = 0xFF if an invalid boot sector was detected
;         r0 = size of device in bytes if no error
;
;
BBU_FAT_BOOT_SEC        FUNCTION

        stmfd   sp!,    {r1-r5, lr}     ; Save registers and link on the stack
;
;       First- zero out a few things
;
        mov     r1,     #0              ; Zero out a work register
        ldr     r2,     =BBU_VOL_SLBA   ; Starting Logical Block Address
        str     r1,     [r2]            ; Zero out this value
        ldr     r2,     =BBU_FAT_TYPE   ; Address of FAT type
        str     r1,     [r2]            ; Zero out this value
;
;       Read the boot block (sector) from a MMC device
;
        mov     r0,     #0              ; Specify sector #0 
2       ldr     r1,     =BBU_FAT_1      ; Buffer address
        bl      BBU_MMC_Read            ; Read the boot sector
        mov     r5,     r0              ; Copy return code to r5
        cmp     r0,     #0xFF           ; was an error detected?
        beq     %F9                     ; Yes - take the exit path
;
;       Check the code at the end of the sector for a valid boot sector ID
;
        ldr     r0,     =BBU_FAT_1      ; Specify the buffer address
        ldr     r2,     =0x1FE          ; Offset to boot sector ID code
        ldrh    r1,     [r0, r2]        ; Fetch end of boot sector code
        ldr     r2,     =0xAA55         ; End of boot sector ID code
        cmp     r1,     r2              ; Do they match?
        movne   r5,     #0xFF           ; No - load error code into r5
        bne     %F9                     ; ...and take the exit path
;
;       Valid ID found - Next see if this sector contains boot code or just a
;       partition table. BBU check the doubleword at offset 0x1B8 (just before
;       the partition table). If this is zero, a partition table is assumed.
;       If not, It's assumed all the volume information is in sector zero.
;
        ldr     r1,     [r0, #0x1B8]    ; Fetch the doubleword at offset 0x1B8
        cmp     r1,     #0              ; Is there any code here?
        beq     %F7                     ; No - search for a partition table
;
;       If the first doubleword is not zero, BBU assumes it's boot code and that
;       this sector contains information about the volume. In that case, the
;       code continues below.
;
        ldrb    r1,     [r0, #0xB]      ; Get bytes/sector (low byte)
        ldrb    r2,     [r0, #0xC]      ; Get bytes/sector (high byte)
        mov     r2,     r2,     LSL #8  ; Shift left 1 byte
        orr     r2,     r2,     r1      ; r2 = bytes per sector 
        ldr     r1,     =BBU_BYTE_SEC   ; Load address where this will be saved
        strh    r2,     [r1]            ; Save bytes/sector

        ldrb    r3,     [r0, #0xD]      ; Sectors per cluster
        ldr     r1,     =BBU_SEC_CLUS   ; Load address where this will be saved
        strb    r3,     [r1]            ; Save sectors/cluster

        ldrh    r3,     [r0, #0xE]      ; Reserved Sector Count
        ldr     r1,     =BBU_RES_SEC    ; Load address where this will be saved
        strh    r3,     [r1]            ; Save Reserved Sector Count

        ldrb    r3,     [r0, #0x11]     ; Max # root dir entries (low byte)
        ldrb    r4,     [r0, #0x12]     ; Max # root dir entries (high byte)
        mov     r4,     r4,     LSL #8  ; Shift left 1 byte
        orr     r3,     r3,     r4      ; Maximum # of root directory entries
        ldr     r1,     =BBU_ROOT_DIRE  ; Load address where this will be saved
        strh    r3,     [r1]            ; Save root directory entry count
        mov     r3,     r3,     LSR #4  ; LSR #4 to get # of root dir sectors
        ldr     r1,     =BBU_ROOT_SIZE  ; Number of root sectors is saved here
        strh    r3,     [r1]            ; Save the number of root sectors

        ldrh    r1,     [r0, #0x16]     ; Sectors per FAT (FAT12/FAT16)
        cmp     r1,     #0              ; Is this zero?
        ldreq   r1,     [r0, #0x24]     ; If zero, load from here (FAT32)
        ldr     r4,     =BBU_SEC_FAT    ; Load address where this will be saved
        str     r1,     [r4]            ; Save sectors per FAT

        ldrb    r3,     [r0, #0x13]     ; Total sectors (low byte)
        ldrb    r4,     [r0, #0x14]     ; Total sectors (high byte)
        mov     r4,     r4,     LSL #8  ; Shift left 1 byte
        orr     r3,     r3,     r4      ; Total sector count
        cmp     r3,     #0              ; Is this value zero?
        ldreq   r3,     [r0, #0x20]     ; If zero, get sector count from here
        ldr     r4,     =BBU_TOT_SEC    ; Load address where this will be saved
        str     r3,     [r4]            ; Save total sector count here
;
;       Figure out if this is a FAT12, FAT16 or a FAT32 volume. This is
;       determined by the count of clusters on the volume and NOTHING ELSE.
;       The formulas are:
;
;       CountofClusters = Data_sector_count / sectorsPerCluster
;
;       where
;
;       Data_sector_count = total sectors - (res_sec + FATsz*NumOfFATs + RtSEC)
;
;       Currently:
;
;       R0 = pointer to base of MBR
;       R1 = sectors per FAT
;       r2 = bytes per sector (leave this alone - it is used later)
;       R3 = total sector count
;
        ldrb    r4,     [r0, #0x10]     ; Get number of FAT tables (usually 2)
        mul     r1,     r1,     r4      ; R1 = sectors taken up by FATs
        ldrh    r4,     [r0, #0xE]      ; Get reserved sector count
        add     r1,     r1,     r4      ; ...and add this to r1
        ldr     r5,     =BBU_ROOT_SIZE  ; Number of root sectors was saved here
        ldrh    r4,     [r5]            ; Fetch this value
        add     r5,     r1,     r4      ; r5 = total of non-data sectors
        ldrb    r1,     [r0, #0xD]      ; Fetch Sectors per cluster       
        sub     r0,     r3,     r5      ; r0 = total # of data sectors
        mul     r5,     r2,     r3      ; r5 = total bytes on this volume/device
;
;       divide total data sector count (in r0) by sectors per cluster (in r1)
;       Count of clusters is then in r2
;
        bl      BBU_U32Divide           ; Divide. R2 = Count of Clusters
;
;       Volume = FAT12 if count of clusters is less than 4085
;       Volume = FAT16 if count of clusters 4085 to 65524
;       Volume - FAT32 if count of clusters is over 65524
;
        ldr     r1,     =4085   ; Xover point for FAT12/FAT16
        cmp     r2,     r1      ; Compare to count of clusters
        movlt   r0,     #12     ; If .LT. 4085, it's FAT12
        blt     %F5             ; ...and exit
        ldr     r1,     =65524  ; Xover point for FAT16/FAT32
        cmp     r2,     r1      ; Compare count of clusters
        movle   r0,     #16     ; 65524 orless= FAT16
        movgt   r0,     #32     ; Over 65524 = FAT32

5       ldr     r1,     =BBU_FAT_TYPE   ; Address of FAT type
        strb    r0,     [r1]            ; Save the FAT type here
;
;       Figure out sector offset to root directory and save this for later
;       reference & use.
;
        ldr     r4,     =BBU_RES_SEC    ; Address of reserved sector count
        ldrh    r0,     [r4]            ; Get reserved sector count
        ldr     r4,     =BBU_SEC_FAT    ; Sectors per FAT count
        ldr     r1,     [r4]            ; Get sectors per FAT count
        mov     r1,     r1,     LSL #1  ; Multiply by 2
        add     r0,     r0,     r1      ; r0 =sector offset to root directory

        ldr     r4,     =BBU_VOL_SLBA   ; Starting Logical Block Address
        ldr     r1,     [r4]            ; Get this value
        add     r0,     r0,     r1      ; Add to the root directory offset
        ldr     r1,     =BBU_ROOT_SECT  ; Location of root directory sector
        str     r0,     [r1]            ; Save this data
        mov     r0,     #0              ; Set default to root dir (cluster #0)
        bl      BBU_SET_DIR             ; Set it up

;
;       Load the 1st segment of the FAT into BBU's internal buffer
;
        mov     r0,     #0      ; Start at FAT offset zero
        bl      BBU_LOAD_FAT    ; Load the first part of the table
;
;       Calculate what the starting sector number for "cluster #0" would be
;       for this volume. This value will be used to with the FAT to figure
;       out what sectors to acess with reading/writing files. The data area
;       really starts at cluster #2 so cluster #0 is a "virtual cluster" to
;       take into account that the fist two cluster entries in the FAT are
;       ignored.
;
;        Currently this code only supports FAT12 and FAT16.
;
        ldr     r2,     =BBU_RES_SEC    ; Address of reserved sector count
        ldrh    r1,     [r2]            ; Get reserved sector count
        ldr     r2,     =BBU_SEC_FAT    ; Address of sectors/FAT count
        ldr     r3,     [r2]            ; Get sectors per FAT
        mov     r3,     r3,     LSL #1  ; Multiply by 2
        add     r1,     r1,     r3      ; R1 = reserved sectors + FAT sectors
        ldr     r2,     =BBU_ROOT_SIZE  ; Number of root sectors is saved here
        ldrh    r3,     [r2]            ; r1 = Size of root dir in sectors
        add     r1,     r1,     r3      ; r1 points to sector that starts data
        ldr     r2,     =BBU_SEC_CLUS   ; Address where sectors/cluster is kept
        ldrb    r3,     [r2]            ; Fetch this value
        mov     r3,     r3,     LSL #1  ; Multiply by 2
        sub     r1,     r1,     r3      ; r1 = sector offset of cluster zero
        b       %F9                     ; ...and exit
;
;       BBU branches here if the first doubleword of master boot record is zero.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -