📄 fs_configfat.c
字号:
/**************************************************************************** * fs/fat/fs_configfat.c * * Copyright (C) 2008 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. Neither the name NuttX nor the names of its contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************//**************************************************************************** * Included Files ****************************************************************************/#include <nuttx/config.h>#include <sys/types.h>#include <string.h>#include <debug.h>#include <errno.h>#include <nuttx/fs.h>#include <nuttx/fat.h>#include <nuttx/mkfatfs.h>#include "fs_internal.h"#include "fs_fat32.h"#include "fs_mkfatfs.h"/**************************************************************************** * Definitions ****************************************************************************/#define NDX12 0#define NDX16 1#define NDX32 2#define fatconfig12 fatconfig[NDX12]#define fatconfig16 fatconfig[NDX16]#define fatconfig32 fatconfig[NDX32]/* JMP rel8 and NOP opcodes */#define OPCODE_JMP_REL8 0xeb#define OPCODE_NOP 0x90#define BOOTCODE_MSGOFFSET 29/**************************************************************************** * Private Types ****************************************************************************/struct fat_config_s{ uint32 fc_navailsects; /* The number of available sectors */ uint32 fc_nfatsects; /* The number of sectors in one FAT */ uint32 fc_nclusters; /* The number of clusters in the filesystem */ uint32 fc_rsvdseccount; /* The number of reserved sectors */};/**************************************************************************** * Private Data ****************************************************************************//* Reverse engineered, generic boot message logic for non-bootable disk. * Message begins at offset 29; Sector relative offset must be poked into * offset 3. */ static ubyte g_bootcodeblob[] ={ 0x0e, 0x1f, 0xbe, 0x00, 0x7c, 0xac, 0x22, 0xc0, 0x74, 0x0b, 0x56, 0xb4, 0x0e, 0xbb, 0x07, 0x00, 0xcd, 0x10, 0x5e, 0xeb, 0xf0, 0x32, 0xe4, 0xcd, 0x16, 0xcd, 0x19, 0xeb, 0xfe, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x20, 0x62, 0x6f, 0x6f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x2e, 0x20, 0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x61, 0x20, 0x62, 0x6f, 0x6f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x70, 0x70, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x0d, 0x0a, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e, 0x20, 0x2e, 0x2e, 0x2e, 0x0d, 0x0a, 0x00};/**************************************************************************** * Private Functions ****************************************************************************//**************************************************************************** * Name: mkfatfs_nfatsect12 * * Description: * Calculate the number of sectors need for one fat in a FAT12 file system. * * Input: * fmt - Caller specified format parameters * var - Other format parameters that are not caller specifiable. (Most * set by mkfatfs_configfatfs()). * navailsects - The number of sectors available for both FAT and data. * This is a precalculated value equal to the total number of sectors * minus the number of root directory sectors and minus the number of * reserved sectors. * * Return: * 0: That calculation would have overflowed * >0: The size of one FAT in sectors. * ****************************************************************************/static inline uint32mkfatfs_nfatsect12(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var, uint32 navailsects){#ifdef CONFIG_HAVE_LONG_LONG uint64 denom; uint64 numer;#else uint32 denom; uint32 numer;#endif /* For FAT12, the cluster number is held in a 12-bit number or 1.5 bytes per * cluster reference. So each FAT sector will hold sectorsize/1.5 cluster * references (except for the first sector of each FAT which has two reserved * 12-bit values). And the total number of FAT sectors needed is: * * nfatsects = (1.5 * (ndataclust + 2) / sectorsize) * * where: * * ndataclust = ndatasect / clustsize * nvailsects = nfatsects + ndatasect * * The solution to this set of linear equations is: * * nfatsects = (3 * navailsects + 6 * clustersize) / * (3 * nfats + 2 * sectorsize * clustersize) * * The numerator would overflow uint32 if: * * 3 * navailsects + 6 * clustersize > 0xffffffff * * Or * * navailsects > 0x55555555 - 2 * clustersize */#ifndef CONFIG_HAVE_LONG_LONG if (navailsects <= (0x55555555 - (1 << (fmt->ff_clustshift + 1)))) {#endif denom = (fmt->ff_nfats << 1) + fmt->ff_nfats + (var->fv_sectorsize << (fmt->ff_clustshift + 1)); numer = (navailsects << 1) + navailsects + (1 << (fmt->ff_clustshift + 2)) + (1 << (fmt->ff_clustshift + 1)); return (uint32)((numer + denom - 1) / denom);#ifndef CONFIG_HAVE_LONG_LONG } else { return 0; }#endif}/**************************************************************************** * Name: mkfatfs_nfatsect16 * * Description: * Calculate the number of sectors need for one fat in a FAT16 file system. * * Input: * fmt - Caller specified format parameters * var - Other format parameters that are not caller specifiable. (Most * set by mkfatfs_configfatfs()). * navailsects - The number of sectors available for both FAT and data. * This is a precalculated value equal to the total number of sectors * minus the number of root directory sectors and minus the number of * reserved sectors. * * Return: * The size of one FAT in sectors. * ****************************************************************************/static inline uint32mkfatfs_nfatsect16(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var, uint32 navailsects){#ifdef CONFIG_HAVE_LONG_LONG uint64 denom; uint64 numer;#else uint32 denom; uint32 numer;#endif /* For FAT16, the cluster number is held in a 16-bit number or 2 bytes per * cluster reference. So each FAT sector will hold sectorsize/2 cluster * references (except for the first sector of each FAT which has two reserved * 16-bit values). And the total number of FAT sectors needed is: * * nfatsects = (2 * (ndataclust + 2) / sectorsize) * * where: * * ndataclust = ndatasect / clustsize * nvailsects = nfatsects + ndatasect * * The solution to this set of linear equations is: * * nfatsects = (navailsects + 2 * clustersize) / * (nfats + sectorsize * clustersize / 2) * * Overflow in the calculation of the numerator could occur if: * * navailsects > 0xffffffff - 2 * clustersize */ if (fmt->ff_clustshift == 0) { denom = fmt->ff_nfats + (var->fv_sectorsize >> 1); numer = navailsects + 2; } else { denom = fmt->ff_nfats + (var->fv_sectorsize << (fmt->ff_clustshift - 1)); numer = navailsects + (1 << (fmt->ff_clustshift + 1)); } return (uint32)((numer + denom - 1) / denom);}/**************************************************************************** * Name: mkfatfs_nfatsect32 * * Description: * Calculate the number of sectors need for one fat in a FAT32 file system. * * Input: * fmt - Caller specified format parameters * var - Other format parameters that are not caller specifiable. (Most * set by mkfatfs_configfatfs()). * navailsects - The number of sectors available for both FAT and data. * This is a precalculated value equal to the total number of sectors * minus the number of root directory sectors and minus the number of * reserved sectors. * * Return: * The size of one FAT in sectors. * ****************************************************************************/static inline uint32mkfatfs_nfatsect32(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var, uint32 navailsects){#ifdef CONFIG_HAVE_LONG_LONG uint64 denom; uint64 numer;#else uint32 denom; uint32 numer;#endif /* For FAT32, the cluster number is held in a 32-bit number or 4 bytes per * cluster reference. So each FAT sector will hold sectorsize/4 cluster * references (except for the first sector of each FAT which has three reserved * 32-bit values). And the total number of FAT sectors needed is: * * nfatsects = (4 * (ndataclust + 3) / sectorsize) * * where: * * ndataclust = ndatasect / clustsize * nvailsects = nfatsects + ndatasect * * The solution to this set of linear equations is: * * nfatsects = (navailsects + 3 * clustersize) / * (nfats + sectorsize * clustersize / 4) * * Overflow in the 32-bit calculation of the numerator could occur if: * * navailsects > 0xffffffff - 3 * clustersize */ if (fmt->ff_clustshift == 0) { denom = fmt->ff_nfats + (var->fv_sectorsize >> 2); numer = navailsects + 3; } else if (fmt->ff_clustshift == 1) { denom = fmt->ff_nfats + (var->fv_sectorsize >> 1); numer = navailsects + 6; } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -