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

📄 fatfs.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
📖 第 1 页 / 共 2 页
字号:
		/* Volume is FAT32 */		fsc->FatType = TYPE_FAT32;	}	return (1);}u_int32_t getFatEntry(struct fat_sc *fsc, int entry){	u_int32_t fatsect;	u_int32_t byteoffset;	u_int32_t fatstart;	u_int32_t fatoffset;	u_int8_t b1,b2,b3,b4;	int res;	fatstart = fsc->ResSectors;		if (fsc->FatType == TYPE_FAT12) {		int odd;		odd = entry & 1;		byteoffset = ((entry & ~1) * 3) / 2;		fatsect = byteoffset / SECTORSIZE;		fatoffset = byteoffset % SECTORSIZE;		if (fsc->FatCacheNum != fatsect) {			res = readsector(fsc, fatsect + fatstart, 1, fsc->FatBuffer);			if (res < 0) {				return res;			}			fsc->FatCacheNum = fatsect;		}				b1 = fsc->FatBuffer[fatoffset];				if ((fatoffset+1) >= SECTORSIZE) {			res = readsector(fsc, fatsect + 1 + fatstart, 1, fsc->FatBuffer);			if (res < 0) {				return res;			}			fsc->FatCacheNum = fatsect+1;			fatoffset -= SECTORSIZE;		}				b2 = fsc->FatBuffer[fatoffset+1];		if ((fatoffset+2) >= SECTORSIZE) {			res = readsector(fsc, fatsect + 1 + fatstart, 1, fsc->FatBuffer);			if (res < 0) {				return res;			}			fsc->FatCacheNum = fatsect + 1;			fatoffset -= SECTORSIZE;		}				b3 = fsc->FatBuffer[fatoffset+2];				if (odd) {			return ((unsigned int) b3 << 4) + ((unsigned int) (b2 & 0xF0) >> 4);		} else {			return ((unsigned int) (b2 & 0x0F) << 8) + ((unsigned int) b1);		}	} else if (fsc->FatType == TYPE_FAT16) {		byteoffset = entry * 2;		fatsect = byteoffset / SECTORSIZE;		fatoffset = byteoffset % SECTORSIZE;				if (fsc->FatCacheNum != fatsect) {			res = readsector(fsc, fatsect + fatstart, 1, fsc->FatBuffer);			if (res < 0) {				return res;			}			fsc->FatCacheNum = fatsect;		}		b1 = fsc->FatBuffer[fatoffset];		b2 = fsc->FatBuffer[fatoffset+1];		return ((unsigned int) b1) + (((unsigned int) b2) << 8);	} else if (fsc->FatType == TYPE_FAT32) {		byteoffset = entry * 4;		fatsect = byteoffset / SECTORSIZE;		fatoffset = byteoffset % SECTORSIZE;				if (fsc->FatCacheNum != fatsect) {			res = readsector(fsc, fatsect + fatstart, 1, fsc->FatBuffer);			if (res < 0) {				return res;			}			fsc->FatCacheNum = fatsect;		}		b1 = fsc->FatBuffer[fatoffset];		b2 = fsc->FatBuffer[fatoffset+1];		b3 = fsc->FatBuffer[fatoffset+2];		b4 = fsc->FatBuffer[fatoffset+3];		return (((unsigned int) b1) + (((unsigned int) b2) << 8) + (((unsigned int) b3) << 16) + (((unsigned int) b4) << 24));	}	return (0);}#define MAX_DIRBUF 10struct direntry dirbuf[MAX_DIRBUF];int fat_findfile(struct fat_sc *fsc, char *name){	struct fat_fileentry filee;	struct direntry *dire;	char *dpath;	int long_name = 0;	int dir_scan = 0;	int i;	bzero(&filee, sizeof(filee));	dpath = strchr(name, '/');	if (dpath != NULL) {		*dpath = '\0';		dpath++;		dir_scan = 1;	}	for (fsc->DirCacheNum = fsc->FirstRootDirSecNum; fsc->DirCacheNum < (fsc->RootDirSectors + fsc->FirstRootDirSecNum); fsc->DirCacheNum++) {		if (readsector(fsc, fsc->DirCacheNum, 1, fsc->DirBuffer) == 0) {			return (0);		}		dire = (struct direntry *)fsc->DirBuffer;		for (i = 0; (i < (SECTORSIZE / sizeof(struct direntry))); i++, dire++) {						if (dire->dirName[0] == SLOT_EMPTY)				return (0);			if (dire->dirName[0] == SLOT_DELETED)				continue;			if (dire->dirAttributes == ATTR_WIN95) {				bcopy((void *)dire, (void *)&dirbuf[long_name], sizeof(struct direntry));				long_name++;				if (long_name > MAX_DIRBUF - 1)					long_name = 0;				continue;			}			if (dir_scan == 0 && dire->dirAttributes == ATTR_DIRECTORY) {				long_name = 0;				continue;			}			bcopy((void *)dire, (void *)&dirbuf[long_name], sizeof(struct direntry));			fat_parseDirEntries(long_name, &filee);			if ((strcasecmp(name, filee.shortName) == 0) || (strcasecmp(name, filee.longName) == 0)) {				if (dir_scan) {					struct fatchain chain;					int res;					fat_getChain(fsc, letoh16(dire->dirStartCluster), &chain);					res = fat_subdirscan(fsc, dpath, &chain);					if (chain.entries) {						free(chain.entries);					}					return (res);				} else {					strcpy(fsc->file.shortName, filee.shortName);					fsc->file.HighClust = filee.HighClust;					fsc->file.StartCluster = filee.StartCluster;					fsc->file.FileSize = filee.FileSize;					fat_getChain(fsc, fsc->file.StartCluster, &fsc->file.Chain);					return (1);				}			}		}	}	return (0);}int fat_subdirscan(struct fat_sc *fsc, char *name, struct fatchain *chain){	struct fat_fileentry filee;	struct direntry *dire;	char *dpath;	int long_name = 0;	int dir_scan = 0;	int sector;	int i;	int j;	int k;		bzero(&filee, sizeof(filee));	dpath = strchr(name, '/');	if (dpath != NULL) {		*dpath = '\0';		dpath++;		dir_scan = 1;	}	for (i = 0; i < chain->count; i++) {		for (j = 0; j < fsc->SecPerClust; j++) {			sector = getSectorIndex(fsc, chain, j);			if (readsector(fsc, sector, 1, fsc->DirBuffer) == 0) {				return (0);			}			dire = (struct direntry *)fsc->DirBuffer;						for (k = 0; (k < (SECTORSIZE / sizeof(struct direntry))); k++, dire++) {								if (dire->dirName[0] == SLOT_EMPTY)					return (0);								if (dire->dirName[0] == SLOT_DELETED)					continue;								if (dire->dirAttributes == ATTR_WIN95) {					bcopy((void *)dire, (void *)&dirbuf[long_name], sizeof(struct direntry));					long_name++;					if (long_name > MAX_DIRBUF - 1)						long_name = 0;					continue;				}								if (dir_scan == 0 && dire->dirAttributes == ATTR_DIRECTORY) {					long_name = 0;					continue;				}								bcopy((void *)dire, (void *)&dirbuf[long_name], sizeof(struct direntry));				fat_parseDirEntries(long_name, &filee);				if ((strcasecmp(name, filee.shortName) == 0) || (strcasecmp(name, filee.longName) == 0)) {					if (dir_scan) {						struct fatchain chain;						int res;												fat_getChain(fsc, letoh16(dire->dirStartCluster), &chain);						res = fat_subdirscan(fsc, dpath, &chain);						if (chain.entries) {							free(chain.entries);						}						return (res);					} else {						strcpy(fsc->file.shortName, filee.shortName);						fsc->file.HighClust = filee.HighClust;						fsc->file.StartCluster = filee.StartCluster;						fsc->file.FileSize = filee.FileSize;						fat_getChain(fsc, fsc->file.StartCluster, &fsc->file.Chain);						return (1);					}				}			}		}	}	return (0);}int fat_parseDirEntries(int dirc, struct fat_fileentry *filee){	struct direntry *dire;	struct winentry *wine;	u_int8_t longName[290];	u_int8_t chksum;	int c = 0;	int i;	dire = &dirbuf[dirc];	filee->HighClust = letoh16(dire->dirHighClust);	filee->StartCluster = letoh16(dire->dirStartCluster);	filee->FileSize = letoh32(dire->dirFileSize);	parseShortFilename(dire, filee->shortName);	chksum = shortNameChkSum(filee->shortName);	if (dirc != 0) {		u_int8_t buffer[26];		u_int16_t *bp;		int j = 0;		for (i = dirc; i != 0; i--) {			wine = (struct winentry *)&dirbuf[i-1];			bzero(buffer, sizeof(buffer));			bcopy(wine->wePart1, &buffer[0], sizeof(wine->wePart1));			bcopy(wine->wePart2, &buffer[sizeof(wine->wePart1)], sizeof(wine->wePart2));			bcopy(wine->wePart3, &buffer[sizeof(wine->wePart1) + sizeof(wine->wePart2)], sizeof(wine->wePart3));			bp = (u_int16_t *)buffer;			for (j = 0; j < 14; j++, c++) {				longName[c] = (u_int8_t)letoh16(bp[j]);				if (longName[c] == '\0')					goto done;			}		} done:		strcpy(filee->longName, longName);	}	return (1);}u_int8_t shortNameChkSum(u_int8_t *name){	u_int16_t len;	u_int8_t sum;	sum = 0;	for (len = 11; len != 0; len--) {		sum = ((sum & 1) ? 0x80 : 0) + (sum >> 1) + *name++;	}	return (sum);	}int fat_getChain(struct fat_sc *fsc, int start, struct fatchain *chain){	u_int32_t mask;	u_int32_t entry;	int count;	int i;		switch (fsc->FatType) {	case TYPE_FAT12:		mask = FAT12_MASK;		break;	case TYPE_FAT16:		mask = FAT16_MASK;		break;	case TYPE_FAT32:		mask = FAT32_MASK;		break;	default:		mask = 0;	}	     	for (count = 0; 1; count++) {		entry = getFatEntry(fsc, start + count);		if (entry >= (CLUST_EOFE & mask))			break;	}	chain->count = count + 1;	chain->start = start;	chain->entries = (u_int32_t *)malloc(sizeof(u_int32_t) * chain->count);	if (chain->entries == NULL) {		return (-1);	}	chain->entries[0] = start;	for (i = 0; i < count; i++) {		chain->entries[i+1] = getFatEntry(fsc, start + i);	}	return (1);}int parseShortFilename(struct direntry *dire, char *name){	int j;	for (j = 0; j < 8; j++) {		if (dire->dirName[j] == ' ')			break;		*name++ = dire->dirName[j];	}	if (dire->dirExtension[0] != ' ')		*name++ = '.';	for (j = 0; j < 3; j++) {		if (dire->dirExtension[j] == ' ')			break;		*name++ = dire->dirExtension[j];	}	*name = '\0';	return (-1);}int readsector(struct fat_sc *fsc, int sector, int count, u_int8_t *buffer){	int res;	res = lseek(fsc->fd, (sector * SECTORSIZE +	    (fsc->PartitionStart * SECTORSIZE)), SEEK_SET);		res = read(fsc->fd, buffer, (SECTORSIZE * count));	if (res == (SECTORSIZE * count)) {		return (1);	} else {		return (-1);	}}#ifdef FAT_DEBUGint fat_dump_fatsc(struct fat_sc *fsc){	printf("Bytes per Sector = %d\n", fsc->BytesPerSec);	printf("Sectors Per Cluster = %d\n", fsc->SecPerClust);	printf("Number of reserved sectors = %d\n", fsc->ResSectors);	printf("Number of FATs = %d\n", fsc->NumFATs);	printf("Number of Root directory entries = %d\n", fsc->RootDirEnts);	printf("Total number of sectors = %d\n", fsc->TotalSectors);	printf("Number of sectors per FAT = %d\n", fsc->FATsecs);	printf("Sectors per track = %d\n", fsc->SecPerTrack);	printf("Number of hidden sectors = %d\n", fsc->HiddenSecs);	printf("Number of Root directory sectors = %d\n", fsc->RootDirSectors);	printf("Count of clusters = %d\n", fsc->CountOfClusters);	printf("Clustersize = %d\n", fsc->ClusterSize);	printf("First Root directory sector = %d\n", fsc->FirstRootDirSecNum);	printf("Total Data Sectors = %d\n", fsc->DataSectors);	printf("Data Sector base = %d\n", fsc->DataSectorBase);	return (1);}int fat_dump_fileentry(struct fat_sc *fsc){	int i;		printf("        File: %s\n", fsc->file.Name);	printf("   HighClust: %d\n", fsc->file.HighClust);	printf("StartCluster: %d\n", fsc->file.StartCluster);	printf("    FileSize: %d\n", fsc->file.FileSize);	if (fsc->file.Chain.count) {		printf("Cluster chain: ");		for (i = 0; i < fsc->file.Chain.count; i++) {			printf("0x%08x ", fsc->file.Chain.entries[i]);		}		printf("\n");	}	return (1);}#endif /* FAT_DEBUG */

⌨️ 快捷键说明

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