*
* Busybox'ed (2009) by Vladimir Dronnikov <dronnikov@gmail.com>
*
- * Licensed under GPLv2, see file LICENSE in this tarball for details.
+ * Licensed under GPLv2, see file LICENSE in this source tree.
*/
+//config:config MKDOSFS
+//config: bool "mkdosfs (6.8 kb)"
+//config: default y
+//config: select PLATFORM_LINUX
+//config: help
+//config: Utility to create FAT32 filesystems.
+//config:
+//config:config MKFS_VFAT
+//config: bool "mkfs.vfat (6.8 kb)"
+//config: default y
+//config: select PLATFORM_LINUX
+//config: help
+//config: Alias to "mkdosfs".
+
+// APPLET_ODDNAME:name main location suid_type help
+//applet:IF_MKDOSFS( APPLET_ODDNAME(mkdosfs, mkfs_vfat, BB_DIR_SBIN, BB_SUID_DROP, mkfs_vfat))
+//applet:IF_MKFS_VFAT(APPLET_ODDNAME(mkfs.vfat, mkfs_vfat, BB_DIR_SBIN, BB_SUID_DROP, mkfs_vfat))
+
+//kbuild:lib-$(CONFIG_MKDOSFS) += mkfs_vfat.o
+//kbuild:lib-$(CONFIG_MKFS_VFAT) += mkfs_vfat.o
+
+//usage:#define mkfs_vfat_trivial_usage
+//usage: "[-v] [-n LABEL] BLOCKDEV [KBYTES]"
+/* Accepted but ignored:
+ "[-c] [-C] [-I] [-l bad-block-file] [-b backup-boot-sector] "
+ "[-m boot-msg-file] [-i volume-id] "
+ "[-s sectors-per-cluster] [-S logical-sector-size] [-f number-of-FATs] "
+ "[-h hidden-sectors] [-F fat-size] [-r root-dir-entries] [-R reserved-sectors] "
+*/
+//usage:#define mkfs_vfat_full_usage "\n\n"
+//usage: "Make a FAT32 filesystem\n"
+/* //usage: "\n -c Check device for bad blocks" */
+//usage: "\n -v Verbose"
+/* //usage: "\n -I Allow to use entire disk device (e.g. /dev/hda)" */
+//usage: "\n -n LBL Volume label"
+
#include "libbb.h"
#include <linux/hdreg.h> /* HDIO_GETGEO */
# define BLKSSZGET _IO(0x12, 104)
#endif
//#include <linux/msdos_fs.h>
-#include "volume_id/volume_id_internal.h"
#define SECTOR_SIZE 512
#define ATTR_VOLUME 8
-#define NUM_FATS 2
+#define NUM_FATS 2
/* FAT32 filesystem looks like this:
* sector -nn...-1: "hidden" sectors, all sectors before this partition
} PACKED; /* 05a end. Total size 26 (0x1a) bytes */
struct msdos_boot_sector {
- char boot_jump[3]; /* 000 short or near jump instruction */
- char system_id[8]; /* 003 name - can be used to special case partition manager volumes */
+ /* We use strcpy to fill both, and gcc-4.4.x complains if they are separate */
+ char boot_jump_and_sys_id[3+8]; /* 000 short or near jump instruction */
+ /*char system_id[8];*/ /* 003 name - can be used to special case partition manager volumes */
uint16_t bytes_per_sect; /* 00b bytes per logical sector */
uint8_t sect_per_clust; /* 00d sectors/cluster */
uint16_t reserved_sect; /* 00e reserved sectors (sector offset of 1st FAT relative to volume start) */
#define MARK_CLUSTER(cluster, value) \
- ((uint32_t *)fat)[cluster] = cpu_to_le32(value)
-
-void BUG_unsupported_field_size(void);
-#define STORE_LE(field, value) \
-do { \
- if (sizeof(field) == 4) \
- field = cpu_to_le32(value); \
- else if (sizeof(field) == 2) \
- field = cpu_to_le16(value); \
- else if (sizeof(field) == 1) \
- field = (value); \
- else \
- BUG_unsupported_field_size(); \
-} while (0)
+ ((uint32_t *)fat)[cluster] = SWAP_LE32(value)
/* compat:
* mkdosfs 2.11 (12 Mar 2005)
int dev;
unsigned bytes_per_sect;
unsigned sect_per_fat;
- unsigned opts;
+ unsigned opts;
uint16_t sect_per_track;
uint8_t media_byte;
uint8_t sect_per_clust;
OPT_v = 1 << 16, // verbose
};
- opt_complementary = "-1";//:b+:f+:F+:h+:r+:R+:s+:S+:vv:c--l:l--c";
- opts = getopt32(argv, "Ab:cCf:F:h:Ii:l:m:n:r:R:s:S:v",
+ opts = getopt32(argv, "^"
+ "Ab:cCf:F:h:Ii:l:m:n:r:R:s:S:v"
+ "\0" "-1", //:b+:f+:F+:h+:r+:R+:s+:S+:vv:c--l:l--c
NULL, NULL, NULL, NULL, NULL,
NULL, NULL, &volume_label, NULL, NULL, NULL, NULL);
argv += optind;
// default volume ID = creation time
volume_id = time(NULL);
- dev = xopen(device_name, O_EXCL | O_RDWR);
- if (fstat(dev, &st) < 0)
- bb_simple_perror_msg_and_die(device_name);
+ dev = xopen(device_name, O_RDWR);
+ xfstat(dev, &st, device_name);
//
// Get image size and sector size
//
bytes_per_sect = SECTOR_SIZE;
- volume_size_bytes = st.st_size;
if (!S_ISBLK(st.st_mode)) {
if (!S_ISREG(st.st_mode)) {
if (!argv[1])
opts &= ~OPT_c;
} else {
int min_bytes_per_sect;
-
- // more portable than BLKGETSIZE[64]
- volume_size_bytes = xlseek(dev, 0, SEEK_END);
- xlseek(dev, 0, SEEK_SET);
#if 0
unsigned device_num;
// for true block devices we do check sanity
bb_error_msg("for this device sector size is %u", min_bytes_per_sect);
}
}
- if (argv[1]) {
- volume_size_bytes = XATOOFF(argv[1]);
- if (volume_size_bytes >= MAXINT(off_t) / 1024)
- bb_error_msg_and_die("image size is too big");
- volume_size_bytes *= 1024;
- }
+ volume_size_bytes = get_volume_size_in_bytes(dev, argv[1], 1024, /*extend:*/ 1);
volume_size_sect = volume_size_bytes / bytes_per_sect;
//
struct msdos_boot_sector *boot_blk = (void*)buf;
struct fat32_fsinfo *info = (void*)(buf + bytes_per_sect);
- strcpy(boot_blk->boot_jump, "\xeb\x58\x90" "mkdosfs"); // system_id[8] included :)
+ strcpy(boot_blk->boot_jump_and_sys_id, "\xeb\x58\x90" "mkdosfs");
STORE_LE(boot_blk->bytes_per_sect, bytes_per_sect);
STORE_LE(boot_blk->sect_per_clust, sect_per_clust);
// cast in needed on big endian to suppress a warning
//STORE_LE(boot_blk->reserved2[3], 0,0,0);
STORE_LE(boot_blk->vi.ext_boot_sign, 0x29);
STORE_LE(boot_blk->vi.volume_id32, volume_id);
- strncpy(boot_blk->vi.fs_type, "FAT32 ", sizeof(boot_blk->vi.fs_type));
+ memcpy(boot_blk->vi.fs_type, "FAT32 ", sizeof(boot_blk->vi.fs_type));
strncpy(boot_blk->vi.volume_label, volume_label, sizeof(boot_blk->vi.volume_label));
memcpy(boot_blk->boot_code, boot_code, sizeof(boot_code));
STORE_LE(boot_blk->boot_sign, BOOT_SIGN);
// create dir entry for volume_label
struct msdos_dir_entry *de;
#if 0
- struct tm tm;
+ struct tm tm_time;
uint16_t t, d;
#endif
de = (void*)buf;
strncpy(de->name, volume_label, sizeof(de->name));
STORE_LE(de->attr, ATTR_VOLUME);
#if 0
- localtime_r(&create_time, &tm);
- t = (tm.tm_sec >> 1) + (tm.tm_min << 5) + (tm.tm_hour << 11);
- d = tm.tm_mday + ((tm.tm_mon+1) << 5) + ((tm.tm_year-80) << 9);
+ localtime_r(&create_time, &tm_time);
+ t = (tm_time.tm_sec >> 1) + (tm_time.tm_min << 5) + (tm_time.tm_hour << 11);
+ d = tm_time.tm_mday + ((tm_time.tm_mon+1) << 5) + ((tm_time.tm_year-80) << 9);
STORE_LE(de->time, t);
STORE_LE(de->date, d);
//STORE_LE(de->ctime_cs, 0);
start_data_sector = (reserved_sect + NUM_FATS * sect_per_fat) * (bytes_per_sect / SECTOR_SIZE);
start_data_block = (start_data_sector + SECTORS_PER_BLOCK - 1) / SECTORS_PER_BLOCK;
- bb_info_msg("searching for bad blocks ");
+ bb_error_msg("searching for bad blocks");
currently_testing = 0;
try = TEST_BUFFER_BLOCKS;
while (currently_testing < volume_size_blocks) {
}
free(blkbuf);
if (badblocks)
- bb_info_msg("%d bad block(s)", badblocks);
+ bb_error_msg("%d bad block(s)", badblocks);
}
#endif