diff options
author | Liu Aleaxander <Aleaxander@gmail.com> | 2009-05-19 06:39:48 +0800 |
---|---|---|
committer | Liu Aleaxander <Aleaxander@gmail.com> | 2009-05-19 06:39:48 +0800 |
commit | d79c1c9fc74b867b2a060f909b62cc7c1b7dfdac (patch) | |
tree | 2ea8f1a355479dfaa77cdf3a1e6ed29151d75006 | |
parent | 2afc0ca8a0faa7e0c90063aa9a6ba2c10155da7a (diff) | |
download | devel-d79c1c9fc74b867b2a060f909b62cc7c1b7dfdac.tar.gz devel-d79c1c9fc74b867b2a060f909b62cc7c1b7dfdac.tar.xz devel-d79c1c9fc74b867b2a060f909b62cc7c1b7dfdac.zip |
some emergency case
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | ldlinux.c | 334 |
2 files changed, 187 insertions, 154 deletions
@@ -1,4 +1,7 @@ -a.out:cache.h cache.c main.c disklab.h disklab.c ext2_fs.h extlinux.c - gcc -g cache.c main.c disklab.c extlinux.c +extlinux:cache.h disklab.h ext2_fs.h + gcc -g cache.c main.c disklab.c extlinux.c -o extlinux + +syslinux:cache.h disklab.h fat_fs.h + gcc -g main.c cache.c disklab.c ldlinux.c -o syslinux clean: (rm -f *~ *.o)
\ No newline at end of file @@ -63,6 +63,8 @@ struct open_file_t Files[MAX_OPEN]; #define trackbufsize 8192 char trackbuf[trackbufsize]; +char MangleBuf[12]; + /* the fat bpb data */ struct fat_bpb fat; @@ -107,7 +109,7 @@ struct open_file_t* alloc_fill_dir(__u32 sector) { struct open_file_t *file; - file = allocat_file(); + file = allocate_file(); if ( !file ) return NULL; @@ -132,12 +134,121 @@ void close_file(struct open_file_t *file) void close_dir(struct fat_dir_entry *dir) { if ( dir ) - *(char*)dir = 0; + *(__u32*)dir = 0; } + +/** + * getfatsector: + * + * check for a particular sector in the FAT cache. + * + */ +struct cache_struct *getfatsector(__u32 sector) +{ + return get_cache_block(FAT + sector); +} + + +/** + * nextcluster: + * + * Advance a cluster pointer in clust_num to the next cluster + * pointer at in the FAT tables. CF = 0 on return if end of file. + * + * @param: clust_num; + * + * @return: the next cluster number + * + */ +__u32 nextcluster(__u32 clust_num) +{ + __u32 next_cluster; + __u32 fat_sector; + struct cache_struct *cs; + + switch(FATType) { + case FAT12: + fat_sector = (clust_num + clust_num / 2) >> SECTOR_SHIFT; + cs = getfatsector(fat_sector); + next_cluster = ((__u16 *)cs->data)[clust_num]; + if ( clust_num & 0x0001 ) + next_cluster >>= 4; /* cluster number is ODD */ + else + next_cluster &= 0x0fff; /* cluster number is EVEN */ + if ( next_cluster > 0x0ff0 ) + goto fail; + break; + + case FAT16: + fat_sector = clust_num >> (SECTOR_SHIFT - 2); + cs = getfatsector(fat_sector); + next_cluster = ((__u16 *)cs->data)[clust_num]; + if ( next_cluster > 0xfff0 ) + goto fail; + break; + + case FAT32: + fat_sector = clust_num >> (SECTOR_SHIFT - 2); + cs = getfatsector(fat_sector); + next_cluster = ((__u32 *)cs->data)[clust_num] & 0x0fffffff; + if ( next_cluster > 0x0ffffff0 ) + goto fail; + break; + } + + return next_cluster; + + fail: /* got an unexcepted cluster number, so return ZERO */ + return 0; +} + + + +/** + * nextsector: + * + * given a sector on input, return the next sector of the + * same filesystem object, which may be the root directory or a + * cluster chain. Returns EOF. + * + */ +__u32 nextsector(__u32 sector) +{ + + __u32 data_sector; + __u32 cluster; + + if ( sector < DataArea ) { + sector ++; + /* if we reached the end of root area */ + if ( sector == DataArea ) + sector = 0; /* return 0 */ + return sector; + } + + + data_sector -= DataArea; + if ( !data_sector & ClustMask ) /* in a cluster */ + return (++sector); + + /* got a new cluster */ + cluster = nextcluster( (data_sector >> ClustShift) + 2 ); + if ( !cluster ) + return 0; + + /* return the start of the new cluster */ + sector = ( (cluster - 2) << ClustShift ) + DataArea; + return sector; + } + + + + + /** * __getfssec_edx: * @@ -152,7 +263,7 @@ void close_dir(struct fat_dir_entry *dir) * @param: sectors * */ -void __getfssec(char *buf, __u32 curr_sector, __u32 sectors) +void __getfssec(char *buf, __u32 curr_sector, __u32 sectors, int *have_more) { __u32 frag_start , next_sector; __u32 con_sec_cnt; @@ -169,18 +280,18 @@ void __getfssec(char *buf, __u32 curr_sector, __u32 sectors) if ( sectors == 0 ) break; - next_sector = nextsector(curr_sector, &have_more); - if ( !have_more ) + next_sector = nextsector(curr_sector, have_more); + if ( ! *have_more ) break; }while( next_sector == (++curr_sector) ); /* do read */ - getlinsecsr(buf, frag_start, con_sec_cnt); - buf += con_sec_cnt << 9; /* adjust buffer pointer */ + getlinsec(buf, frag_start, con_sec_cnt); + buf += con_sec_cnt << 9;/* adjust buffer pointer */ - curr_sector --; /* this is the last sector actually read */ - curr_sector = next_sector = nextsector(curr_sector, &have_more); + curr_sector --; /* this is the last sector actually read */ + curr_sector = next_sector = nextsector(curr_sector); }while( sectors ); } @@ -201,11 +312,11 @@ void __getfssec(char *buf, __u32 curr_sector, __u32 sectors) * @return: number of bytes read * */ -void getfssec(char *buf, struct open_file_t *file, __u32 sectors, int *have_more) +__u32 getfssec(char *buf, struct open_file_t *file, __u32 sectors, int *have_more) { __u32 bytes_read; - if ( sectors > file_file_left ) + if ( sectors > file->file_left ) sectors = file->file_left; bytes_read = sectors << SECTOR_SHIFT; @@ -299,24 +410,37 @@ void mangle_dos_name(char *MangleBuf, char *filename) char entry_name[13]; + +void unicode_to_ascii(char *entry_name, __u16 *unicode_buf) +{ + int i = 0; + + for (; i < 13; i++) { + if ( unicode_buf[i] == 0xffff ) { + entry_name[i] = '\0'; + return; + } + entry_name[i] = (char)unicode_buf[i]; + } +} + /** * long_entry_name: * * get the long entry name * */ -char * long_entry_name(struct fat_dir_entry *dir) +void long_entry_name(struct fat_long_name_entry *dir) { int id = dir->id & 0x3f; __u16 unicode_buf[13]; - memcpy(unicode_buf, long_name->name1, 5 * 2); - memcpy(unicode_buf + 5, long_name->name2, 6 * 2); - memcpy(unicode_buf + 11,long_name->name3, 2 * 2); + memcpy(unicode_buf, dir->name1, 5 * 2); + memcpy(unicode_buf + 5, dir->name2, 6 * 2); + memcpy(unicode_buf + 11,dir->name3, 2 * 2); unicode_to_ascii(entry_name, unicode_buf); - return entry_name; } @@ -335,7 +459,7 @@ __u32 first_sector(struct fat_dir_entry *dir) __u32 first_clust, sector; first_clust = (dir->first_cluster_high << 16) + dir->first_cluster_low; - sector = (fisrt_clust - 2) << ClustShift + DataArea; + sector = (first_clust - 2) << ClustShift + DataArea; return sector; } @@ -371,8 +495,15 @@ struct open_file_t* search_dos_dir(char *MangleBuf, __u32 dir_sector, struct fat_dir_entry *dir; struct fat_long_name_entry *long_dir; + __u8 VFATInit, VFATNext, VFATCsum; + __u8 id; __u16 *unicode_buf; __u32 slots; + __u32 entries; + + int checksum; + int have_more; + char *long_name; file = allocate_file(); if ( !file ) @@ -419,7 +550,7 @@ struct open_file_t* search_dos_dir(char *MangleBuf, __u32 dir_sector, VFATNext = --id; /* got the long entry name */ - entry_name = long_entry_name(dir); + long_entry_name(long_dir); memcpy(long_name + id * 13, entry_name, 13); /* @@ -436,7 +567,7 @@ struct open_file_t* search_dos_dir(char *MangleBuf, __u32 dir_sector, } else { /* it's a short entry */ if ( dir->attr & 0x08 ) /* ingore volume labels */ - goto not_macth; + goto not_match; /* If we have a long name match, then VFATNext must be 0 */ @@ -476,7 +607,7 @@ struct open_file_t* search_dos_dir(char *MangleBuf, __u32 dir_sector, } - +__u32 CurrentDir = 0; /** @@ -493,7 +624,6 @@ struct open_file_t* search_dos_dir(char *MangleBuf, __u32 dir_sector, struct open_file_t* searchdir(char *filename, __u32 *file_len) { __u32 dir_sector, prev_dir; - __u32 file_len; __u8 attr; char *p; @@ -505,7 +635,7 @@ struct open_file_t* searchdir(char *filename, __u32 *file_len) filename ++; } - while ( *pathname ) { + while ( *filename ) { p = filename; /* try to find the end */ @@ -518,7 +648,7 @@ struct open_file_t* searchdir(char *filename, __u32 *file_len) prev_dir = dir_sector; mangle_dos_name(MangleBuf, filename); - file = search_dos_dir(MangleBuf, dir_sector, &file_len, &attr); + file = search_dos_dir(MangleBuf, dir_sector, file_len, &attr); if ( !file ) { *file_len = 0; return NULL; @@ -539,8 +669,8 @@ struct open_file_t* searchdir(char *filename, __u32 *file_len) if ( (attr & 0x18) || (file_len == 0) ) return NULL; - file->file_bytesleft = file_len; - file->file_left = ( file_len + SECTOR_SIZE -1 ) >> SECTOR_SHIFT; + file->file_bytesleft = *file_len; + file->file_left = ( *file_len + SECTOR_SIZE -1 ) >> SECTOR_SHIFT; return file; } @@ -559,18 +689,22 @@ struct open_file_t* searchdir(char *filename, __u32 *file_len) * @param: file * */ -struct open_file_t * readdir(struct open_file_t* dir_file, char* filename +struct open_file_t * readdir(struct open_file_t* dir_file, char* filename, __u32 *file_len, __u8 *attr) { __u32 sector, sec_off; /* make it to be 1 to check if we have met a long name entry before */ __u8 id = 1; - __u8 entries_left; + __u8 init_id, next_id; + __u8 entries_left; + int i; + int have_more; struct cache_struct *cs; struct fat_dir_entry *dir; struct fat_long_name_entry *long_dir; + struct open_file_t *file; sector = dir_file->file_sector; sec_off = dir_file->file_bytesleft; @@ -589,17 +723,17 @@ struct open_file_t * readdir(struct open_file_t* dir_file, char* filename /* it's a long name */ long_dir = (struct fat_long_name_entry *)dir; - if ( dir->id & 0x40 ) - init_id = id = dir->id & 0x3f; + if ( long_dir->id & 0x40 ) + init_id = id = long_dir->id & 0x3f; else - id_next = (dir->id & 0x3f) - 1; + next_id = (long_dir->id & 0x3f) - 1; id --; - if ( id != id_next ) + if ( id != next_id ) goto next_entry; - entry_name = long_entry_name(dir); + long_entry_name(long_dir); memcpy(filename + id * 13, entry_name, 13); @@ -614,7 +748,7 @@ struct open_file_t * readdir(struct open_file_t* dir_file, char* filename if ( !id ) /* we got a long name match */ break; - if ( dir->atrr & 0x08 ) + if ( dir->attr & 0x08 ) goto next_entry; for( i = 0; i < 8; i ++) { @@ -640,7 +774,7 @@ struct open_file_t * readdir(struct open_file_t* dir_file, char* filename break; } - /* next_entry */ + next_entry: dir ++; entries_left --; @@ -648,7 +782,7 @@ struct open_file_t * readdir(struct open_file_t* dir_file, char* filename sector = next_sector(sector, &have_more); if ( !sector ) goto fail; - cs = get_cache_sector(sector); + cs = (struct cache_struct *)get_cache_sector(sector); dir = (struct fat_dir_entry *)cs->data; } } @@ -665,130 +799,21 @@ struct open_file_t * readdir(struct open_file_t* dir_file, char* filename file->file_bytesleft = (SECTOR_SIZE - (entries_left << DIRENT_SHIFT) ) & 0xffff; *file_len = dir->file_size; - *attr = dir->atr; + *attr = dir->attr; return file; fail: - close_dir(dir_file); + close_dir(dir); return NULL; } -/** - * getfatsector: - * - * check for a particular sector in the FAT cache. - * - */ -struct cache_struct *getfatsector(__u32 sector) -{ - return get_cache_block(FAT + sector); -} - - -/** - * nextsector: - * - * given a sector on input, return the next sector of the - * same filesystem object, which may be the root directory or a - * cluster chain. Returns EOF. - * - */ -__u32 nextsector(__u32 sector, int *have_more) -{ - - __u32 data_sector; - __u32 cluster; - - *have_more = 1; - - if ( sector < DataArea ) { - sector ++; - if ( sector >= DataArea ) - *have_more = 0; - return sector; - } - - - data_sector -= DataArea; - if ( !data_sector & ClustMask ) /* in a cluster */ - return (++sector); - - /* got a new cluster */ - cluster = nextcluster( (data_sector >> ClustShift) + 2 ); - if ( !cluster ) { - *have_more = 0; - return 0; - } - - /* return the start of the new cluster */ - sector = ( (cluster - 2) << ClustShift ) + DataArea; - return sector; - } - - - - -/** - * nextcluster: - * - * Advance a cluster pointer in clust_num to the next cluster - * pointer at in the FAT tables. CF = 0 on return if end of file. - * - * @param: clust_num; - * - * @return: the next cluster number - * - */ -__u32 nextcluster(__u32 clust_num) -{ - __u32 nextcluster; - __u32 fat_sector; - struct cache_struct *cs; - - switch(FATType) { - case FAT12: - fat_sector = (clust_num + clust_num / 2) >> SECTOR_SHIFT; - cs = getfatsector(fat_sector); - nextcluster = ((__u16 *)cs->data)[clust_num]; - if ( clust_num & 0x0001 ) - nextcluster >>= 4; /* cluster number is ODD */ - else - nextcluster &= 0x0fff; /* cluster number is EVEN */ - if ( nextcluster > 0x0ff0 ) - goto fail; - break; - - case FAT16: - fat_sector = clust_num >> (SECTOR_SHIFT - 2); - cs = getfatsector(fat_sector); - nextcluster = ((__u16 *)cs->data)[clust_num]; - if ( next > 0xfff0 ) - goto fail; - break; - - case FAT32: - fat_sector = clust_num >> (SECTOR_SHIFT - 2); - cs = getfatsector(fat_sector); - nextcluster = ((__u32 *)cs->data)[clust_num] & 0x0fffffff; - if ( nextcluster > 0x0ffffff0 ) - goto fail; - break; - } - - return nextcluster; - - fail: /* got an unexcepted cluster number, so return ZERO */ - return 0; -} - - - -struct open_file_t open_file(char *filename) +struct open_file_t* open_file(char *filename) { struct open_file_t *file; + int file_len; file = searchdir(filename, &file_len); @@ -803,12 +828,17 @@ __u32 read_file(struct open_file_t *file, char *buf, int size, int *have_more) return getfssec(buf, file, sectors, have_more); } +void bsr(__u8 *res, int num) +{ + *res = 2; +} /* init. the fs meta data */ void init_fs() { int sectors_per_fat; __u32 clust_num; + int RootDirSize; /* get the fat bpb information */ getlinsec(&fat, 0, 1); @@ -816,15 +846,15 @@ void init_fs() TotalSectors = fat.bxSectors ? : fat.bsHugeSectors; FAT = fat.bxResSectors; - sectors_per_fat = fat.bxFATsecs ? : fat.bxFATsecs_32; + sectors_per_fat = fat.bxFATsecs ? : fat.u.fat32.bxFATsecs_32; RootDir = RootDirArea = FAT + sectors_per_fat * fat.bxFATs; - RootDirSize = (fat.bxRootDirEnts+SECTOR_SIZE/32-1) >> (SECTOR_SHFIT-5); + RootDirSize = (fat.bxRootDirEnts+SECTOR_SIZE/32-1) >> (SECTOR_SHIFT-5); DataArea = RootDirArea + RootDirSize; - bsr(ClustShift, bxSecPerClust); + bsr(&ClustShift, fat.bxSecPerClust); ClustByteShift = ClustShift + SECTOR_SHIFT; ClustMask = fat.bxSecPerClust - 1; - ClustSize = fat.bxSecPerClust << SECTOR_SIZE; + ClustSize = fat.bxSecPerClust << SECTOR_SHIFT; blk_size = SECTOR_SIZE; |