Пример #1
0
/** @brief Fill sectors with byte.
 *
 * @param[in] fd             File descriptor index.
 * @param[in] start_secror   Sector number to fill to.
 * @param[in] sector_cnt     Number of sectors to fill to.
 * @param[in[ sector_size    Size of sector.
 * @param[in] fill_byte      Byte to fill into sectors.
 *
 * @return 0: OK.
 * @return -1: Error occured. Errno is set to real error value.
 */
static int msdos_format_fill_sectors
(
 int         fd,                       /* IN */
 uint32_t    start_sector,             /* IN */
 uint32_t    sector_cnt,               /* IN */
 uint32_t    sector_size,              /* IN */
 const char  fill_byte                 /* IN */
 )
{
  int ret_val = 0;
  char *fill_buffer = NULL;

  /*
   * allocate and fill buffer
   */
  if (ret_val == 0) {
    fill_buffer = malloc(sector_size);
    if (fill_buffer == NULL) {
      errno = ENOMEM;
      ret_val = -1;
    }
    else {
      memset(fill_buffer,fill_byte,sector_size);
    }
  }
  /*
   * write to consecutive sectors
   */
  while ((ret_val == 0) && 
	 (sector_cnt > 0)) {
    ret_val = msdos_format_write_sec(fd,start_sector,sector_size,fill_buffer);
    start_sector++;
    sector_cnt--;
  }
  /*
   * cleanup
   */
  if (fill_buffer != NULL) {
    free(fill_buffer);
    fill_buffer = NULL;
  }
  return ret_val;
}
Пример #2
0
/*=========================================================================* \
| Function:                                                                 |
\*-------------------------------------------------------------------------*/
static int msdos_format_fill_sectors
(
/*-------------------------------------------------------------------------*\
| Purpose:                                                                  |
|     function to fill sectors with byte                                    |
+---------------------------------------------------------------------------+
| Input Parameters:                                                         |
\*-------------------------------------------------------------------------*/
 const msdos_format_request_param_t *rqdata,
 int         fd,                       /* file descriptor index            */
 uint32_t    start_sector,             /* sector number to fill to         */
 uint32_t    sector_cnt,               /* number of sectors to fill to     */
 uint32_t    sector_size,              /* size of sector                   */
 const char  fill_byte                 /* byte to fill into sectors        */
 )
/*-------------------------------------------------------------------------*\
| Return Value:                                                             |
|    0, if success, -1 and errno if failed                                  |
\*=========================================================================*/
{
  int ret_val = 0;
  char *fill_buffer = NULL;
  uint32_t total_sectors = sector_cnt;
  int last_percent = -1;

  /*
   * allocate and fill buffer
   */
  if (ret_val == 0) {
    fill_buffer = malloc(sector_size);
    if (fill_buffer == NULL) {
      errno = ENOMEM;
      ret_val = -1;
    }
    else {
      memset(fill_buffer,fill_byte,sector_size);
    }
  }

  msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
                       "Filling : ");
  /*
   * write to consecutive sectors
   */
  while ((ret_val == 0) &&
         (sector_cnt > 0)) {
    int percent = (sector_cnt * 100) / total_sectors;
    if (percent != last_percent) {
      if ((percent & 1) == 0)
        msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, ".");
      last_percent = percent;
    }
    ret_val = msdos_format_write_sec(fd,start_sector,sector_size,fill_buffer);
    start_sector++;
    sector_cnt--;
  }

  msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, "\n");

  if (ret_val)
    msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_INFO,
                         "filling error on sector: %d\n", start_sector);

  /*
   * cleanup
   */
  if (fill_buffer != NULL) {
    free(fill_buffer);
    fill_buffer = NULL;
  }
  return ret_val;
}
Пример #3
0
/*=========================================================================*\
| Function:                                                                 |
\*-------------------------------------------------------------------------*/
int msdos_format
(
/*-------------------------------------------------------------------------*\
| Purpose:                                                                  |
|     format device with msdos filesystem                                   |
+---------------------------------------------------------------------------+
| Input Parameters:                                                         |
\*-------------------------------------------------------------------------*/
 const char *devname,                  /* device name                      */
 const msdos_format_request_param_t *rqdata  /* requested fmt parameters   */
                                             /* set to NULL for automatic  */
                                             /* determination              */
 )
