Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/mkfat/mkfat.c

    r2456fd0 r8d2dd7f2  
    3838 */
    3939
    40 #include <ctype.h>
    4140#include <stdio.h>
    4241#include <stdlib.h>
     
    4645#include <loc.h>
    4746#include <byteorder.h>
     47#include <sys/typefmt.h>
    4848#include <inttypes.h>
    4949#include <errno.h>
    5050#include "fat.h"
    51 #include "fat_dentry.h"
    5251
    5352#define NAME    "mkfat"
    54 
    55 #define LABEL_NONAME "NO NAME"
    5653
    5754/** Divide and round up. */
     
    8178        uint32_t total_clusters;
    8279        uint8_t fat_count;
    83         const char *label;
    8480} fat_cfg_t;
    8581
     
    107103        cfg.root_ent_max = 128;
    108104        cfg.fat_type = FATAUTO;
    109         cfg.label = NULL;
    110105
    111106        if (argc < 2) {
     
    116111
    117112        --argc; ++argv;
    118 
    119         while (*argv[0] == '-') {
    120                 if (str_cmp(*argv, "--size") == 0) {
    121                         --argc; ++argv;
    122                         if (*argv == NULL) {
    123                                 printf(NAME ": Error, argument missing.\n");
    124                                 syntax_print();
    125                                 return 1;
    126                         }
    127 
    128                         cfg.total_sectors = strtol(*argv, &endptr, 10);
    129                         if (*endptr != '\0') {
    130                                 printf(NAME ": Error, invalid argument.\n");
    131                                 syntax_print();
    132                                 return 1;
    133                         }
    134 
    135                         --argc; ++argv;
    136                 }
    137 
    138                 if (str_cmp(*argv, "--type") == 0) {
    139                         --argc; ++argv;
    140                         if (*argv == NULL) {
    141                                 printf(NAME ": Error, argument missing.\n");
    142                                 syntax_print();
    143                                 return 1;
    144                         }
    145 
    146                         cfg.fat_type = strtol(*argv, &endptr, 10);
    147                         if (*endptr != '\0') {
    148                                 printf(NAME ": Error, invalid argument.\n");
    149                                 syntax_print();
    150                                 return 1;
    151                         }
    152 
    153                         --argc; ++argv;
    154                 }
    155 
    156                 if (str_cmp(*argv, "--label") == 0) {
    157                         --argc; ++argv;
    158                         if (*argv == NULL) {
    159                                 printf(NAME ": Error, argument missing.\n");
    160                                 syntax_print();
    161                                 return 1;
    162                         }
    163 
    164                         cfg.label = *argv;
    165 
    166                         --argc; ++argv;
    167                 }
    168 
    169                 if (str_cmp(*argv, "-") == 0) {
    170                         --argc; ++argv;
    171                         break;
    172                 }
     113        if (str_cmp(*argv, "--size") == 0) {
     114                --argc; ++argv;
     115                if (*argv == NULL) {
     116                        printf(NAME ": Error, argument missing.\n");
     117                        syntax_print();
     118                        return 1;
     119                }
     120
     121                cfg.total_sectors = strtol(*argv, &endptr, 10);
     122                if (*endptr != '\0') {
     123                        printf(NAME ": Error, invalid argument.\n");
     124                        syntax_print();
     125                        return 1;
     126                }
     127
     128                --argc; ++argv;
     129        }
     130
     131        if (str_cmp(*argv, "--type") == 0) {
     132                --argc; ++argv;
     133                if (*argv == NULL) {
     134                        printf(NAME ": Error, argument missing.\n");
     135                        syntax_print();
     136                        return 1;
     137                }
     138
     139                cfg.fat_type = strtol(*argv, &endptr, 10);
     140                if (*endptr != '\0') {
     141                        printf(NAME ": Error, invalid argument.\n");
     142                        syntax_print();
     143                        return 1;
     144                }
     145
     146                --argc; ++argv;
    173147        }
    174148
     
    221195        }
    222196
    223         printf(NAME ": Creating FAT filesystem on device %s.\n", dev_path);
     197        printf(NAME ": Creating FAT%d filesystem on device %s.\n", cfg.fat_type, dev_path);
    224198
    225199        rc = fat_params_compute(&cfg);
     
    229203        }
    230204
    231         printf(NAME ": Filesystem type FAT%d.\n", cfg.fat_type);
    232 
    233205        rc = fat_blocks_write(&cfg, service_id);
    234206        if (rc != EOK) {
     
    245217static void syntax_print(void)
    246218{
    247         printf("syntax: mkfat [<options>...] <device_name>\n");
    248         printf("options:\n"
    249             "\t--size <sectors> Filesystem size, overrides device size\n"
    250             "\t--type 12|16|32  FAT type (auto-detected by default)\n"
    251             "\t--label <label>  Volume label\n");
    252 }
    253 
    254 static int fat_label_encode(void *dest, const char *src)
    255 {
    256         int i;
    257         const char *sp;
    258         uint8_t *dp;
    259 
    260         i = 0;
    261         sp = src;
    262         dp = (uint8_t *)dest;
    263 
    264         while (*sp != '\0' && i < FAT_VOLLABEL_LEN) {
    265                 if (!ascii_check(*sp))
    266                         return EINVAL;
    267                 if (dp != NULL)
    268                         dp[i] = toupper(*sp);
    269                 ++i; ++sp;
    270         }
    271 
    272         while (i < FAT_VOLLABEL_LEN) {
    273                 if (dp != NULL)
    274                         dp[i] = FAT_PAD;
    275                 ++i;
    276         }
    277 
    278         return EOK;
     219        printf("syntax: mkfat [--size <sectors>] [--type 12|16|32] <device_name>\n");
    279220}
    280221
     
    287228{
    288229        uint32_t fat_bytes;
    289         uint32_t non_data_sectors_lb_16;
    290230        uint32_t non_data_sectors_lb;
    291         uint32_t rd_sectors;
    292         uint32_t tot_clust_16;
    293231
    294232        /*
     
    296234         * system. The optimum could be potentially smaller since we
    297235         * do not subtract size of the FAT itself when computing the
    298          * size of the data region. Also the root dir area might not
    299          * need FAT entries if we decide to make a FAT32.
     236         * size of the data region.
    300237         */
    301238
    302239        cfg->reserved_sectors = 1 + cfg->addt_res_sectors;
    303 
    304         /* Only correct for FAT12/16 (FAT32 has root dir stored in clusters */
    305         rd_sectors = div_round_up(cfg->root_ent_max * DIRENT_SIZE,
    306                 cfg->sector_size);
    307         non_data_sectors_lb_16 = cfg->reserved_sectors + rd_sectors;
    308 
    309         /* Only correct for FAT12/16 */
    310         tot_clust_16 = div_round_up(cfg->total_sectors - non_data_sectors_lb_16,
     240        if (cfg->fat_type != FAT32) {
     241                cfg->rootdir_sectors = div_round_up(cfg->root_ent_max * DIRENT_SIZE,
     242                        cfg->sector_size);
     243        } else
     244                cfg->rootdir_sectors = 0;
     245        non_data_sectors_lb = cfg->reserved_sectors + cfg->rootdir_sectors;
     246
     247        cfg->total_clusters = div_round_up(cfg->total_sectors - non_data_sectors_lb,
    311248            cfg->sectors_per_cluster);
    312249
    313         /* Now detect FAT type */
    314         if (tot_clust_16 <= FAT12_CLST_MAX) {
     250        if (cfg->total_clusters <= FAT12_CLST_MAX) {
    315251                if (cfg->fat_type == FATAUTO)
    316252                        cfg->fat_type = FAT12;
    317253                else if (cfg->fat_type != FAT12)
    318254                        return EINVAL;
    319         } else if (tot_clust_16 <= FAT16_CLST_MAX) {
     255        } else if (cfg->total_clusters <= FAT16_CLST_MAX) {
    320256                if (cfg->fat_type == FATAUTO)
    321257                        cfg->fat_type = FAT16;
     
    329265        }
    330266
    331         /* Actual root directory size, non-data sectors */
    332         if (cfg->fat_type != FAT32) {
    333                 cfg->rootdir_sectors = div_round_up(cfg->root_ent_max * DIRENT_SIZE,
    334                         cfg->sector_size);
    335                 non_data_sectors_lb = cfg->reserved_sectors + cfg->rootdir_sectors;
    336 
    337         } else {
    338                 /* We create a single-cluster root dir */
    339                 cfg->rootdir_sectors = cfg->sectors_per_cluster;
    340                 non_data_sectors_lb = cfg->reserved_sectors;
    341         }
    342 
    343         /* Actual total number of clusters */
    344         cfg->total_clusters = div_round_up(cfg->total_sectors - non_data_sectors_lb,
    345             cfg->sectors_per_cluster);
    346 
    347267        fat_bytes = div_round_up((cfg->total_clusters + 2) *
    348268            FAT_CLUSTER_DOUBLE_SIZE(cfg->fat_type), 2);
    349269        cfg->fat_sectors = div_round_up(fat_bytes, cfg->sector_size);
    350 
    351         if (cfg->label != NULL && fat_label_encode(NULL, cfg->label) != EOK)
    352                 return EINVAL;
    353270
    354271        return EOK;
     
    364281        int rc;
    365282        struct fat_bs bs;
    366         fat_dentry_t *de;
    367283
    368284        fat_bootsec_create(cfg, &bs);
     
    424340        printf("Writing root directory.\n");
    425341        memset(buffer, 0, cfg->sector_size);
    426         de = (fat_dentry_t *)buffer;
    427         size_t idx;
    428         for (idx = 0; idx < cfg->rootdir_sectors; ++idx) {
    429 
    430                 if (idx == 0 && cfg->label != NULL) {
    431                         /* Set up volume label entry */
    432                         (void) fat_label_encode(&de->name, cfg->label);
    433                         de->attr = FAT_ATTR_VOLLABEL;
    434                         de->mtime = 0x1234;
    435                         de->mdate = 0x1234;
    436                 } else if (idx == 1) {
    437                         /* Clear volume label entry */
    438                         memset(buffer, 0, cfg->sector_size);
    439                 }
    440 
    441                 rc = block_write_direct(service_id, addr, 1, buffer);
    442                 if (rc != EOK)
    443                         return EIO;
    444 
    445                 ++addr;
     342        if (cfg->fat_type != FAT32) {
     343                size_t idx;
     344                for (idx = 0; idx < cfg->rootdir_sectors; ++idx) {
     345                        rc = block_write_direct(service_id, addr, 1, buffer);
     346                        if (rc != EOK)
     347                                return EIO;
     348
     349                        ++addr;
     350                }
     351        } else {
     352                for (i = 0; i < cfg->sectors_per_cluster; i++) {
     353                        rc = block_write_direct(service_id, addr, 1, buffer);
     354                        if (rc != EOK)
     355                                return EIO;
     356
     357                        ++addr;
     358                }       
    446359        }
    447360
     
    454367static void fat_bootsec_create(struct fat_cfg const *cfg, struct fat_bs *bs)
    455368{
    456         const char *bs_label;
    457 
    458         /*
    459          * The boot sector must always contain a valid label. If there
    460          * is no label, there should be 'NO NAME'
    461          */
    462         if (cfg->label != NULL)
    463                 bs_label = cfg->label;
    464         else
    465                 bs_label = LABEL_NONAME;
    466369        memset(bs, 0, sizeof(*bs));
    467370
     
    502405                bs->fat32.root_cluster = 2;
    503406
    504                 (void) fat_label_encode(&bs->fat32.label, bs_label);
     407                memcpy(bs->fat32.label, "HELENOS_NEW", 11);
    505408                memcpy(bs->fat32.type, "FAT32   ", 8);
    506409        } else {
     
    510413                bs->id = host2uint32_t_be(0x12345678);
    511414
    512                 (void) fat_label_encode(&bs->label, bs_label);
    513                 if (cfg->fat_type == FAT12)
    514                         memcpy(bs->type, "FAT12   ", 8);
    515                 else
    516                         memcpy(bs->type, "FAT16   ", 8);
     415                memcpy(bs->label, "HELENOS_NEW", 11);
     416                memcpy(bs->type, "FAT   ", 8);
    517417        }
    518418}
Note: See TracChangeset for help on using the changeset viewer.