Changes in uspace/app/mkfat/mkfat.c [8d2dd7f2:2456fd0] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/mkfat/mkfat.c
r8d2dd7f2 r2456fd0 38 38 */ 39 39 40 #include <ctype.h> 40 41 #include <stdio.h> 41 42 #include <stdlib.h> … … 45 46 #include <loc.h> 46 47 #include <byteorder.h> 47 #include <sys/typefmt.h>48 48 #include <inttypes.h> 49 49 #include <errno.h> 50 50 #include "fat.h" 51 #include "fat_dentry.h" 51 52 52 53 #define NAME "mkfat" 54 55 #define LABEL_NONAME "NO NAME" 53 56 54 57 /** Divide and round up. */ … … 78 81 uint32_t total_clusters; 79 82 uint8_t fat_count; 83 const char *label; 80 84 } fat_cfg_t; 81 85 … … 103 107 cfg.root_ent_max = 128; 104 108 cfg.fat_type = FATAUTO; 109 cfg.label = NULL; 105 110 106 111 if (argc < 2) { … … 111 116 112 117 --argc; ++argv; 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; 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; 119 136 } 120 137 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; 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; 126 154 } 127 155 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; 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; 137 167 } 138 168 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; 169 if (str_cmp(*argv, "-") == 0) { 170 --argc; ++argv; 171 break; 144 172 } 145 146 --argc; ++argv;147 173 } 148 174 … … 195 221 } 196 222 197 printf(NAME ": Creating FAT %d filesystem on device %s.\n", cfg.fat_type, dev_path);223 printf(NAME ": Creating FAT filesystem on device %s.\n", dev_path); 198 224 199 225 rc = fat_params_compute(&cfg); … … 203 229 } 204 230 231 printf(NAME ": Filesystem type FAT%d.\n", cfg.fat_type); 232 205 233 rc = fat_blocks_write(&cfg, service_id); 206 234 if (rc != EOK) { … … 217 245 static void syntax_print(void) 218 246 { 219 printf("syntax: mkfat [--size <sectors>] [--type 12|16|32] <device_name>\n"); 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; 220 279 } 221 280 … … 228 287 { 229 288 uint32_t fat_bytes; 289 uint32_t non_data_sectors_lb_16; 230 290 uint32_t non_data_sectors_lb; 291 uint32_t rd_sectors; 292 uint32_t tot_clust_16; 231 293 232 294 /* … … 234 296 * system. The optimum could be potentially smaller since we 235 297 * do not subtract size of the FAT itself when computing the 236 * size of the data region. 298 * size of the data region. Also the root dir area might not 299 * need FAT entries if we decide to make a FAT32. 237 300 */ 238 301 239 302 cfg->reserved_sectors = 1 + cfg->addt_res_sectors; 240 if (cfg->fat_type != FAT32) { 241 cfg->rootdir_sectors = div_round_up(cfg->root_ent_max * DIRENT_SIZE,242 cfg->sector_size);243 } else244 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,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, 248 311 cfg->sectors_per_cluster); 249 312 250 if (cfg->total_clusters <= FAT12_CLST_MAX) { 313 /* Now detect FAT type */ 314 if (tot_clust_16 <= FAT12_CLST_MAX) { 251 315 if (cfg->fat_type == FATAUTO) 252 316 cfg->fat_type = FAT12; 253 317 else if (cfg->fat_type != FAT12) 254 318 return EINVAL; 255 } else if ( cfg->total_clusters<= FAT16_CLST_MAX) {319 } else if (tot_clust_16 <= FAT16_CLST_MAX) { 256 320 if (cfg->fat_type == FATAUTO) 257 321 cfg->fat_type = FAT16; … … 265 329 } 266 330 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 267 347 fat_bytes = div_round_up((cfg->total_clusters + 2) * 268 348 FAT_CLUSTER_DOUBLE_SIZE(cfg->fat_type), 2); 269 349 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; 270 353 271 354 return EOK; … … 281 364 int rc; 282 365 struct fat_bs bs; 366 fat_dentry_t *de; 283 367 284 368 fat_bootsec_create(cfg, &bs); … … 340 424 printf("Writing root directory.\n"); 341 425 memset(buffer, 0, cfg->sector_size); 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; 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); 350 439 } 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 } 440 441 rc = block_write_direct(service_id, addr, 1, buffer); 442 if (rc != EOK) 443 return EIO; 444 445 ++addr; 359 446 } 360 447 … … 367 454 static void fat_bootsec_create(struct fat_cfg const *cfg, struct fat_bs *bs) 368 455 { 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; 369 466 memset(bs, 0, sizeof(*bs)); 370 467 … … 405 502 bs->fat32.root_cluster = 2; 406 503 407 memcpy(bs->fat32.label, "HELENOS_NEW", 11);504 (void) fat_label_encode(&bs->fat32.label, bs_label); 408 505 memcpy(bs->fat32.type, "FAT32 ", 8); 409 506 } else { … … 413 510 bs->id = host2uint32_t_be(0x12345678); 414 511 415 memcpy(bs->label, "HELENOS_NEW", 11); 416 memcpy(bs->type, "FAT ", 8); 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); 417 517 } 418 518 }
Note:
See TracChangeset
for help on using the changeset viewer.