source: mainline/uspace/app/mkexfat/mkexfat.c@ 89a0a827

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 89a0a827 was 89a0a827, checked in by Maurizio Lombardi <m.lombardi85@…>, 14 years ago

mkexfat: write the upcase table to disk

  • Property mode set to 100644
File size: 16.8 KB
RevLine 
[dd22cc4]1/*
2 * Copyright (c) 2012 Maurizio Lombardi
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup fs
30 * @{
31 */
32
33/**
34 * @file mkexfat.c
35 * @brief Tool for creating new exFAT file systems.
36 *
37 */
38
39#include <stdio.h>
40#include <libblock.h>
[ffee7bf]41#include <assert.h>
42#include <errno.h>
[50e754e]43#include <malloc.h>
[ffee7bf]44#include <byteorder.h>
[6cf9aeb]45#include <align.h>
[ffee7bf]46#include <sys/types.h>
47#include <sys/typefmt.h>
48#include "exfat.h"
[367014a]49#include "upcase.h"
[dd22cc4]50
51#define NAME "mkexfat"
52
[9744f2d]53/** First sector of the FAT */
54#define FAT_SECTOR_START 128
55
[55dbaeb]56/** First sector of the Main Extended Boot Region */
57#define EBS_SECTOR_START 1
58
[dabe1664]59/** First sector of the Main Extended Boot Region Backup */
60#define EBS_BACKUP_SECTOR_START 13
61
[3938375]62/** First sector of the Main Boot Sector */
63#define MBS_SECTOR 0
[dabe1664]64
[3938375]65/** First sector of the Main Boot Sector Backup */
66#define MBS_BACKUP_SECTOR 12
[dabe1664]67
[55dbaeb]68/** Size of the Main Extended Boot Region */
69#define EBS_SIZE 8
70
[9744f2d]71/** Divide and round up. */
72#define div_round_up(a, b) (((a) + (b) - 1) / (b))
73
[ffee7bf]74/** The default size of each cluster is 4096 byte */
75#define DEFAULT_CLUSTER_SIZE 4096
76
[78de7be2]77/** Index of the first free cluster on the device */
78#define FIRST_FREE_CLUSTER 2
79
[9744f2d]80typedef struct exfat_cfg {
[ffee7bf]81 aoff64_t volume_start;
82 aoff64_t volume_count;
[6cf9aeb]83 unsigned long fat_sector_count;
84 unsigned long data_start_sector;
85 unsigned long rootdir_cluster;
[557e5b13]86 unsigned long upcase_table_cluster;
[6cf9aeb]87 unsigned long total_clusters;
[6aeab59c]88 unsigned long allocated_clusters;
89 size_t bitmap_size;
[ffee7bf]90 size_t sector_size;
91 size_t cluster_size;
[9744f2d]92} exfat_cfg_t;
93
[dabe1664]94
95static unsigned log2(unsigned n);
96
97static uint32_t
98vbr_checksum_start(void const *octets, size_t nbytes);
99
100static void
101vbr_checksum_update(void const *octets, size_t nbytes, uint32_t *checksum);
102
103static int
104ebs_write(service_id_t service_id, exfat_cfg_t *cfg,
105 int base, uint32_t *chksum);
106
[6aeab59c]107static int
108bitmap_write(service_id_t service_id, exfat_cfg_t *cfg);
109
[116cb91]110static void usage(void)
111{
112 printf("Usage: mkexfat <device>\n");
113}
114
[9744f2d]115/** Initialize the exFAT params structure.
116 *
117 * @param cfg Pointer to the exFAT params structure to initialize.
118 */
119static void
120cfg_params_initialize(exfat_cfg_t *cfg)
121{
[5dbd696]122 unsigned long fat_bytes;
123 aoff64_t const volume_bytes = (cfg->volume_count - FAT_SECTOR_START) *
124 cfg->sector_size;
[ffee7bf]125
126 aoff64_t n_req_clusters = volume_bytes / DEFAULT_CLUSTER_SIZE;
127 cfg->cluster_size = DEFAULT_CLUSTER_SIZE;
128
129 /* Compute the required cluster size to index
[e15f4d5]130 * the entire storage device and to keep the FAT
131 * size less or equal to 64 Mb.
[ffee7bf]132 */
[e15f4d5]133 while (n_req_clusters > 16000000ULL &&
[ffee7bf]134 (cfg->cluster_size < 32 * 1024 * 1024)) {
135
136 cfg->cluster_size <<= 1;
137 n_req_clusters = volume_bytes / cfg->cluster_size;
138 }
[5dbd696]139
[e15f4d5]140 /* The first two clusters are reserved */
[6cf9aeb]141 cfg->total_clusters = n_req_clusters + 2;
[5dbd696]142
143 /* Compute the FAT size in sectors */
144 fat_bytes = (cfg->total_clusters + 1) * 4;
145 cfg->fat_sector_count = div_round_up(fat_bytes, cfg->sector_size);
[f8973122]146
[6cf9aeb]147 /* Compute the number of the first data sector */
148 cfg->data_start_sector = ROUND_UP(FAT_SECTOR_START +
149 cfg->fat_sector_count, cfg->cluster_size / cfg->sector_size);
150
[6aeab59c]151 /* Compute the bitmap size */
152 cfg->bitmap_size = n_req_clusters / 8;
153
[a69e396]154 /* Compute the number of clusters reserved to the bitmap */
[6aeab59c]155 cfg->allocated_clusters = div_round_up(cfg->bitmap_size,
156 cfg->cluster_size);
157
158 /* This account for the root directory */
159 cfg->allocated_clusters++;
[a69e396]160
161 /* Compute the number of clusters reserved to the upcase table */
162 cfg->allocated_clusters += div_round_up(sizeof(upcase_table),
163 cfg->cluster_size);
[6aeab59c]164
[89a0a827]165 /* Will be set later */
[6cf9aeb]166 cfg->rootdir_cluster = 0;
167
[f8973122]168 /* The first sector of the partition is zero */
169 cfg->volume_start = 0;
[9744f2d]170}
171
[6cf9aeb]172/** Prints the exFAT structure values
173 *
174 * @param cfg Pointer to the exfat_cfg_t structure.
175 */
176static void
177cfg_print_info(exfat_cfg_t *cfg)
178{
179 printf(NAME ": Sector size: %lu\n", cfg->sector_size);
180 printf(NAME ": Cluster size: %lu\n", cfg->cluster_size);
181 printf(NAME ": FAT size in sectors: %lu\n", cfg->fat_sector_count);
182 printf(NAME ": Data start sector: %lu\n", cfg->data_start_sector);
183 printf(NAME ": Total num of clusters: %lu\n", cfg->total_clusters);
[7f381e5]184 printf(NAME ": Bitmap size: %lu\n",
185 div_round_up(cfg->bitmap_size, cfg->cluster_size));
186 printf(NAME ": Upcase table size: %lu\n",
187 div_round_up(sizeof(upcase_table), cfg->cluster_size));
[6cf9aeb]188}
189
[3938375]190/** Initialize the Main Boot Sector fields.
[9744f2d]191 *
[3938375]192 * @param mbs Pointer to the Main Boot Sector structure.
[9744f2d]193 * @param cfg Pointer to the exFAT configuration structure.
[dabe1664]194 * @return Initial checksum value.
[9744f2d]195 */
[dabe1664]196static uint32_t
[3938375]197vbr_initialize(exfat_bs_t *mbs, exfat_cfg_t *cfg)
[9744f2d]198{
199 /* Fill the structure with zeroes */
[3938375]200 memset(mbs, 0, sizeof(exfat_bs_t));
[9744f2d]201
202 /* Init Jump Boot section */
[3938375]203 mbs->jump[0] = 0xEB;
204 mbs->jump[1] = 0x76;
205 mbs->jump[2] = 0x90;
[9744f2d]206
207 /* Set the filesystem name */
[3938375]208 memcpy(mbs->oem_name, "EXFAT ", sizeof(mbs->oem_name));
[9744f2d]209
[3938375]210 mbs->volume_start = host2uint64_t_le(cfg->volume_start);
211 mbs->volume_count = host2uint64_t_le(cfg->volume_count);
212 mbs->fat_sector_start = host2uint32_t_le(FAT_SECTOR_START);
213 mbs->fat_sector_count = host2uint32_t_le(cfg->fat_sector_count);
214 mbs->data_start_sector = host2uint32_t_le(cfg->data_start_sector);
[6cf9aeb]215
[3938375]216 mbs->data_clusters = host2uint32_t_le(cfg->total_clusters -
[6cf9aeb]217 div_round_up(cfg->data_start_sector, cfg->cluster_size));
218
[557e5b13]219 mbs->rootdir_cluster = host2uint32_t_le(cfg->rootdir_cluster);
[3938375]220 mbs->volume_serial = 0;
221 mbs->version.major = 1;
222 mbs->version.minor = 0;
223 mbs->volume_flags = host2uint16_t_le(0);
224 mbs->bytes_per_sector = log2(cfg->sector_size);
225 mbs->sec_per_cluster = log2(cfg->cluster_size / cfg->sector_size);
[ffee7bf]226
227 /* Maximum cluster size is 32 Mb */
[3938375]228 assert((mbs->bytes_per_sector + mbs->sec_per_cluster) <= 25);
[ffee7bf]229
[3938375]230 mbs->fat_count = 1;
231 mbs->drive_no = 0x80;
232 mbs->allocated_percent = 0;
233 mbs->signature = host2uint16_t_le(0xAA55);
[dabe1664]234
[3938375]235 return vbr_checksum_start(mbs, sizeof(exfat_bs_t));
[dabe1664]236}
237
238static int
239bootsec_write(service_id_t service_id, exfat_cfg_t *cfg)
240{
[3938375]241 exfat_bs_t mbs;
[dabe1664]242 uint32_t vbr_checksum;
243 uint32_t initial_checksum;
244 int rc;
245
[3938375]246 vbr_checksum = vbr_initialize(&mbs, cfg);
[dabe1664]247 initial_checksum = vbr_checksum;
248
[3938375]249 /* Write the Main Boot Sector to disk */
250 rc = block_write_direct(service_id, MBS_SECTOR, 1, &mbs);
[dabe1664]251 if (rc != EOK)
252 return rc;
253
[3938375]254 /* Write the Main extended boot sectors to disk */
255 rc = ebs_write(service_id, cfg, EBS_SECTOR_START, &vbr_checksum);
[dabe1664]256 if (rc != EOK)
257 return rc;
258
[3938375]259 /* Write the Main Boot Sector backup to disk */
260 rc = block_write_direct(service_id, MBS_BACKUP_SECTOR, 1, &mbs);
[dabe1664]261 if (rc != EOK)
262 return rc;
263
264 /* Restore the checksum to its initial value */
265 vbr_checksum = initial_checksum;
266
[3938375]267 /* Write the Main extended boot sectors backup to disk */
[9587b37]268 return ebs_write(service_id, cfg,
269 EBS_BACKUP_SECTOR_START, &vbr_checksum);
[9744f2d]270}
271
[55dbaeb]272/** Write the Main Extended Boot Sector to disk
273 *
274 * @param service_id The service id.
275 * @param cfg Pointer to the exFAT configuration structure.
[dabe1664]276 * @param base Base sector of the EBS.
[55dbaeb]277 * @return EOK on success or a negative error code.
278 */
279static int
[dabe1664]280ebs_write(service_id_t service_id, exfat_cfg_t *cfg, int base, uint32_t *chksum)
[55dbaeb]281{
282 uint32_t *ebs = calloc(cfg->sector_size, sizeof(uint8_t));
283 int i, rc;
[dabe1664]284 unsigned idx;
[55dbaeb]285
286 if (!ebs)
287 return ENOMEM;
288
289 ebs[cfg->sector_size / 4 - 1] = host2uint32_t_le(0xAA550000);
290
291 for (i = 0; i < EBS_SIZE; ++i) {
[dabe1664]292 vbr_checksum_update(ebs, cfg->sector_size, chksum);
293
294 rc = block_write_direct(service_id,
295 i + EBS_SECTOR_START + base, 1, ebs);
[55dbaeb]296
297 if (rc != EOK)
298 goto exit;
299 }
300
[dabe1664]301 /* The OEM record is not yet used
302 * by the official exFAT implementation, we'll fill
303 * it with zeroes.
304 */
305
306 memset(ebs, 0, cfg->sector_size);
307 vbr_checksum_update(ebs, cfg->sector_size, chksum);
308
309 rc = block_write_direct(service_id, i++ + base, 1, ebs);
310 if (rc != EOK)
311 goto exit;
312
313 /* The next sector is reserved, fill it with zeroes too */
314 vbr_checksum_update(ebs, cfg->sector_size, chksum);
315 rc = block_write_direct(service_id, i++ + base, 1, ebs);
316 if (rc != EOK)
317 goto exit;
318
319 /* Write the checksum sector */
320 for (idx = 0; idx < cfg->sector_size / sizeof(uint32_t); ++idx)
321 ebs[idx] = host2uint32_t_le(*chksum);
322
323 rc = block_write_direct(service_id, i + base, 1, ebs);
324
[55dbaeb]325exit:
326 free(ebs);
327 return rc;
328}
329
[7f381e5]330/** Initialize the FAT table.
[50e754e]331 *
[3938375]332 * @param service_id The service id.
[50e754e]333 * @param cfg Pointer to the exfat_cfg structure.
334 * @return EOK on success or a negative error code.
335 */
336static int
[7f381e5]337fat_initialize(service_id_t service_id, exfat_cfg_t *cfg)
[50e754e]338{
339 unsigned long i;
340 uint32_t *pfat;
341 int rc;
342
[6aeab59c]343 pfat = calloc(cfg->sector_size, 1);
[50e754e]344 if (!pfat)
345 return ENOMEM;
346
347 pfat[0] = host2uint32_t_le(0xFFFFFFF8);
348 pfat[1] = host2uint32_t_le(0xFFFFFFFF);
349
350 rc = block_write_direct(service_id, FAT_SECTOR_START, 1, pfat);
351 if (rc != EOK)
352 goto error;
353
[78de7be2]354 pfat[0] = pfat[1] = 0;
[50e754e]355
[6aeab59c]356 for (i = 1; i < cfg->fat_sector_count; ++i) {
[69c4172]357 rc = block_write_direct(service_id,
[b0fecad]358 FAT_SECTOR_START + i, 1, pfat);
[50e754e]359 if (rc != EOK)
360 goto error;
361 }
362
363error:
364 free(pfat);
365 return rc;
366}
367
[78de7be2]368/** Allocate a given number of clusters and create a cluster chain.
369 *
370 * @param service_id The service id.
371 * @param cfg Pointer to the exfat configuration number.
372 * @param cur_cls Cluster index from where to start the allocation.
373 * @param ncls Number of clusters to allocate.
374 * @return EOK on success or a negative error code.
375 */
376static int
377fat_allocate_clusters(service_id_t service_id, exfat_cfg_t *cfg,
378 uint32_t cur_cls, unsigned long ncls)
379{
380 int rc;
381 unsigned const fat_entries = cfg->sector_size / sizeof(uint32_t);
[69f9cf5]382 aoff64_t fat_sec = cur_cls / fat_entries + FAT_SECTOR_START;
[78de7be2]383 uint32_t *fat;
384
385 cur_cls %= fat_entries;
386
387 fat = malloc(cfg->sector_size);
388 if (!fat)
389 return ENOMEM;
390
391loop:
392 rc = block_read_direct(service_id, fat_sec, 1, fat);
393 if (rc != EOK)
394 goto exit;
395
396 assert(fat[cur_cls] == 0);
397 assert(ncls > 0);
398
399 if (ncls == 1) {
400 fat[cur_cls] = host2uint32_t_le(0xFFFFFFFF);
401 rc = block_write_direct(service_id, fat_sec, 1, fat);
402 goto exit;
403 }
404
405 for (; cur_cls < fat_entries && ncls > 1; ++cur_cls, --ncls)
406 fat[cur_cls] = host2uint32_t_le(cur_cls + 1);
407
408 if (cur_cls == fat_entries) {
409 rc = block_write_direct(service_id, fat_sec++, 1, fat);
410 if (rc != EOK)
411 goto exit;
412 cur_cls = 0;
413 goto loop;
414 } else if (ncls == 1)
415 fat[cur_cls] = host2uint32_t_le(0xFFFFFFFF);
416
417 rc = block_write_direct(service_id, fat_sec, 1, fat);
418
419exit:
420 free(fat);
421 return rc;
422}
423
[6aeab59c]424/** Initialize the allocation bitmap.
425 *
426 * @param service_id The service id.
427 * @param cfg Pointer to the exfat configuration structure.
428 * @return EOK on success or a negative error code.
429 */
430static int
431bitmap_write(service_id_t service_id, exfat_cfg_t *cfg)
432{
433 unsigned long i, sec;
434 unsigned long allocated_cls;
435 int rc = EOK;
436
437 /* Bitmap size in sectors */
438 size_t const bss = div_round_up(cfg->bitmap_size, cfg->sector_size);
439
440 uint8_t *bitmap = malloc(cfg->sector_size);
441 if (!bitmap)
442 return ENOMEM;
443
444 allocated_cls = cfg->allocated_clusters;
445
446 for (sec = 0; sec < bss; ++sec) {
447 memset(bitmap, 0, cfg->sector_size);
448 if (allocated_cls > 0) {
449 for (i = 0; i < allocated_cls; ++i) {
450 unsigned byte_idx = i / 8;
451 unsigned bit_idx = i % 8;
452
453 if (byte_idx == cfg->sector_size)
454 break;
455 bitmap[byte_idx] |= 1 << bit_idx;
456 }
457
[cbd8a72]458 allocated_cls -= i;
[6aeab59c]459 }
460
461 rc = block_write_direct(service_id,
462 cfg->data_start_sector + sec, 1, bitmap);
463 if (rc != EOK)
464 goto exit;
465 }
466
467exit:
468 free(bitmap);
469 return rc;
470}
471
[89a0a827]472/** Write the upcase table to disk. */
473static int
474upcase_table_write(service_id_t service_id, exfat_cfg_t *cfg)
475{
476 int rc;
477 aoff64_t start_sec, nsecs, i;
478 uint8_t *table_ptr;
479
480 start_sec = cfg->data_start_sector;
481 start_sec += (cfg->upcase_table_cluster * cfg->cluster_size) /
482 cfg->sector_size;
483
484 nsecs = div_round_up(sizeof(upcase_table), cfg->sector_size);
485 table_ptr = (uint8_t *) upcase_table;
486
487 for (i = 0; i < nsecs; ++i, table_ptr += cfg->sector_size) {
488 rc = block_write_direct(service_id,
489 start_sec + i, 1, table_ptr);
490 if (rc != EOK)
491 return rc;
492 }
493
494 return EOK;
495}
496
[dabe1664]497/** Given a number (n), returns the result of log2(n).
[ffee7bf]498 *
499 * It works only if n is a power of two.
500 */
[6cf9aeb]501static unsigned
502log2(unsigned n)
[ffee7bf]503{
504 unsigned r;
505
506 for (r = 0;n >> r != 1; ++r);
507
508 return r;
509}
510
[dabe1664]511/** Initialize the VBR checksum calculation */
512static uint32_t
513vbr_checksum_start(void const *data, size_t nbytes)
514{
515 uint32_t checksum = 0;
516 size_t index;
517 uint8_t const *octets = (uint8_t *) data;
518
519 for (index = 0; index < nbytes; ++index) {
520 if (index == 106 || index == 107 || index == 112) {
521 /* Skip volume_flags and allocated_percent fields */
522 continue;
523 }
524
525 checksum = ((checksum << 31) | (checksum >> 1)) + octets[index];
526 }
527
528 return checksum;
529}
530
531/** Update the VBR checksum */
532static void
533vbr_checksum_update(void const *data, size_t nbytes, uint32_t *checksum)
534{
535 size_t index;
536 uint8_t const *octets = (uint8_t *) data;
537
538 for (index = 0; index < nbytes; ++index)
539 *checksum = ((*checksum << 31) | (*checksum >> 1)) + octets[index];
540}
541
[dd22cc4]542int main (int argc, char **argv)
543{
[9744f2d]544 exfat_cfg_t cfg;
[78de7be2]545 uint32_t next_cls;
[116cb91]546 char *dev_path;
547 service_id_t service_id;
548 int rc;
549
550 if (argc < 2) {
551 printf(NAME ": Error, argument missing\n");
552 usage();
553 return 1;
554 }
555
556 /* TODO: Add parameters */
557
558 ++argv;
559 dev_path = *argv;
560
561 printf(NAME ": Device = %s\n", dev_path);
562
563 rc = loc_service_get_id(dev_path, &service_id, 0);
564 if (rc != EOK) {
[ffee7bf]565 printf(NAME ": Error resolving device `%s'.\n", dev_path);
[116cb91]566 return 2;
567 }
568
569 rc = block_init(EXCHANGE_SERIALIZE, service_id, 2048);
570 if (rc != EOK) {
571 printf(NAME ": Error initializing libblock.\n");
572 return 2;
573 }
574
[ffee7bf]575 rc = block_get_bsize(service_id, &cfg.sector_size);
[116cb91]576 if (rc != EOK) {
577 printf(NAME ": Error determining device block size.\n");
578 return 2;
579 }
580
[ffee7bf]581 if (cfg.sector_size > 4096) {
[3f6d4ea]582 printf(NAME ": Error, sector size can't be greater" \
[ffee7bf]583 " than 4096 bytes.\n");
584 return 2;
585 }
586
587 rc = block_get_nblocks(service_id, &cfg.volume_count);
[9744f2d]588 if (rc != EOK) {
[5dbd696]589 printf(NAME ": Warning, failed to obtain" \
590 " device block size.\n");
591 /* FIXME: the user should be able to specify the filesystem size */
[9744f2d]592 return 1;
593 } else {
594 printf(NAME ": Block device has %" PRIuOFF64 " blocks.\n",
[ffee7bf]595 cfg.volume_count);
[9744f2d]596 }
597
598 cfg_params_initialize(&cfg);
[6cf9aeb]599 cfg_print_info(&cfg);
[116cb91]600
[7f381e5]601 rc = fat_initialize(service_id, &cfg);
[50e754e]602 if (rc != EOK) {
[55dbaeb]603 printf(NAME ": Error, failed to write the FAT to disk\n");
[50e754e]604 return 2;
605 }
606
[78de7be2]607 /* Allocate clusters for the bitmap */
608 rc = fat_allocate_clusters(service_id, &cfg, FIRST_FREE_CLUSTER,
609 div_round_up(cfg.bitmap_size, cfg.cluster_size));
610 if (rc != EOK) {
611 printf(NAME ": Error, failed to allocate clusters for bitmap.\n");
612 return 2;
613 }
614
615 next_cls = FIRST_FREE_CLUSTER +
616 div_round_up(cfg.bitmap_size, cfg.cluster_size);
[557e5b13]617 cfg.upcase_table_cluster = next_cls;
[78de7be2]618
619 /* Allocate clusters for the upcase table */
620 rc = fat_allocate_clusters(service_id, &cfg, next_cls,
621 div_round_up(sizeof(upcase_table), cfg.cluster_size));
622 if (rc != EOK) {
623 printf(NAME ":Error, failed to allocate clusters foe the upcase table.\n");
624 return 2;
625 }
626
[69f9cf5]627 next_cls += div_round_up(sizeof(upcase_table), cfg.cluster_size);
628 cfg.rootdir_cluster = next_cls;
629
630 /* Allocate a cluster for the root directory entry */
631 rc = fat_allocate_clusters(service_id, &cfg, next_cls, 1);
632 if (rc != EOK) {
633 printf(NAME ": Error, failed to allocate cluster for the root dentry.\n");
634 return 2;
635 }
636
[557e5b13]637 rc = bitmap_write(service_id, &cfg);
638 if (rc != EOK) {
639 printf(NAME ": Error, failed to write the allocation" \
640 " bitmap to disk.\n");
641 return 2;
642 }
643
[89a0a827]644 rc = upcase_table_write(service_id, &cfg);
645 if (rc != EOK) {
646 printf(NAME ": Error, failed to write the upcase table to disk.\n");
647 return 2;
648 }
649
[557e5b13]650 rc = bootsec_write(service_id, &cfg);
651 if (rc != EOK) {
652 printf(NAME ": Error, failed to write the VBR to disk\n");
653 return 2;
654 }
655
[dd22cc4]656 return 0;
657}
[9744f2d]658
Note: See TracBrowser for help on using the repository browser.