aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiu Aleaxander <Aleaxander@gmail.com>2009-05-19 06:39:48 +0800
committerLiu Aleaxander <Aleaxander@gmail.com>2009-05-19 06:39:48 +0800
commitd79c1c9fc74b867b2a060f909b62cc7c1b7dfdac (patch)
tree2ea8f1a355479dfaa77cdf3a1e6ed29151d75006
parent2afc0ca8a0faa7e0c90063aa9a6ba2c10155da7a (diff)
downloaddevel-d79c1c9fc74b867b2a060f909b62cc7c1b7dfdac.tar.gz
devel-d79c1c9fc74b867b2a060f909b62cc7c1b7dfdac.tar.xz
devel-d79c1c9fc74b867b2a060f909b62cc7c1b7dfdac.zip
some emergency case
-rw-r--r--Makefile7
-rw-r--r--ldlinux.c334
2 files changed, 187 insertions, 154 deletions
diff --git a/Makefile b/Makefile
index 30c89bc..63b72cc 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/ldlinux.c b/ldlinux.c
index 7fe13f9..9203283 100644
--- a/ldlinux.c
+++ b/ldlinux.c
@@ -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;