Exemple #1
0
fx_rtn
fx_write_panic0(u32_t pstart, u32_t pend) {
    panic0_hdr_t *p;
    uint16_t   *ptr, i, sum;

    assert(fx_buf);
    memset(fx_buf, 0, MS_BUF_SIZE);
    p = (void *) fx_buf;
    p->sig_a       = CT_LE_32(PANIC0_MAJIK);
    p0c.sig_a	   = CF_LE_32(p->sig_a);
    p->panic_start = CT_LE_32(pstart);
    p0c.panic_start= CF_LE_32(p->panic_start);
    p->panic_nxt   = CT_LE_32(pstart);
    p0c.panic_nxt  = CF_LE_32(p->panic_nxt);
    p->panic_end   = CT_LE_32(pend);
    p0c.panic_end  = CF_LE_32(p->panic_end);
    p->fubar       = 0;
    p0c.fubar      = 0;
    p->sig_b       = CT_LE_32(PANIC0_MAJIK);
    p0c.sig_b      = CF_LE_32(p->sig_b);
    p->chksum      = 0;
    ptr = (void *) p;
    sum = 0;
    for (i = 0; i < PANIC0_SIZE_SHORTS; i++)
	sum += CF_LE_16(ptr[i]);
    p->chksum = CT_LE_16((uint16_t) (0 - sum));
    p0c.chksum = CF_LE_16(p->chksum);
    assert(!ms_write_blk(PANIC0_SECTOR, fx_buf));
    return(FX_OK);
}
Exemple #2
0
fx_rtn
fx_cap_dblk(char *name, char *ext, char *n_name, char *n_ext, u32_t size,
	    fat_dir_entry_t **rtn_de) {
    fat_dir_entry_t *de, *n_de;
    u32_t rds, n_rds, o_size, cluster;
    u32_t *fat, fat_sector, fat_offset;

    assert(fx_buf);
    if (strlen(name) != 8 || strlen(ext) != 3 ||
	strlen(n_name) != 8 || strlen(n_ext) != 3)
	return(FX_INTERNAL);

    /* check to see if new name already exists */
    de = f32_get_de(n_name, n_ext, &rds);
    if (de)
	return(FX_EXIST);
    de = f32_get_de(name, ext, &rds);
    if (!de)
	return(FX_NOT_FOUND);
    if (size >= CF_LE_32(de->size))
	return(FX_INTERNAL);
    if (!f32_find_empty(&n_de, &n_rds))
	return(FX_NO_ROOM);
    /*
     * read dir entry of original file and tweak size.
     */
    assert(! ms_read_blk(rds, fx_buf));
    o_size = CF_LE_32(de->size);
    de->size = CT_LE_32(size);
    assert(! ms_write_blk(rds, fx_buf));
    /*
     * compute eof cluster.  write it to eof.
     */
    cluster = (CF_LE_16(de->starthi) << 16) | CF_LE_16(de->start);
    cluster += (size + (FX_CLUSTER_SIZE * SECTOR_SIZE - 1))/(FX_CLUSTER_SIZE * SECTOR_SIZE) - 1;
    fat_sector = FAT_SECTOR(cluster) + fx_fat_start;
    fat_offset = FAT_OFFSET(cluster);
    assert(! ms_read_blk(fat_sector, fx_buf));
    fat = fx_buf;
    fat[fat_offset] = CT_LE_32(EOF_FAT32);
    assert(! ms_write_blk(fat_sector, fx_buf));
    /*
     * now read the directory sector for the new file
     */
    cluster++;
    assert(! ms_read_blk(n_rds, fx_buf));
    memcpy(n_de->name, n_name, 8);
    memcpy(n_de->ext, n_ext, 3);
    n_de->starthi = CT_LE_16(cluster >> 16);
    n_de->start = CT_LE_16(cluster & 0xffff);
    size += (FX_CLUSTER_SIZE * SECTOR_SIZE - 1);
    size &= ~FX_CB_MASK;	/* round up to next cluster */
    n_de->size = CT_LE_32(o_size - size);
    assert(! ms_write_blk(n_rds, fx_buf));
    return(FX_OK);
}
Exemple #3
0
static bool_t
f32_get_chain(u32_t cluster, u32_t *start, u32_t *end) {
    u32_t fat_sector, nxt_cluster;
    uint8_t  fat_offset;
    u32_t *fats;

    *start = 0;
    *end = 0;
    cluster &= FAT32_CLUSTER_MASK;
    if (cluster < 2 || cluster > fx_max_cluster) {
      fprintf(stderr, "*** bad cluster, %lu\n", cluster);
      return(FALSE);
    }
    fat_sector = FAT_SECTOR(cluster);
    fat_sector += fx_fat_start;
    if (fat_sector > fx_fat_end) {
      fprintf(stderr, "*** bad fat sector: %lu\n", fat_sector);
      return(FALSE);
    }
    fat_offset = FAT_OFFSET(cluster);
    assert(!ms_read_blk(fat_sector, fx_buf));
    fats = fx_buf;
    *start = clu2sec(cluster);
    nxt_cluster = CF_LE_32(fats[fat_offset]) & FAT32_CLUSTER_MASK;
    while (nxt_cluster < EOF_FAT32 &&
	   nxt_cluster >= 2 &&
	   nxt_cluster == cluster + 1) {
	cluster++;
	fat_offset++;
	if (fat_offset > FAT_MAX_OFFSET) {
	    fat_sector++;
	    fat_offset = 0;
	    if (fat_sector > fx_fat_end) {
	      fprintf(stderr, "*** fat_sector (%lu) > fx_fat_end (%lu)\n", fat_sector, fx_fat_end);
	      return(FALSE);
	    }
	    assert(!ms_read_blk(fat_sector, fx_buf));
	}
	nxt_cluster = CF_LE_32(fats[fat_offset]) & FAT32_CLUSTER_MASK;
	if (nxt_cluster == BAD_FAT32) {
	  fprintf(stderr, "*** nxt_cluster is BAD_FAT32, %lu\n", nxt_cluster);
	  return(FALSE);
	}
    }
    if (nxt_cluster >= EOF_FAT32) {
	*end = clu2sec(cluster + 1) - 1;
	return(TRUE);
    }
    *start = 0;
    *end = 0;
    return(FALSE);
}
Exemple #4
0
void
display_info(void) {
    fat_dir_entry_t *de;
    u32_t rds;

    fprintf(stderr, "fs_loc:  p:   s: %-8x   e: %x\n",
            loc.locators[FS_LOC_PANIC].start,
            loc.locators[FS_LOC_PANIC].end);
    fprintf(stderr, "         c:   s: %-8x   e: %x\n",
            loc.locators[FS_LOC_CONFIG].start,
            loc.locators[FS_LOC_CONFIG].end);
    fprintf(stderr, "         i:   s: %-8x   e: %x\n",
            loc.locators[FS_LOC_IMAGE].start,
            loc.locators[FS_LOC_IMAGE].end);
    fprintf(stderr, "         d:   s: %-8x   e: %-8x   n: %x\n",
            loc.locators[FS_LOC_DBLK].start,
            loc.locators[FS_LOC_DBLK].end,
            msc_dblk_nxt);

    if (p0c.panic_start)
      fprintf(stderr, "panic0:    p: %-8x %-8x  (nxt) %-8x\n",
	      p0c.panic_start, p0c.panic_end,  p0c.panic_nxt);
    else
      fprintf(stderr, "panic0:   no panic0 block\n");

    de = f32_get_de("PANIC001", "   ", &rds);
    if (de) {
	rds = (CF_LE_16(de->starthi) << 16) | CF_LE_16(de->start);
	fprintf(stderr, "PANIC001:  start  0x%04x  size: %10u (0x%x)\n",
                fx_clu2sec(rds),  CF_LE_32(de->size), CF_LE_32(de->size));
    } else
	fprintf(stderr, "PANIC001: not found\n");
    de = f32_get_de("CNFG0001", "   ", &rds);
    if (de) {
	rds = (CF_LE_16(de->starthi) << 16) | CF_LE_16(de->start);
	fprintf(stderr, "CNFG0001:  start  0x%04x  size: %10u (0x%x)\n",
                fx_clu2sec(rds),  CF_LE_32(de->size), CF_LE_32(de->size));
    } else
	fprintf(stderr, "CNFG0001: not found\n");
    de = f32_get_de("IMAGE001", "   ", &rds);
    if (de) {
	rds = (CF_LE_16(de->starthi) << 16) | CF_LE_16(de->start);
	fprintf(stderr, "IMAGE001:  start  0x%04x  size: %10u (0x%x)\n",
		fx_clu2sec(rds), CF_LE_32(de->size), CF_LE_32(de->size));
    } else
	fprintf(stderr, "IMAGE001: not found\n");
    de = f32_get_de("DBLK0001", "   ", &rds);
    if (de) {
	rds = (CF_LE_16(de->starthi) << 16) | CF_LE_16(de->start);
	fprintf(stderr, "DBLK0001:  start  0x%04x  size: %10u (0x%x)\n",
		fx_clu2sec(rds), CF_LE_32(de->size), CF_LE_32(de->size));
    } else
	fprintf(stderr, "DBLK0001: not found\n");
}
Exemple #5
0
void
display_info(void) {
    fat_dir_entry_t *de;
    u32_t rds;
    
    if (msc.dblk_start) {
      fprintf(stderr, "dblk_loc:  p: %-8x %-8x\n",
              msc.panic_start,  msc.panic_end);
      fprintf(stderr, "           c: %-8x %-8x\n",
              msc.config_start, msc.config_end);
      fprintf(stderr, "           d: %-8x %-8x  (nxt) %-8x\n",
              msc.dblk_start, msc.dblk_end, msc.dblk_nxt);
    }

    if (p0c.panic_start)
      fprintf(stderr, "panic0:    p: %-8x %-8x  (nxt) %-8x\n",
	      p0c.panic_start, p0c.panic_end,  p0c.panic_nxt);
    else
      fprintf(stderr, "panic0:    no panic0 block\n");

    de = f32_get_de("PANIC001", "   ", &rds);
    if (de) {
	rds = (CF_LE_16(de->starthi) << 16) | CF_LE_16(de->start);
	fprintf(stderr, "PANIC001:  start  0x%04x  size: %10u (0x%x)\n",
                fx_clu2sec(rds),  CF_LE_32(de->size), CF_LE_32(de->size));
    } else
	fprintf(stderr, "PANIC001: not found\n");
    de = f32_get_de("CNFG0001", "   ", &rds);
    if (de) {
	rds = (CF_LE_16(de->starthi) << 16) | CF_LE_16(de->start);
	fprintf(stderr, "CNFG0001:  start  0x%04x  size: %10u (0x%x)\n",
                fx_clu2sec(rds),  CF_LE_32(de->size), CF_LE_32(de->size));
    } else
	fprintf(stderr, "CNFG0001: not found\n");
    de = f32_get_de("DBLK0001", "   ", &rds);
    if (de) {
	rds = (CF_LE_16(de->starthi) << 16) | CF_LE_16(de->start);
	fprintf(stderr, "DBLK0001:  start  0x%04x  size: %10u (0x%x)\n",
		fx_clu2sec(rds), CF_LE_32(de->size), CF_LE_32(de->size));
    } else
	fprintf(stderr, "DBLK0001: not found\n");
}
Exemple #6
0
fx_rtn
fx_create_contig(char *name, char *ext, u32_t size, u32_t *s, u32_t *e) {
    u32_t *fat;
    u32_t max, max_count, start, count;
    u32_t fat_sector, i, limit;
    fat_dir_entry_t *de;
    info_sector_t *info;
    uint8_t offset;
    int done;

    assert(fx_buf);
    if (strlen(name) != 8 || strlen(ext) != 3)
	return(FX_INTERNAL);

    if (fx_find_file(name, ext, &start, &count) != FX_NOT_FOUND)
	return(FX_EXIST);

    fat = fx_buf;
    start = count = max = max_count = done = 0;
    for (fat_sector = fx_fat_start; fat_sector <= fx_fat_end; fat_sector++) {
	assert(!ms_read_blk(fat_sector, fx_buf));
	for (i = (fat_sector == fx_fat_start ? 2 : 0);
	       i <= (fat_sector == fx_fat_end ?
		     (fx_max_cluster & FAT32_CPB_MASK) :
		     FAT32_CPB_MASK);
	       i++) {
	    if ((fat[i] & CT_LE_32(FAT32_CLUSTER_MASK)) == 0) {	/* swap constant, compile time */
		switch(start) {
		  case 0:
		      start = ((fat_sector - fx_fat_start) << FAT32_CPB_BITS) + i;
		      count = 1;
		      break;
		  default:
		      count++;
		      if (size && count * FX_CLUSTER_SIZE * SECTOR_SIZE >= size)
			  done = 1;
		      break;
		}
		if (done)
		    break;
	    } else
		switch(start) {
		  case 0:
		      break;
		  default:
		      if (count > max_count) {
			  max = start;
			  max_count = count;
		      }
		      start = count = 0;
		      break;
		}
	}
	if (done)
	    break;
    }
    if (start && count > max_count) {
	max = start;
	max_count = count;
    }
    if (debug) {
	printf("create_contig: size: %lx   s: %lx, count: %lx\n", size, max, max_count);
	printf("               clusters: %lx-%lx, sectors: %lx-%lx, size: %lx\n",
		max, max + max_count - 1, clu2sec(max), clu2sec(max + max_count) - 1,
		max_count * FX_CLUSTER_SIZE * SECTOR_SIZE);
    }
    *s = clu2sec(max);
    *e = clu2sec(max + max_count) - 1;
    if (max == 0)
	return(FX_NO_ROOM);
    assert(max + max_count - 1 <= fx_data_end);
    if (!f32_find_empty(&de, &i))
	return(FX_NO_ROOM);
    memset(de, 0, sizeof(fat_dir_entry_t));
    strncpy((char *) de->name, name, 8);
    strncpy((char *) de->ext, ext, 3);
    de->attr = ATTR_NONE;
    de->starthi = CT_LE_16(max >> 16);
    de->start = CT_LE_16(max & 0xffff);
    de->size = CT_LE_32(max_count * FX_CLUSTER_SIZE * SECTOR_SIZE);
    assert(! ms_write_blk(i, fx_buf));

    /* now rerun through the FAT changing the chain */
    fat_sector = FAT_SECTOR(max) + fx_fat_start;
    offset = FAT_OFFSET(max);
    assert(!ms_read_blk(fat_sector, fx_buf));
    fat = fx_buf;
    limit = max + max_count;		/* one past last */
    for (start = max + 1; start <= limit; start++) {
	fat[offset] = (start == limit ? CT_LE_32(EOF_FAT32) : CT_LE_32(start));
	offset++;
	if (offset > FAT_MAX_OFFSET) {
	    assert(!ms_write_blk(fat_sector, fx_buf));
	    assert(!ms_write_blk(fat_sector + fx_fat_size, fx_buf));
	    fat_sector++;
	    assert(!ms_read_blk(fat_sector, fx_buf));
	    offset = 0;
	}
    }
    if (offset) {
	assert(!ms_write_blk(fat_sector, fx_buf));
	assert(!ms_write_blk(fat_sector + fx_fat_size, fx_buf));
    }
    if (fx_info_sector) {
	assert(!ms_read_blk(fx_info_sector, fx_buf));
	info = fx_buf;
	if (info->boot_sig == CT_LE_16(BOOT_SIG) && IS_FSINFO(info)) {
	    info->free_clusters = CT_LE_32((u32_t) -1);
	    info->next_cluster = CF_LE_32((u32_t) -1);
	    assert(!ms_write_blk(fx_info_sector, fx_buf));
	} else
	    fx_info_sector = 0;
	fx_free_clusters = (u32_t) -1;
	fx_next_cluster  = (u32_t) -1;
    }
    return(FX_OK);
}
Exemple #7
0
fx_rtn
fx_init(void) {
    boot_sector_t *bs;
    info_sector_t *info;
    mbr_t *mbr;
    u32_t start, size;

    assert(fx_buf);
    assert(! ms_read_blk(0, fx_buf));

    /* First sector is either an MBR or the boot_sector of the partition.  It
     * had better have the 2 byte signature at the end.  ie.  0xaa55.
     *
     * Start by looking for a boot sector rather than the MBR.
     */
    bs = fx_buf;
    if (bs->sig != CT_LE_16(BOOT_SIG))
	return(FX_BAD_BOOT_SIG);

    start = fx_data_start = 0;
    if ( ! fat32_boot_sector(bs)) {
	/*
	 * something doesn't look right.  Look at the sector as an MBR and see
	 * if it makes sense.  We only look at partition 1.
	 */
	mbr = fx_buf;
	start = (mbr->p1.start4[3] << 24) | (mbr->p1.start4[2] << 16) |
	    (mbr->p1.start4[1] << 8)      | mbr->p1.start4[0];
	size  = (mbr->p1.size4[3] << 24)  | (mbr->p1.size4[2] << 16)  |
	    (mbr->p1.size4[1] << 8      ) | mbr->p1.size4[0];

	/* check for reasonableness, boot_ind can be 0x00 or 0x80 */
	if ((mbr->p1.boot_ind != 0 && mbr->p1.boot_ind != 0x80) ||
	      !fat32_part(mbr->p1.part_type) ||		/* reasonable fat32 partition? */
	      start == 0 ||				/* can't start at 0 */
	      size == 0)				/* zero means nothing, bail */
	    return(FX_NO_PARTITION);
	
	assert(! ms_read_blk(start, fx_buf));
	bs = fx_buf;
	if (CF_LE_16(bs->sig) != BOOT_SIG)
	    return(FX_BAD_BOOT_SIG);
	if (!fat32_boot_sector(bs))			/* make sure what we got is good */
	    return(FX_NO_PARTITION);
	/* check mbr partition size vs. total_sect entry in the file system header
	   only accept if the same or if file system size is one less than the partition header
	*/
	if (size != CF_LE_32(bs->total_sect)) {		/* and partition size should match internal */
	    if (debug)
		printf("*** mbr/fs size mismatch: mbr: %lu (%lx), fs: %lu (%lx)\n",
		       size, size, CF_LE_32(bs->total_sect), CF_LE_32(bs->total_sect));
	    if (size != CF_LE_32(bs->total_sect) + 1)
		return(FX_SIZE_MISMATCH);
	}
	fx_data_start = start;
    }

    if (debug)
	printf("Partition start: %lx, size: %lx\n",
		(u32_t) fx_data_start, CF_LE_32(bs->total_sect));

    /* buf contains the boot_sector.  compute total data sectors and make
       sure that it conforms to FAT32. */

    fx_cluster_size  = bs->cluster_size;	/* u8 */
    fx_reserved      = CF_LE_16(bs->reserved);
    fx_num_fats      = bs->fats;		/* u8 */
    fx_total_sectors = CF_LE_32(bs->total_sect);
    fx_fat_size      = CF_LE_32(bs->fat32_length);
    fx_info_sector   = start + CF_LE_16(bs->info_sector);

    fx_data_end      = fx_data_start + fx_total_sectors - 1;
    fx_fat_start     = fx_data_start + fx_reserved;
    fx_fat_end	     = fx_fat_start + fx_fat_size - 1;
    fx_data_start    = fx_fat_start + fx_fat_size * FX_NUM_FATS;

    size = fx_total_sectors;
    size -= (fx_reserved + (fx_fat_size * fx_num_fats));
    fx_max_cluster = size/fx_cluster_size;		/* last cluster */

    if (debug)
	printf("phys data sectors: %lx, phys clusters: %lx, unused sectors: %lx\n",
		size,
		fx_max_cluster,
		size - fx_max_cluster * fx_cluster_size);

    if (fx_max_cluster < 65525)				/* if less, not FAT32 */
	return(FX_NOT_FAT32);

    fx_max_cluster++;					/* make into cluster id */
    fx_data_end = clu2sec(fx_max_cluster + 1) - 1;	/* get last usable data sector */

    if (fx_cluster_size != FX_CLUSTER_SIZE)
      fprintf(stderr, "*** bad fx_cluster_size (%u) should be (%u)\n", fx_cluster_size, FX_CLUSTER_SIZE);
    if (fx_num_fats != FX_NUM_FATS)
      fprintf(stderr, "*** wrong number of FATS: (%u) should be (%u)\n", fx_num_fats, FX_NUM_FATS);

    f32_get_chain(CF_LE_32(bs->root_cluster), &fx_rdir_start, &fx_rdir_end);
    assert(fx_rdir_start && fx_rdir_end);

    assert(!ms_read_blk(fx_info_sector, fx_buf));
    info = fx_buf;
    if (info->boot_sig == CT_LE_16(BOOT_SIG) && IS_FSINFO(info)) {
	fx_free_clusters = CF_LE_32(info->free_clusters);
	fx_next_cluster = CF_LE_32(info->next_cluster);
    } else {
	fx_info_sector = 0;
	fx_free_clusters = (u32_t) -1;
	fx_next_cluster  = (u32_t) -1;
    }

    if (debug) {
	printf("ts: %lx, r: %x, fat_s: %lx, n: %d, ds: %lx\n",
		fx_total_sectors, fx_reserved,  fx_fat_size, fx_num_fats,
		fx_total_sectors-fx_reserved-(fx_num_fats*fx_fat_size));
	printf("fat_size (secs): %lx, (clus) %lx, %lx bytes\n",
		fx_fat_size, fx_fat_size * SECTOR_SIZE / sizeof(u32_t),
		fx_fat_size * SECTOR_SIZE);
	printf("data_start: %lx, end: %lx, usable sectors: %lx, last phys sector: %lx\n",
		fx_data_start,
		fx_data_end,
		fx_data_end - fx_data_start + 1,	/* usable */
		fx_data_start + (fx_total_sectors - fx_reserved -
				 (fx_num_fats * fx_fat_size))  - 1);
	printf("unused fat entries: %lx,  cluster ids: 2 - %lx\n",
		(fx_fat_end - fx_fat_start + 1) * FAT32_CPB - (fx_max_cluster + 1),
		    fx_max_cluster);
	printf("Last cluster: %lx,  sectors: %lx - %lx, fat sector: %lx, off: %lx\n",
		fx_max_cluster,
		clu2sec(fx_max_cluster),
		clu2sec(fx_max_cluster + 1) - 1,
		FAT_SECTOR(fx_max_cluster) + fx_fat_start,
		FAT_OFFSET(fx_max_cluster));
	printf("  fat_start: %5lx, fat_end: %5lx\n", fx_fat_start, fx_fat_end);
	printf("  info: free %5lx, next:    %5lx\n", fx_free_clusters, fx_next_cluster);
    }

    return(FX_OK);
}