diff options
author | Liu Aleaxander <Aleaxander@gmail.com> | 2009-05-20 07:07:31 +0800 |
---|---|---|
committer | Liu Aleaxander <Aleaxander@gmail.com> | 2009-05-20 07:07:31 +0800 |
commit | 7ae9080b65998c402cee3268161035d7c7afa7cd (patch) | |
tree | e566fd73a3bf3b46893d6495797b0e4d4ecb67a2 | |
parent | 88a72896dc32cc4a2a79b962af6b21ec5d442333 (diff) | |
download | devel-ldlinux.tar.gz devel-ldlinux.tar.xz devel-ldlinux.zip |
Make the fat system dirve do the workldlinux
bug fixed; syslinux can read the files correctly , and more, it also can
detect the fat cluster that corss one sector(FAT12 will, since the cache
is based on sector size for fat filesystem), so it may or even can work
correctly.
-rw-r--r-- | disklab.c | 7 | ||||
-rw-r--r-- | ldlinux.c | 36 |
2 files changed, 33 insertions, 10 deletions
@@ -21,7 +21,8 @@ void* getoneblk(__u32 block) buf = malloc(blk_size); if ( (bytes_read = read(fd, buf, blk_size)) < blk_size ) - printf("read %d bytes less than %dB..\n", bytes_read, blk_size); + printf("%s:%s: read %d bytes less than %dB..\n", + __FILE__, __FUNCTION__, bytes_read, blk_size); return buf; } @@ -37,7 +38,7 @@ void getlinsec(char *buf, int sector, int sector_cnt) } if ( (bytes_read = read(fd, buf, 512*sector_cnt)) < 512*sector_cnt) - printf("read %d bytes less than %d bytes..\n", - bytes_read, 512 * sector_cnt); + printf("%s:%s: read %d bytes less than %d bytes..\n", + __FILE__, __FUNCTION__, bytes_read, 512 * sector_cnt); } @@ -171,12 +171,31 @@ __u32 nextcluster(__u32 clust_num) __u32 next_cluster; __u32 fat_sector; struct cache_struct *cs; + +#if FATType == FAT12 + int offset; + int lo, hi; +#endif switch(FATType) { case FAT12: fat_sector = (clust_num + clust_num / 2) >> SECTOR_SHIFT; cs = getfatsector(fat_sector); - next_cluster = *(__u16 *)(cs->data + (clust_num*3/2) % 512); + offset = (clust_num * 3 / 2) & ( SECTOR_SIZE -1 ); + if ( offset == 0x1ff ) { + /* + * we got the end of the one fat sector, + * but we don't got we have(just one byte, we need two), + * so store the low part, then read the next fat + * sector, read the high part, then combine it. + */ + lo = *(__u8 *)(cs->data + offset); + cs = getfatsector(fat_sector + 1); + hi = *(__u8 *)cs->data; + next_cluster = (hi << 8) + lo; + } else + next_cluster = *(__u16 *)(cs->data + offset); + if ( clust_num & 0x0001 ) next_cluster >>= 4; /* cluster number is ODD */ else @@ -261,12 +280,13 @@ __u32 nextsector(__u32 sector) * 64K boundaries. * * @param: buf - * @param: curr_sector, the sector where to start reading + * @param: file structure * @param: sectors * */ -void __getfssec(char *buf, __u32 curr_sector, __u32 sectors) +void __getfssec(char *buf, struct open_file_t *file, __u32 sectors) { + __u32 curr_sector = file->file_sector; __u32 frag_start , next_sector; __u32 con_sec_cnt; @@ -301,8 +321,11 @@ void __getfssec(char *buf, __u32 curr_sector, __u32 sectors) if ( !sectors ) break; //curr_sector --; /* this is the last sector actually read */ - curr_sector = next_sector = nextsector(curr_sector); + curr_sector = next_sector; }while( sectors ); + + /* update the file_sector filed for the next read */ + file->file_sector = nextsector(curr_sector); } @@ -329,7 +352,7 @@ __u32 getfssec(char *buf, struct open_file_t *file, __u32 sectors, int *have_mor if ( sectors > file->file_left ) sectors = file->file_left; - __getfssec(buf, file->file_sector, sectors); + __getfssec(buf, file, sectors); if ( bytes_read >= file->file_bytesleft ) { bytes_read = file->file_bytesleft; @@ -343,8 +366,7 @@ __u32 getfssec(char *buf, struct open_file_t *file, __u32 sectors, int *have_mor } file->file_left -= sectors; - file->file_sector += sectors; - + return bytes_read; } |