hdd_file.c
上传用户:caisangzi8
上传日期:2013-10-25
资源大小:15756k
文件大小:26k
源码类别:

DVD

开发平台:

C/C++

  1. /*=================================================================
  2. hdd_fs.c: Some FileSystem Info Function for HDD
  3. 2002-04-28 10:00AM Created  by Verdure
  4. 2002-06-12 08:42AM Modified by cyue
  5. Copyright(c)2000-2002 by Worldplus Technology (ShenZhen) Co., Ltd.
  6.                    ALL RIGHTS RESERVED 
  7. =================================================================*/
  8. #include "config.h"
  9. #include "set.h"
  10. #include "global.h"
  11. #include "hdd_if.h"
  12. #include "user_init.h"
  13. #ifdef SUPPORT_HDD_ACCESS
  14. #define D printf("INFO: __%d__(%s:%s)n",__LINE__,__FILE__,__FUNCTION__);
  15. #define SUPPORT_FAT2 //MIKEY 2003.09.18 write FAT2
  16. //#define SUPPORT_BACKUP_FAT //MIKEY 2003.09.18 copy FAT1 to FAT2
  17. #define DBG_HDD_FS //MIKEY_DEBUG
  18. #ifndef DBG_HDD_FS
  19. #undef printf
  20. #define printf(f, a...)  {}
  21. #endif
  22. UINT32  keep_lba=-1;
  23. //==============================================================
  24. //
  25. //==============================================================
  26. // Global for FAT FS
  27. extern UINT8  pwb[];
  28. //UINT8 *Info_buff=pwb+0;
  29. #define NAVBUFSTART (0xa03c0000) // 0xa03c0000 40k
  30. UINT8 *Info_buff=(UINT8 *)(NAVBUFSTART+0);
  31. UINT8  HD_EXIST;
  32. HDD_INFO HDD_Info;
  33. BPB_INFO BPB;
  34. UINT32 Data_Start_Clus;
  35. UINT32 File_FDB_Lba;
  36. UINT32 Start_LBA;
  37. UINT32 Data_Curr_Clus;
  38. UINT32 Data_Next_Clus;
  39. int FS_Get_BPBPara(UINT8*);
  40. PARTITION_INFO* HDD_AddPE(HDD_INFO* HDD_Info,UINT32 MBR,PARTITION_ENTRY* pe)
  41. {
  42. PARTITION_INFO *pi=0;
  43. #ifdef PI_USE_MATRIX
  44. int j;
  45. for(j=0;j<MAX_PART_INFO;j++)
  46.      if(!HDD_Info->part[j].type) break;
  47. pi=&HDD_Info->part[j]; 
  48. #else
  49. PARTITION_INFO *hddpi;
  50. pi=(PARTITION_INFO*)malloc(sizeof(PARTITION_INFO));
  51. #endif
  52. pi->type=pe->type;
  53. pi->next=NULL;
  54. pi->startlba=MBR+(pe->secfrommbr_hi<<16|pe->secfrommbr_lo);
  55. Start_LBA=pi->startlba;
  56.         // printf("n startlba:%xn",Start_LBA);//jichuan
  57. pi->seccnt=pe->seccnt_hi<<16|pe->seccnt_lo;
  58. pi->act=pe->act; 
  59. #ifndef PI_USE_MATRIX
  60. if(HDD_Info->partition_list==NULL)
  61. HDD_Info->partition_list=pi;
  62. else {
  63. for(hddpi=HDD_Info->partition_list;hddpi->next!=NULL;hddpi=hddpi->next);
  64. hddpi->next=pi;
  65. }
  66. #endif 
  67. return pi; 
  68. }
  69. int HDD_MakeInfo(HDD_INFO *HDD_Info,UINT8* buff)
  70. {
  71. PARTITION_ENTRY *pe;
  72. UINT32 i;     
  73. UINT32 MBR=0,secfrommbr,seccnt;
  74. #ifdef PI_USE_MATRIX
  75. for(i=0;i<MAX_PART_INFO;i++)
  76. HDD_Info->part[i].type=0;
  77. #else
  78. HDD_Info->partition_list=NULL;
  79. #endif
  80. HDD_ReadSec(buff,MBR,1);
  81. //print_sector(buff);
  82. for(i=0;i<4;i++) { //Parse Primary partitions
  83. pe=(PARTITION_ENTRY*)(buff+ 0x1be +i*16);
  84. secfrommbr=pe->secfrommbr_hi<<16|pe->secfrommbr_lo;
  85. seccnt=pe->seccnt_hi<<16|pe->seccnt_lo;  
  86. printf("n--secfrommbr=%lx--n",secfrommbr);
  87. if (!pe->type)
  88. continue;
  89. if ((pe->type==0x0f)||(pe->type==0x05)) {
  90. // Extended Partition!!
  91. UINT32 MBREXT=MBR+secfrommbr;
  92. do {
  93. HDD_ReadSec(buff,MBREXT,1);
  94. printf("n Parse EXT %lu... ",MBREXT);
  95. if (*(UINT16*)(buff+510)!=0xaa55) {
  96. printf("n Fail EXT Partition!!");
  97. break;
  98. }
  99. pe=(PARTITION_ENTRY*)(buff + 0x1be);
  100. secfrommbr=pe->secfrommbr_hi<<16|pe->secfrommbr_lo;
  101. seccnt=pe->seccnt_hi<<16|pe->seccnt_lo;
  102. if (pe->type) {
  103. #ifdef MIKEY
  104. HDD_AddPE(HDD_Info,MBREXT,pe);
  105. #else
  106. printf("MIKEY: skip add EXT partition type[%x]n",pe->type);
  107. break;
  108. #endif
  109. }
  110. else
  111. break;
  112. pe=(PARTITION_ENTRY*)(buff+ 0x1be +16);
  113. if(!pe->type) {
  114. printf("nLast MBR!!");
  115. MBREXT=HDD_Info->seccnt - seccnt;
  116. }
  117. else {
  118. MBREXT=MBREXT+secfrommbr+seccnt;
  119. }
  120. }while((pe->type==0x0f)||(pe->type==0x05));
  121. else {
  122. HDD_AddPE(HDD_Info,MBR,pe);
  123. printf("n primary=%d n",i);
  124. }
  125. }
  126. return 0;
  127. }
  128. void HDD_Dump_Info(HDD_INFO* HDD_Info)
  129. {
  130. PARTITION_INFO *pi;
  131. int i;
  132. printf("nnHDD: C=%lu H=%lu S=%lu",HDD_Info->cyl,HDD_Info->head,HDD_Info->sec);
  133. printf("nHDD total Sectors = %lu, %lu MB ",HDD_Info->seccnt,HDD_Info->seccnt/2000);
  134. printf("nPAR  A TYPE START LBA       COUNT"); 
  135. #ifdef PI_USE_MATRIX
  136. for(i=0;i<MAX_PART_INFO;i++) {
  137. pi= &HDD_Info->part[i];
  138. if(pi->type)
  139. printf("n%2d  %02x  %02x %10lu  %10lun",i,pi->act,pi->type,pi->startlba,pi->seccnt);
  140. }
  141. #else
  142. for(i=0,pi=HDD_Info->partition_list;pi!=NULL;i++,pi=pi->next) {
  143. printf("n%2d  %02x  %02x  %10lu  %10lu",i,pi->act,pi->type,pi->startlba,pi->seccnt);
  144. }
  145. #endif
  146. }
  147. static int FS_check_SecPerClus(unsigned SecPerClus)
  148. {
  149. unsigned char log;
  150. for(log = 0; log < 8; log++) {
  151. if(SecPerClus & 1) {
  152. SecPerClus >>= 1;
  153. return (SecPerClus != 0) ? -1 : log;
  154. }
  155. SecPerClus >>= 1;
  156. }
  157. return -1;
  158. }
  159. int FS_check_BootSec(UINT8* buf)
  160. {
  161. UINT16 temp;
  162. //check Jump Code + NOP
  163. if(buf[0] == 0xE9)
  164. /* OK */;
  165. else if(buf[0] == 0xEB && buf[2] == 0x90)
  166. /* OK */;
  167. else {
  168. printf("Missing JMP/NOPn");
  169. return 1;
  170. }
  171. //check Sectors Per Cluster
  172. temp = buf[13];
  173. if(FS_check_SecPerClus(temp) < 0) {
  174. printf("Sectors per cluster (%u) is not a power of 2n",temp);
  175. return 1;
  176. }
  177. //check the Number of FATs
  178. temp = buf[16];
  179. if(temp != 1 && temp != 2) {
  180. printf("Invalid number of FATs (%u)n",temp);
  181. return 1;
  182. }
  183.     
  184. //check Sectors Per Track
  185. temp = read_le16(buf + 24);
  186. if(temp == 0 || temp > 63) {
  187. printf("Invalid number of sectors (%u)n",temp);
  188. return 1;
  189. }
  190. //check Number of Heads
  191. temp = read_le16(buf + 26);
  192. if(temp == 0 || temp > 255) {
  193. printf("Invalid number of heads (%u)n",temp);
  194. return 1;
  195. }
  196. return FS_Get_BPBPara(buf);
  197. }
  198. int FS_Get_BPBPara(UINT8* buf)
  199. {
  200. BPB.BytesPerSec=(buf[12]<<8)|buf[11];
  201. switch(BPB.BytesPerSec) {
  202. case 512: BPB.BytesPerSecPwr=9; break;
  203. case 2048: BPB.BytesPerSecPwr=11; break;
  204. case 256: BPB.BytesPerSecPwr=8; break;
  205. }
  206. printf("n## BytesPerSec:%d ",BPB.BytesPerSec);
  207.      
  208. BPB.SecPerClus=buf[13];
  209. switch(BPB.SecPerClus) {
  210. case 128: BPB.SecPerClusPwr=7; break; //64K allocation unit
  211. case  64: BPB.SecPerClusPwr=6; break; //32K allocation unit
  212. case  32: BPB.SecPerClusPwr=5; break; //16K allocation unit
  213. case  16: BPB.SecPerClusPwr=4; break; // 8K allocation unit
  214. case   8: BPB.SecPerClusPwr=3; break; // 4K allocation unit
  215. case   4: BPB.SecPerClusPwr=2; break; // 2K allocation unit
  216. }
  217. printf("n## SecPerClus:%d ",BPB.SecPerClus);
  218. printf("n## SecPerClusPwr:%d ",BPB.SecPerClusPwr);
  219.      
  220. BPB.ReserSecCnt=read_le16(buf + 14);
  221. BPB.NumFATs=buf[16];
  222. // BPB.MediaDescriptor=buf[21];
  223. // BPB.SecPerTrack=read_le16(buf + 24);
  224. // BPB.NumHeads=read_le16(buf + 26);
  225. // BPB.HiddenSecCnt=read_le32(buf + 28);
  226. // BPB.TolSec32=read_le32(buf + 32);
  227. BPB.FATSize32=read_le32(buf + 36);
  228. printf("n## FATSize32:%d ",BPB.FATSize32);
  229. BPB.CurrDirClus=BPB.RootClus=read_le32(buf + 44);
  230. BPB.FAT1_Start=Start_LBA+BPB.ReserSecCnt;
  231. printf("n## BPB.FAT1_Start:%d ",BPB.FAT1_Start);
  232. if (BPB.NumFATs==1) 
  233. BPB.FAT2_Start=0;
  234. if (BPB.NumFATs==2)
  235. BPB.FAT2_Start=BPB.FAT1_Start+BPB.FATSize32;
  236. BPB.Data_Area_Start=((BPB.RootClus-2)*BPB.SecPerClus) + BPB.FAT1_Start+BPB.FATSize32*BPB.NumFATs;
  237. printf("n## BPB.Data_Area_Start:%d n",BPB.Data_Area_Start);
  238. return 0;
  239. }
  240. UINT32 Last_FAT_Lba=0x0FFFFFFF; // cyue: Try to make a cache 2002-06-11 11:14PM
  241. UINT8 *FS_ReadInfoSec(UINT32 lba,int seccnt)
  242. {
  243. if(Last_FAT_Lba!=lba) {
  244. HDD_ReadSec(Info_buff,lba,seccnt);
  245. }
  246. return Info_buff;
  247. }
  248. void FS_flush_cache()
  249. {
  250. keep_lba=-1;
  251. }
  252. UINT32  FS_Get_NextClus(UINT32 clus) //MIKEY 2003.09.02 for speed up
  253. {
  254. UINT32 lba;
  255. UINT32 nOffset;
  256. // static UINT32  keep_lba=-1;
  257. static UINT32  keep_count=0;
  258. // extern UINT8  pwb[];
  259. // UINT8 *buff512=pwb+512;
  260. UINT8 *buff512=(UINT8 *)(NAVBUFSTART+512);
  261.     keep_lba=-1; //MIKEY disable cache
  262. nOffset=clus&0x7F;//%128;
  263. lba=(clus>>7)+BPB.FAT1_Start;
  264. if(keep_lba!=lba) { //MIKEY_CACHE
  265. keep_lba=lba;
  266. HDD_ReadSec(buff512, lba, 1);
  267. }
  268. else {
  269. keep_count++;
  270. if((keep_count % 100)==99)
  271. printf("INFO: FS_Get_NextClus keep_count(%ld)n",keep_count);
  272. }
  273. Data_Next_Clus=read_le32(buff512+(nOffset<<2))&0x0fffffff;
  274. return Data_Next_Clus;
  275. }
  276. //==============================================================
  277. //
  278. //==============================================================
  279. //extern BYTE CardReadSector();
  280. extern BYTE FSReadSector();
  281. extern BYTE CardWriteSector();
  282. extern void *memcpy();
  283. extern unsigned strlen();
  284. /* Check whether HD present */
  285. UINT8 HDD_DEV_Existence(void)
  286. {
  287. return 0;
  288. }
  289. int HDD_ReadSec(UINT8 *buff, UINT32 lba, int seccnt)
  290. {
  291. int i;
  292. int ret=0;
  293. for(i=0;i<5;i++) { // retry?
  294. // if((ret=CardReadSector(lba, seccnt, buff))==0)
  295. if((ret=FSReadSector(lba, seccnt, buff))==0)
  296. break; //OK
  297. printf("ERROR: HDD_ReadSec retry(%d)n",i+1);
  298. }
  299. return ret;
  300. int HDD_WriteSec(UINT8 *buff, UINT32 lba, int seccnt)
  301. {
  302. int i;
  303. int ret=0;
  304. for(i=0;i<5;i++) { // retry?
  305. if((ret=CardWriteSector(lba, seccnt, buff))==0)
  306. break; //OK
  307. printf("ERROR: HDD_WriteSec retry(%d)n",i+1);
  308. }
  309. return ret;
  310. UINT32 FS_LBA2Clus(UINT32 lba)
  311. {
  312. UINT32 clus;
  313. clus = (lba - BPB.Data_Area_Start)/BPB.SecPerClus + 2;
  314. return clus;
  315. }
  316. UINT32 FS_LBAinClus(UINT32 lba)
  317. {
  318. UINT32 curClus, nextClus;
  319. int i;
  320.     
  321. curClus = FS_LBA2Clus(lba);
  322. for (i=0; i<BPB.SecPerClus; i++) {
  323. nextClus = FS_LBA2Clus(lba+i+1);
  324. if (curClus != nextClus)
  325. break;
  326. }
  327. return i;
  328. }
  329. //==============================================================
  330. //
  331. //==============================================================
  332. #ifdef SUPPORT_BACKUP_FAT
  333. void  HDD_Backup_FAT(void)
  334. {
  335. UINT32 i;
  336. if(BPB.NumFATs<2)
  337. return;
  338. for(i=0; i<BPB.FATSize32; i++) {
  339. HDD_ReadSec (Info_buff, BPB.FAT1_Start+i, 1);
  340. HDD_WriteSec(Info_buff, BPB.FAT2_Start+i, 1);
  341. }
  342. }
  343. #endif //SUPPORT_BACKUP_FAT
  344. int HDD_list_clus(FILE_INFO *fp)
  345. {
  346. UINT32 st,next;
  347. // UINT32 lba_count=LBA_COUNT(fp->fsize),sec_count=BPB.SecPerClus; 
  348. int i=0;
  349. st=fp->start_clus;
  350. next=0;
  351. //printf("MIKEY: lba_count(%d)/(%d)=(%d)n",lba_count,sec_count,(lba_count+sec_count-1)/sec_count);
  352. while(1) {
  353. printf("$$ clus(%4d):[%x]n",i,st);
  354. if(st>=0x0FFFFFF8) {//End?
  355. break;
  356. }
  357. next=FS_Get_NextClus(st);
  358. st=next;
  359. i++;
  360. }
  361. return 0;
  362. }
  363. //==============================================================
  364. //
  365. //==============================================================
  366. UINT8  FS_Emu_stricmp(UINT8* s1, UINT8* s2)
  367. {
  368. UINT16 i;
  369. //MIKEY_BUG
  370. // for(i=0;(i<11)&&(*s1)&&(*s2);i++,s1++,s2++) {
  371. for(i=0;i<11;i++) {
  372. if(((s1[i])&~0x20)!=((s2[i])&~0x20))
  373.      return 1;
  374. }
  375. return 0;
  376. }
  377. UINT8  HDD_Mount(void)
  378. {
  379. UINT8 i;
  380.     
  381. if ((HD_EXIST = HDD_DEV_Existence()))
  382. return 0;
  383. HDD_MakeInfo(&HDD_Info,Info_buff);
  384. for(i=0;HDD_Info.part[i].type;i++) { /*浪代–