/*-------------------------------------------------------------------------*\
| Return Value:                                                             |
|    0, if success, -1 and errno if failed                                  |
\*=========================================================================*/
{
  char                 tmp_sec[FAT_TOTAL_MBR_SIZE];
  struct stat          stat_buf;
  int                  ret_val   = 0;
  int                  fd        = -1;
  int                  i;
  msdos_format_param_t fmt_params;

  /*
   * open device for writing
   */
  msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, "open device\n");
  fd = open(devname, O_RDWR);
  if (fd == -1) {
    ret_val= -1;
  }

  /*
   * sanity check on device
   */
  msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
                       "stat check: %s\n", devname);
  if (ret_val == 0) {
    ret_val = fstat(fd, &stat_buf);
  }

  msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_INFO,
                       "formating: %s\n", devname);
  /* rtems feature: no block devices, all are character devices */
  if ((ret_val == 0) && (!S_ISBLK(stat_buf.st_mode))) {
    errno = ENOTTY;
    ret_val = -1;
  }

  /*
   * compute formatting parameters
   */
  if (ret_val == 0) {
    ret_val = msdos_format_determine_fmt_params(fd,rqdata,&fmt_params);
  }
  /*
   * if requested, write whole disk/partition with 0xe5
   */
  if ((ret_val == 0) &&
      (rqdata != NULL) &&
      !(rqdata->quick_format)) {
    ret_val = msdos_format_fill_sectors
      (rqdata,
       fd,
       0,                            /* start sector */
       fmt_params.totl_sector_cnt,   /* sector count */
       fmt_params.bytes_per_sector,
       0xe5);
  }

  /*
   * create master boot record
   */
  if (ret_val == 0) {
    /*
     * Read the current MBR to obtain the partition table.
     */
    msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
                         "read MRB sector\n");
    ret_val = msdos_format_read_sec(fd,
                                    0,
                                    fmt_params.bytes_per_sector,
                                    tmp_sec);
    if (ret_val == 0) {
      msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
                           "generate MRB sector\n");
      ret_val = msdos_format_gen_mbr(tmp_sec,&fmt_params);
    }

    /*
     * write master boot record to disk
     * also write copy of MBR to disk
     */
    if (ret_val == 0) {
      msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
                           "write MRB sector\n");
      ret_val = msdos_format_write_sec(fd,
                                       0,
                                       fmt_params.bytes_per_sector,
                                       tmp_sec);
    }
    if ((ret_val == 0) &&
        (fmt_params.mbr_copy_sec != 0)) {
      /*
       * write copy of MBR
       */
      msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
                           "write back up MRB sector\n");
      ret_val = msdos_format_write_sec(fd,
                                       fmt_params.mbr_copy_sec ,
                                       fmt_params.bytes_per_sector,
                                       tmp_sec);
    }
  }
  /*
   * for FAT32: initialize info sector on disk
   */
  if ((ret_val == 0) &&
      (fmt_params.fsinfo_sec != 0)) {
      ret_val = msdos_format_gen_fsinfo(tmp_sec);
  }
  /*
   * write fsinfo sector
   */
  if ((ret_val == 0) &&
      (fmt_params.fsinfo_sec != 0)) {
    ret_val = msdos_format_write_sec(fd,
                                     fmt_params.fsinfo_sec,
                                     fmt_params.bytes_per_sector,
                                     tmp_sec);
  }
  /*
   * write FAT as all empty
   * -> write all FAT sectors as zero
   */
  if (ret_val == 0) {
    ret_val = msdos_format_fill_sectors
      (rqdata,
       fd,
       fmt_params.rsvd_sector_cnt,                   /* start sector */
       fmt_params.fat_num*fmt_params.sectors_per_fat,/* sector count */
       fmt_params.bytes_per_sector,
       0x00);
  }
  /*
   * clear/init root directory
   * -> write all directory sectors as 0x00
   */
  if (ret_val == 0) {
    ret_val = msdos_format_fill_sectors
      (rqdata,
       fd,
       fmt_params.root_dir_start_sec,        /* start sector */
       fmt_params.root_dir_fmt_sec_cnt,      /* sector count */
       fmt_params.bytes_per_sector,
       0x00);
  }
  /*
   * write volume label to first entry of directory
   */
  if ((ret_val == 0) && fmt_params.VolLabel_present) {
    memset(tmp_sec,0,sizeof(tmp_sec));
    memcpy(MSDOS_DIR_NAME(tmp_sec),fmt_params.VolLabel,MSDOS_SHORT_NAME_LEN);
    *MSDOS_DIR_ATTR(tmp_sec) = MSDOS_ATTR_VOLUME_ID;
    ret_val = msdos_format_write_sec
      (fd,
       fmt_params.root_dir_start_sec,
       fmt_params.bytes_per_sector,
       tmp_sec);
  }
  /*
   * write FAT entry 0 as (0xffffff00|Media_type)EOC,
   * write FAT entry 1 as EOC
   * allocate directory in a FAT32 FS
   */
  if (ret_val == 0) {
    uint32_t start_sector;

    /*
     * empty sector: all clusters are free/do not link further on
     */
    memset(tmp_sec,0,sizeof(tmp_sec));

    switch(fmt_params.fattype) {
    case FAT_FAT12:
      /* LSBits of FAT entry 0: media_type */
      FAT_SET_VAL8(tmp_sec,0,(fmt_params.media_code));
      /* MSBits of FAT entry 0:0xf, LSBits of FAT entry 1: LSB of EOC */
      FAT_SET_VAL8(tmp_sec,1,(0x0f | (FAT_FAT12_EOC << 4)));
      /* MSBits of FAT entry 1: MSBits of EOC */
      FAT_SET_VAL8(tmp_sec,2,(FAT_FAT12_EOC >> 4));
      break;

    case FAT_FAT16:
      /* FAT entry 0: 0xff00|media_type */
      FAT_SET_VAL8(tmp_sec,0,fmt_params.media_code);
      FAT_SET_VAL8(tmp_sec,1,0xff);
      /* FAT entry 1: EOC */
      FAT_SET_VAL16(tmp_sec,2,FAT_FAT16_EOC);
      break;

    case FAT_FAT32:
      /* FAT entry 0: 0xffffff00|media_type */
      FAT_SET_VAL32(tmp_sec,0,0xffffff00|fmt_params.media_code);
      /* FAT entry 1: Not dirty, no IO error, EOC */
      FAT_SET_VAL32(tmp_sec,4,0xc0000000|FAT_FAT32_EOC);
      break;

    default:
      ret_val = -1;
      errno = EINVAL;
    }
    if (fmt_params.fattype == FAT_FAT32) {
      /*
       * only first valid cluster (cluster number 2) belongs
       * to root directory, and is end of chain
       * mark this in every copy of the FAT
       */
      FAT_SET_VAL32(tmp_sec,8,FAT_FAT32_EOC);
    }

    start_sector = loc_align_object (fmt_params.rsvd_sector_cnt,
                                     fmt_params.sectors_per_cluster,
                                     fmt_params.skip_alignment);
    for (i = 0;
         (i < fmt_params.fat_num) && (ret_val == 0);
         i++) {
      ret_val = msdos_format_write_sec
        (fd,
         start_sector
         + (i * fmt_params.sectors_per_fat),
         fmt_params.bytes_per_sector,
         tmp_sec);
    }
  }