3 * esd gmbh <www.esd-electronics.com>
4 * Reinhard Arlt <reinhard.arlt@esd-electronics.com>
6 * made from cmd_reiserfs by
8 * (C) Copyright 2003 - 2004
9 * Sysgo Real-Time Solutions, AG <www.elinos.com>
10 * Pavel Bartusek <pba@sysgo.com>
12 * See file CREDITS for list of people who contributed to this
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
40 #include <linux/ctype.h>
41 #include <asm/byteorder.h>
43 #include <linux/stat.h>
44 #include "../disk/part_dos.h"
47 #if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
51 #if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION)
52 #error DOS or EFI partition support must be selected
55 /* #define EXT2_DEBUG */
58 #define PRINTF(fmt,args...) printf (fmt ,##args)
60 #define PRINTF(fmt,args...)
63 static int total_sector;
64 static block_dev_desc_t *cur_dev = NULL;
65 static unsigned long part_offset = 0;
66 static unsigned long part_size = 0;
68 static int cur_part = 1;
70 #define DOS_PART_MAGIC_OFFSET 0x1fe
71 #define DOS_FS_TYPE_OFFSET 0x36
72 #define DOS_FS32_TYPE_OFFSET 0x52
75 * Constants relative to the data blocks
77 #define EXT2_NDIR_BLOCKS 12
78 #define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
79 #define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
80 #define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
81 #define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
84 * Macro-instructions used to manage several block sizes
86 #define EXT2_MIN_BLOCK_LOG_SIZE 10 /* 1024 */
87 #define EXT2_MAX_BLOCK_LOG_SIZE 16 /* 65536 */
88 #define EXT2_MIN_BLOCK_SIZE (1 << EXT2_MIN_BLOCK_LOG_SIZE)
89 #define EXT2_MAX_BLOCK_SIZE (1 << EXT2_MAX_BLOCK_LOG_SIZE)
91 #define ENABLE_FEATURE_MKFS_EXT2_RESERVED_GDT 0
92 #define ENABLE_FEATURE_MKFS_EXT2_DIR_INDEX 1
93 /* First non-reserved inode for old ext2 filesystems */
94 #define EXT2_GOOD_OLD_FIRST_INO 11
96 #define SWAP_LE16(x) (x)
97 #define SWAP_LE32(x) (x)
99 #define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */
100 #define EXT2_FEATURE_COMPAT_RESIZE_INODE 0x0010
101 #define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020
103 * The second extended file system magic number
105 #define EXT2_SUPER_MAGIC 0xEF53
106 #define EXT2_OS_LINUX 0
107 #define EXT2_HASH_HALF_MD4 1
109 #define EXT2_HASH_HALF_MD4 1
110 #define EXT2_FLAGS_SIGNED_HASH 0x0001
111 #define EXT2_FLAGS_UNSIGNED_HASH 0x0002
112 #define EXT2_ROOT_INO 2 /* Root inode */
114 #define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002
115 #define EXT2_FEATURE_COMPAT_SUPP 0
116 #define EXT2_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */
117 #define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
120 * Behaviour when detecting errors
122 #define EXT2_ERRORS_DEFAULT 1
125 * Ext2 directory file types. Only the low 3 bits are used. The
126 * other bits are reserved for now.
140 /* The ext2 superblock. */
142 uint32_t total_inodes;
143 uint32_t total_blocks;
144 uint32_t reserved_blocks;
145 uint32_t free_blocks;
146 uint32_t free_inodes;
147 uint32_t first_data_block;
148 uint32_t log2_block_size;
149 uint32_t log2_fragment_size;
150 uint32_t s_blocks_per_group;
151 uint32_t fragments_per_group;
152 uint32_t inodes_per_group;
156 uint16_t max_mnt_count;
159 uint16_t error_handling;
160 uint16_t minor_revision_level;
162 uint32_t checkinterval;
164 uint32_t revision_level;
165 uint16_t uid_reserved;
166 uint16_t gid_reserved;
167 uint32_t first_inode;
169 uint16_t block_group_number;
170 uint32_t feature_compatibility;
171 uint32_t feature_incompat;
172 uint32_t feature_ro_compat;
173 uint32_t unique_id[4];
174 char volume_name[16];
175 char last_mounted_on[64];
176 uint32_t compression_info;
180 * Structure of an inode on the disk
183 uint16_t i_mode; /* File mode */
184 uint16_t i_uid; /* Low 16 bits of Owner Uid */
185 uint32_t i_size; /* Size in bytes */
186 uint32_t i_atime; /* Access time */
187 uint32_t i_ctime; /* Creation time */
188 uint32_t i_mtime; /* Modification time */
189 uint32_t i_dtime; /* Deletion Time */
190 uint16_t i_gid; /* Low 16 bits of Group Id */
191 uint16_t i_links_count; /* Links count */
192 uint32_t i_blocks; /* Blocks count */
193 uint32_t i_flags; /* File flags */
196 uint32_t l_i_reserved1;
199 uint32_t h_i_translator;
202 uint32_t m_i_reserved1;
204 } osd1; /* OS dependent 1 */
205 uint32_t i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
206 uint32_t i_generation; /* File version (for NFS) */
207 uint32_t i_file_acl; /* File ACL */
208 uint32_t i_dir_acl; /* Directory ACL */
209 uint32_t i_faddr; /* Fragment address */
212 uint8_t l_i_frag; /* Fragment number */
213 uint8_t l_i_fsize; /* Fragment size */
215 uint16_t l_i_uid_high; /* these 2 fields */
216 uint16_t l_i_gid_high; /* were reserved2[0] */
217 uint32_t l_i_reserved2;
220 uint8_t h_i_frag; /* Fragment number */
221 uint8_t h_i_fsize; /* Fragment size */
222 uint16_t h_i_mode_high;
223 uint16_t h_i_uid_high;
224 uint16_t h_i_gid_high;
228 uint8_t m_i_frag; /* Fragment number */
229 uint8_t m_i_fsize; /* Fragment size */
231 uint32_t m_i_reserved2[2];
233 } osd2; /* OS dependent 2 */
237 * Structure of a blocks group descriptor
239 struct ext2_group_desc {
240 uint32_t bg_block_bitmap; /* Blocks bitmap block */
241 uint32_t bg_inode_bitmap; /* Inodes bitmap block */
242 uint32_t bg_inode_table; /* Inodes table block */
243 uint16_t bg_free_blocks_count; /* Free blocks count */
244 uint16_t bg_free_inodes_count; /* Free inodes count */
245 uint16_t bg_used_dirs_count; /* Directories count */
247 uint32_t bg_reserved[3];
250 // All fields are little-endian
269 #define FETCH_LE32(field) \
270 (sizeof(field) == 4 ? SWAP_LE32(field) : BUG_wrong_field_size())
273 char BUG_wrong_field_size(void);
274 #define STORE_LE(field, value) \
276 if (sizeof(field) == 4) \
277 field = SWAP_LE32(value); \
278 else if (sizeof(field) == 2) \
279 field = SWAP_LE16(value); \
280 else if (sizeof(field) == 1) \
283 BUG_wrong_field_size(); \
286 int do_ext2ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
288 char *filename = "/";
292 block_dev_desc_t *dev_desc=NULL;
296 return cmd_usage(cmdtp);
298 dev = (int)simple_strtoul (argv[2], &ep, 16);
299 dev_desc = get_dev(argv[1],dev);
301 if (dev_desc == NULL) {
302 printf ("\n** Block device %s %d not supported\n", argv[1], dev);
308 puts ("\n** Invalid boot device, use `dev[:part]' **\n");
311 part = (int)simple_strtoul(++ep, NULL, 16);
317 PRINTF("Using device %s %d:%d, directory: %s\n", argv[1], dev, part, filename);
319 if ((part_length = ext2fs_set_blk_dev(dev_desc, part)) == 0) {
320 printf ("** Bad partition - %s %d:%d **\n", argv[1], dev, part);
325 if (!ext2fs_mount(part_length)) {
326 printf ("** Bad ext2 partition or disk - %s %d:%d **\n", argv[1], dev, part);
331 if (ext2fs_ls (filename)) {
332 printf ("** Error ext2fs_ls() **\n");
343 ext2ls, 4, 1, do_ext2ls,
344 "list files in a directory (default /)",
345 "<interface> <dev[:part]> [directory]\n"
346 " - list files from 'dev' on 'interface' in a 'directory'"
349 int do_ext2write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
351 block_dev_desc_t *dev_desc=NULL;
352 char *filename = "/";
357 unsigned long ram_address;
358 unsigned long file_size;
359 disk_partition_t info;
362 return cmd_usage(cmdtp);
364 dev = (int)simple_strtoul (argv[2], &ep, 16);
365 dev_desc = get_dev(argv[1],dev);
367 if (dev_desc == NULL) {
368 printf ("\n** Block device %s %d not supported\n", argv[1], dev);
374 puts ("\n** Invalid boot device, use `dev[:part]' **\n");
377 part = (int)simple_strtoul(++ep, NULL, 16);
383 /*get the address in hexadecimal format (string to int)*/
384 ram_address = simple_strtoul (argv[4], NULL, 16);
386 /*get the filesize in base 10 format*/
387 file_size=simple_strtoul (argv[5], NULL, 10);
390 PRINTF("Using device %s %d:%d, directory: %s\n", argv[1], dev, part, filename);
392 if ((part_length = ext2fs_set_blk_dev(dev_desc, part)) == 0) {
393 printf ("** Bad partition - %s %d:%d **\n", argv[1], dev, part);
398 if (ext2_register_device(dev_desc,part)!=0)
400 printf("\n** Unable to use %s %d:%d for fattable **\n",
405 if (!get_partition_info(dev_desc, part, &info))
407 total_sector = (info.size * info.blksz) / SECTOR_SIZE;
411 printf("error : get partition info\n");
414 if (!ext2fs_mount(part_length)) {
415 printf ("** Bad ext2 partition or disk - %s %d:%d **\n", argv[1], dev, part);
420 if (ext2fs_write(dev_desc,part,filename,(unsigned char*)ram_address,file_size))
422 printf ("** Error ext2fs_write() **\n");
431 ext2write, 6, 1, do_ext2write,
432 "create a file in the root directory",
433 "<interface> <dev[:part]> [filename] [Address] [sizebytes]\n"
434 " - create a file in / directory"
437 /******************************************************************************
438 * Ext2fs boot command intepreter. Derived from diskboot
440 int do_ext2load (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
442 char *filename = NULL;
445 ulong addr = 0, part_length;
447 disk_partition_t info;
448 block_dev_desc_t *dev_desc = NULL;
455 addr_str = getenv("loadaddr");
456 if (addr_str != NULL)
457 addr = simple_strtoul (addr_str, NULL, 16);
459 addr = CONFIG_SYS_LOAD_ADDR;
461 filename = getenv ("bootfile");
465 addr = simple_strtoul (argv[3], NULL, 16);
466 filename = getenv ("bootfile");
470 addr = simple_strtoul (argv[3], NULL, 16);
475 addr = simple_strtoul (argv[3], NULL, 16);
477 count = simple_strtoul (argv[5], NULL, 16);
481 return cmd_usage(cmdtp);
485 puts ("** No boot file defined **\n");
489 dev = (int)simple_strtoul (argv[2], &ep, 16);
490 dev_desc = get_dev(argv[1],dev);
491 if (dev_desc==NULL) {
492 printf ("** Block device %s %d not supported\n", argv[1], dev);
497 puts ("** Invalid boot device, use `dev[:part]' **\n");
500 part = (int)simple_strtoul(++ep, NULL, 16);
503 PRINTF("Using device %s%d, partition %d\n", argv[1], dev, part);
506 if (get_partition_info (dev_desc, part, &info)) {
507 printf ("** Bad partition %d **\n", part);
511 if (strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) {
512 printf ("** Invalid partition type \"%.32s\""
513 " (expect \"" BOOT_PART_TYPE "\")\n",
517 printf ("Loading file \"%s\" "
518 "from %s device %d:%d (%.32s)\n",
520 argv[1], dev, part, info.name);
522 printf ("Loading file \"%s\" from %s device %d\n",
523 filename, argv[1], dev);
527 if ((part_length = ext2fs_set_blk_dev(dev_desc, part)) == 0) {
528 printf ("** Bad partition - %s %d:%d **\n", argv[1], dev, part);
533 if (!ext2fs_mount(part_length)) {
534 printf ("** Bad ext2 partition or disk - %s %d:%d **\n",
540 filelen = ext2fs_open(filename);
542 printf("** File not found %s\n", filename);
546 if ((count < filelen) && (count != 0)) {
550 if (ext2fs_read((char *)addr, filelen) != filelen) {
551 printf("** Unable to read \"%s\" from %s %d:%d **\n",
552 filename, argv[1], dev, part);
559 /* Loading ok, update default load address */
562 printf ("%d bytes read\n", filelen);
563 sprintf(buf, "%X", filelen);
564 setenv("filesize", buf);
570 ext2load, 6, 0, do_ext2load,
571 "load binary file from a Ext2 filesystem",
572 "<interface> <dev[:part]> [addr] [filename] [bytes]\n"
573 " - load binary file 'filename' from 'dev' on 'interface'\n"
574 " to address 'addr' from ext2 filesystem"
576 static unsigned int_log2(unsigned arg)
579 while ((arg >>= 1) != 0)
583 // taken from mkfs_minix.c. libbb candidate?
584 // "uint32_t size", since we never use it for anything >32 bits
585 uint32_t div_roundup(uint32_t size, uint32_t n)
587 // Overflow-resistant
588 uint32_t res = size / n;
594 static uint32_t has_super(uint32_t x)
596 // 0, 1 and powers of 3, 5, 7 up to 2^32 limit
597 static const uint32_t supers[] = {
598 0, 1, 3, 5, 7, 9, 25, 27, 49, 81, 125, 243, 343, 625, 729,
599 2187, 2401, 3125, 6561, 15625, 16807, 19683, 59049, 78125,
600 117649, 177147, 390625, 531441, 823543, 1594323, 1953125,
601 4782969, 5764801, 9765625, 14348907, 40353607, 43046721,
602 48828125, 129140163, 244140625, 282475249, 387420489,
603 1162261467, 1220703125, 1977326743, 3486784401/* >2^31 */,
605 const uint32_t *sp = supers + ARRAY_SIZE(supers);
615 // Die if we can't allocate size bytes of memory.
616 void* xmalloc(size_t size)
618 void *ptr = malloc(size);
619 if (ptr == NULL && size != 0)
620 printf("bb_msg_memory_exhausted\n");
624 // Die if we can't allocate and zero size bytes of memory.
625 void* xzalloc(size_t size)
627 void *ptr = xmalloc(size);
628 memset(ptr, 0, size);
631 static void allocate(uint8_t *bitmap, uint32_t blocksize, uint32_t start, uint32_t end)
634 memset(bitmap, 0, blocksize);
636 memset(bitmap, 0xFF, i);
637 bitmap[i] = (1 << (start & 7)) - 1;
639 bitmap[blocksize - i - 1] |= 0x7F00 >> (end & 7);
640 memset(bitmap + blocksize - i, 0xFF, i);
643 /* Like strncpy but make sure the resulting string is always 0 terminated. */
644 char* safe_strncpy(char *dst, const char *src, size_t size)
646 if (!size) return dst;
648 return strncpy(dst, src, size);
651 void PUT(block_dev_desc_t *dev_desc,uint64_t off, void *buf, uint32_t size)
653 uint64_t startblock,remainder;
654 unsigned int sector_size = 512;
656 unsigned char *temp_ptr=NULL;
657 char sec_buf[SECTOR_SIZE];
658 startblock = off / (uint64_t)sector_size;
659 startblock += part_offset;
660 remainder = off % (uint64_t)sector_size;
661 remainder &= SECTOR_SIZE - 1;
662 if (dev_desc == NULL)
665 if ((startblock + (size/SECTOR_SIZE)) > (part_offset +total_sector)) {
666 printf("part_offset is %d\n",part_offset);
667 printf("total_sector is %d\n",total_sector);
668 printf("error: overflow occurs\n");
673 if (dev_desc->block_read) {
674 dev_desc->block_read(dev_desc->dev, startblock, 1,
675 (unsigned char *) sec_buf);
676 temp_ptr=(unsigned char*)sec_buf;
677 memcpy((temp_ptr + remainder),(unsigned char*)buf,size);
678 dev_desc->block_write(dev_desc->dev, startblock, 1,
679 (unsigned char *)sec_buf);
684 if(size/SECTOR_SIZE!=0)
686 dev_desc->block_write(dev_desc->dev, startblock,
687 size/SECTOR_SIZE,(unsigned long *) buf);
691 dev_desc->block_read(dev_desc->dev, startblock, 1,
692 (unsigned char *) sec_buf);
693 temp_ptr=(unsigned char*)sec_buf;
694 memcpy(temp_ptr,buf,size);
695 dev_desc->block_write(dev_desc->dev, startblock,
696 1,(unsigned long *) sec_buf);
703 int mkfs_ext2(block_dev_desc_t *dev_desc, int part_no)
705 disk_partition_t info;
708 unsigned blocksize, blocksize_log2;
709 unsigned inodesize, user_inodesize;
710 unsigned reserved_percent = 5;
711 unsigned long long kilobytes;
712 uint32_t nblocks, nblocks_full;
715 uint32_t bytes_per_inode;
716 uint32_t first_block;
717 uint32_t inodes_per_group;
718 uint32_t group_desc_blocks;
719 uint32_t inode_table_blocks;
720 uint32_t lost_and_found_blocks;
722 const char *label = "";
723 struct ext2_sblock *sb; // superblock
724 struct ext2_group_desc *gd; // group descriptors
725 struct ext2_inode *inode;
726 struct ext2_dir *dir;
729 __u32 bytes_per_sect;
730 __u32 volume_size_sect;
731 __u64 volume_size_bytes;
732 unsigned char *buffer;
733 unsigned char *temp_buffer;
734 dos_partition_t *pt,*temp_pt;
735 pt=xzalloc(sizeof(dos_partition_t));
737 /* volume_id is fixed */
738 volume_id = 0x386d43bf;
740 /* Get image size and sector size */
741 bytes_per_sect = SECTOR_SIZE;
743 if (!get_partition_info(dev_desc, part_no, &info)) {
744 kilobytes = (info.size * info.blksz)/1024;
745 volume_size_bytes = info.size * info.blksz;
746 volume_size_sect = volume_size_bytes / bytes_per_sect;
748 total_sector = volume_size_sect;
750 printf("error : get partition info\n");
754 bytes_per_inode = 16384;
755 if (kilobytes < 512*1024)
756 bytes_per_inode = 4096;
757 if (kilobytes < 3*1024)
758 bytes_per_inode = 8192;
760 // Determine block size and inode size
761 // block size is a multiple of 1024
762 // inode size is a multiple of 128
765 inodesize = sizeof(struct ext2_inode); // 128
766 if (kilobytes >= 512*1024) { // mke2fs 1.41.9 compat
771 if (EXT2_MAX_BLOCK_SIZE > 4096) {
772 while ((kilobytes >> 22) >= blocksize)
776 if ((int32_t)bytes_per_inode < blocksize)
777 printf("-%c is bad", 'i');
778 // number of bits in one block, i.e. 8*blocksize
779 #define blocks_per_group (8 * blocksize)
780 first_block = (EXT2_MIN_BLOCK_SIZE == blocksize);
781 blocksize_log2 = int_log2(blocksize);
783 // Determine number of blocks
784 kilobytes >>= (blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE);
786 if (nblocks != kilobytes)
787 printf("block count doesn't fit in 32 bits");
788 #define kilobytes kilobytes_unused_after_this
789 // Experimentally, standard mke2fs won't work on images smaller than 60k
791 printf("need >= 60 blocks");
793 // How many reserved blocks?
794 if (reserved_percent > 50)
795 printf("-%c is bad", 'm');
796 nreserved = (uint64_t)nblocks * reserved_percent / 100;
798 // N.B. killing e2fsprogs feature! Unused blocks don't account in calculations
799 nblocks_full = nblocks;
801 // If last block group is too small, nblocks may be decreased in order
802 // to discard it, and control returns here to recalculate some
804 // Note: blocksize and bytes_per_inode are never recalculated.
806 // N.B. a block group can have no more than blocks_per_group blocks
807 ngroups = div_roundup(nblocks - first_block, blocks_per_group);
809 group_desc_blocks = div_roundup(ngroups, blocksize / sizeof(*gd));
812 // N.B. e2fsprogs does as follows!
813 uint32_t overhead, remainder;
814 // ninodes is the max number of inodes in this filesystem
816 ((uint64_t) nblocks_full * blocksize) / bytes_per_inode;
817 if (ninodes < EXT2_GOOD_OLD_FIRST_INO+1)
818 ninodes = EXT2_GOOD_OLD_FIRST_INO+1;
819 inodes_per_group = div_roundup(ninodes, ngroups);
820 // minimum number because the first EXT2_GOOD_OLD_FIRST_INO-1 are reserved
821 if (inodes_per_group < 16)
822 inodes_per_group = 16;
823 // a block group can't have more inodes than blocks
824 if (inodes_per_group > blocks_per_group)
825 inodes_per_group = blocks_per_group;
826 // adjust inodes per group so they completely fill the inode table blocks in the descriptor
828 (div_roundup(inodes_per_group * inodesize,
829 blocksize) * blocksize) / inodesize;
830 // make sure the number of inodes per group is a multiple of 8
831 inodes_per_group &= ~7;
832 inode_table_blocks = div_roundup(inodes_per_group * inodesize,
835 // to be useful, lost+found should occupy at least 2 blocks (but not exceeding 16*1024 bytes),
836 // and at most EXT2_NDIR_BLOCKS. So reserve these blocks right now
837 /* Or e2fsprogs comment verbatim (what does it mean?):
838 * Ensure that lost+found is at least 2 blocks, so we always
839 * test large empty blocks for big-block filesystems. */
840 lost_and_found_blocks = MIN(EXT2_NDIR_BLOCKS,
841 16 >> (blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE));
843 // the last group needs more attention: isn't it too small for possible overhead?
844 overhead = (has_super(ngroups - 1) ?
845 (1/*sb*/ + group_desc_blocks) : 0) + 1/*bbmp*/ + 1/*ibmp*/ + inode_table_blocks;
846 remainder = (nblocks - first_block) % blocks_per_group;
847 if (remainder && (remainder < overhead + 50)) {
848 nblocks -= remainder;
853 if (nblocks_full - nblocks)
854 printf("warning: %u blocks unused\n\n", nblocks_full - nblocks);
856 "Filesystem label=%s\n"
858 "Block size=%u (log=%u)\n"
859 "Fragment size=%u (log=%u)\n"
860 "%u inodes, %u blocks\n"
861 "%u blocks (%u%%) reserved for the super user\n"
862 "First data block=%u\n"
863 "Maximum filesystem blocks=%u\n"
865 "%u blocks per group, %u fragments per group\n"
866 "%u inodes per group"
868 , blocksize, blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE
869 , blocksize, blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE
870 , inodes_per_group * ngroups, nblocks
871 , nreserved, reserved_percent
873 , group_desc_blocks * (blocksize / (unsigned)sizeof(*gd)) * blocks_per_group
875 , blocks_per_group, blocks_per_group
879 const char *fmt = "\nSuperblock backups stored on blocks:\n"
882 for (i = 1; i < ngroups; i++) {
883 pos += blocks_per_group;
885 printf(fmt, (unsigned)pos);
892 // fill the superblock
894 STORE_LE(sb->revision_level, EXT2_DYNAMIC_REV); // revision 1 filesystem
895 STORE_LE(sb->magic, EXT2_SUPER_MAGIC);
896 STORE_LE(sb->inode_size, inodesize);
897 // set "Required extra isize" and "Desired extra isize" fields to 28
898 //if (inodesize != sizeof(*inode))
899 //STORE_LE(sb->s_reserved[21], 0x001C001C);
900 STORE_LE(sb->first_inode, EXT2_GOOD_OLD_FIRST_INO);
901 STORE_LE(sb->log2_block_size, blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE);
902 STORE_LE(sb->log2_fragment_size,
903 blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE);
904 // first 1024 bytes of the device are for boot record. If block size is 1024 bytes, then
905 // the first block is 1, otherwise 0
906 STORE_LE(sb->first_data_block, first_block);
907 // block and inode bitmaps occupy no more than one block, so maximum number of blocks is
908 STORE_LE(sb->s_blocks_per_group, blocks_per_group);
909 STORE_LE(sb->fragments_per_group, blocks_per_group);
911 STORE_LE(sb->total_blocks, nblocks);
912 // reserve blocks for superuser
913 STORE_LE(sb->reserved_blocks, nreserved);
915 STORE_LE(sb->inodes_per_group, inodes_per_group);
916 STORE_LE(sb->total_inodes, inodes_per_group * ngroups);
917 STORE_LE(sb->free_inodes,
918 inodes_per_group * ngroups - EXT2_GOOD_OLD_FIRST_INO);
919 /* TODO: Implement timestamps, currently commented*/
922 timestamp = time(NULL);
923 STORE_LE(sb->s_mkfs_time, timestamp);
924 STORE_LE(sb->s_wtime, timestamp);
925 STORE_LE(sb->s_lastcheck, timestamp);
927 // misc. Values are chosen to match mke2fs 1.41.9
928 STORE_LE(sb->fs_state, 1); // TODO: what's 1?
929 STORE_LE(sb->creator_os, EXT2_OS_LINUX);
930 STORE_LE(sb->checkinterval, 24*60*60 * 180); // 180 days
931 STORE_LE(sb->error_handling, EXT2_ERRORS_DEFAULT);
932 // mke2fs 1.41.9 also sets EXT3_FEATURE_COMPAT_RESIZE_INODE
933 // and if >= 0.5GB, EXT3_FEATURE_RO_COMPAT_LARGE_FILE.
934 // we use values which match "mke2fs -O ^resize_inode":
935 // in this case 1.41.9 never sets EXT3_FEATURE_RO_COMPAT_LARGE_FILE.
936 STORE_LE(sb->feature_compatibility, EXT2_FEATURE_COMPAT_SUPP
937 //| (EXT2_FEATURE_COMPAT_RESIZE_INO * ENABLE_FEATURE_MKFS_EXT2_RESERVED_GDT)
938 | (ENABLE_FEATURE_MKFS_EXT2_RESERVED_GDT)
939 | (EXT2_FEATURE_COMPAT_DIR_INDEX * ENABLE_FEATURE_MKFS_EXT2_DIR_INDEX));
940 STORE_LE(sb->feature_incompat, EXT2_FEATURE_INCOMPAT_FILETYPE);
941 STORE_LE(sb->feature_ro_compat, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER);
942 //STORE_LE(sb->s_flags, EXT2_FLAGS_UNSIGNED_HASH * ENABLE_FEATURE_MKFS_EXT2_DIR_INDEX);
943 //generate_uuid(sb->s_uuid);
944 //if (ENABLE_FEATURE_MKFS_EXT2_DIR_INDEX) {
945 //STORE_LE(sb->s_def_hash_version, EXT2_HASH_HALF_MD4);
946 // generate_uuid((uint8_t *)sb->s_hash_seed);
949 * From e2fsprogs: add "jitter" to the superblock's check interval so that we
950 * don't check all the filesystems at the same time. We use a
951 * kludgy hack of using the UUID to derive a random jitter value.
953 STORE_LE(sb->max_mnt_count,EXT2_DFL_MAX_MNT_COUNT);
954 //+ (sb->s_uuid[ARRAY_SIZE(sb->s_uuid)-1] % EXT2_DFL_MAX_MNT_COUNT));
957 safe_strncpy((char *)sb->volume_name, label, sizeof(sb->volume_name));
959 // calculate filesystem skeleton structures
960 gd = xzalloc(group_desc_blocks * blocksize);
961 buf = xmalloc(blocksize);
963 for (i = 0, pos = first_block, n = nblocks - first_block;
965 i++, pos += blocks_per_group, n -= blocks_per_group
967 memset(buf,'\0',blocksize);
969 uint32_t overhead = pos + (has_super(i) ?
970 (1/*sb*/ + group_desc_blocks) : 0);
971 uint32_t free_blocks;
972 // fill group descriptors
973 STORE_LE(gd[i].bg_block_bitmap, overhead + 0);
974 STORE_LE(gd[i].bg_inode_bitmap, overhead + 1);
975 STORE_LE(gd[i].bg_inode_table, overhead + 2);
977 overhead - pos + 1/*bbmp*/ + 1/*ibmp*/ + inode_table_blocks;
978 gd[i].bg_free_inodes_count = inodes_per_group;
979 //STORE_LE(gd[i].bg_used_dirs_count, 0);
980 // N.B. both "/" and "/lost+found" are within the first block group
981 // "/" occupies 1 block, "/lost+found" occupies lost_and_found_blocks...
983 // ... thus increased overhead for the first block group ...
984 overhead += 1 + lost_and_found_blocks;
985 // ... and 2 used directories
986 STORE_LE(gd[i].bg_used_dirs_count, 2);
987 // well known reserved inodes belong to the first block too
988 gd[i].bg_free_inodes_count -= EXT2_GOOD_OLD_FIRST_INO;
991 // cache free block count of the group
992 free_blocks = (n < blocks_per_group ? n : blocks_per_group)
995 // mark preallocated blocks as allocated
996 allocate(buf, blocksize,
997 // reserve "overhead" blocks
999 // mark unused trailing blocks
1000 blocks_per_group - (free_blocks + overhead)
1002 // dump block bitmap
1003 PUT(dev_desc,(uint64_t)(FETCH_LE32(gd[i].bg_block_bitmap)) * blocksize,
1005 STORE_LE(gd[i].bg_free_blocks_count, free_blocks);
1006 memset(buf,'\0',blocksize);
1008 // mark preallocated inodes as allocated
1009 allocate(buf, blocksize,
1010 // mark reserved inodes
1011 inodes_per_group - gd[i].bg_free_inodes_count,
1012 // mark unused trailing inodes
1013 blocks_per_group - inodes_per_group
1015 // dump inode bitmap, but it's right after block bitmap, so we can just:
1016 //Modified to write in immediate block after block bitmap
1017 PUT(dev_desc,((uint64_t)(FETCH_LE32(gd[i].bg_block_bitmap))+1) * blocksize,
1019 STORE_LE(gd[i].bg_free_inodes_count, gd[i].bg_free_inodes_count);
1021 // count overall free blocks
1022 sb->free_blocks += free_blocks;
1024 STORE_LE(sb->free_blocks, sb->free_blocks);
1026 // dump filesystem skeleton structures
1027 for (i = 0, pos = first_block; i < ngroups; i++, pos += blocks_per_group) {
1028 // dump superblock and group descriptors and their backups
1030 // N.B. 1024 byte blocks are special
1031 PUT(dev_desc,((uint64_t)pos * blocksize) +
1032 ((0 == i && 1024 != blocksize) ? 1024 : 0),
1034 PUT(dev_desc,((uint64_t)pos * blocksize) + blocksize,
1035 gd, group_desc_blocks * blocksize);
1039 // zero boot sectors
1040 /* Magic number is written in first block*/
1041 buffer= (char *)xmalloc(1024);
1042 temp_buffer= (char *)xmalloc(1024);
1043 memset(buffer, 0, 1024);
1044 buffer[DOS_PART_MAGIC_OFFSET] = 0x55;
1045 buffer[DOS_PART_MAGIC_OFFSET + 1] = 0xaa;
1047 /* Read the first block and restore the partition info into first block*/
1048 dev_desc->block_read (dev_desc->dev, 0, 1, (ulong *) temp_buffer);
1049 temp_pt = (dos_partition_t *) (temp_buffer + DOS_PART_TBL_OFFSET);
1052 memcpy(buffer+DOS_PART_TBL_OFFSET,pt,sizeof(dos_partition_t));
1053 PUT(dev_desc,0, buffer, 1024);
1054 memset(buf, 0, blocksize);
1057 // zero inode tables
1058 for (i = 0; i < ngroups; ++i)
1059 for (n = 0; n < inode_table_blocks; ++n){
1061 (uint64_t)(FETCH_LE32(gd[i].bg_inode_table) + n)
1062 * blocksize, buf, blocksize);
1066 // prepare directory inode
1067 inode = (struct ext2_inode *)buf;
1068 STORE_LE(inode->i_mode, S_IFDIR | S_IRWXU | S_IRGRP | S_IROTH | S_IXGRP | S_IXOTH);
1069 STORE_LE(inode->i_mtime, timestamp);
1070 STORE_LE(inode->i_atime, timestamp);
1071 STORE_LE(inode->i_ctime, timestamp);
1072 STORE_LE(inode->i_size, blocksize);
1074 // inode->i_blocks stores the number of 512 byte data blocks
1075 // (512, because it goes directly to struct stat without scaling)
1076 STORE_LE(inode->i_blocks, blocksize / 512);
1078 // dump root dir inode
1079 STORE_LE(inode->i_links_count, 3); // "/.", "/..", "/lost+found/.." point to this inode
1080 STORE_LE(inode->i_block[0],
1081 FETCH_LE32(gd[0].bg_inode_table) + inode_table_blocks);
1082 PUT(dev_desc,((uint64_t)FETCH_LE32(gd[0].bg_inode_table) * blocksize) +
1083 (EXT2_ROOT_INO-1) * inodesize,buf, inodesize);
1085 // dump lost+found dir inode
1086 STORE_LE(inode->i_links_count, 2); // both "/lost+found" and "/lost+found/." point to this inode
1087 STORE_LE(inode->i_size, lost_and_found_blocks * blocksize);
1088 STORE_LE(inode->i_blocks, (lost_and_found_blocks * blocksize) / 512);
1089 n = FETCH_LE32(inode->i_block[0]) + 1;
1091 for (i = 0; i < lost_and_found_blocks; ++i)
1092 STORE_LE(inode->i_block[i], i + n); // use next block
1093 PUT(dev_desc,((uint64_t)FETCH_LE32(gd[0].bg_inode_table) * blocksize) +
1094 (EXT2_GOOD_OLD_FIRST_INO-1) * inodesize, buf, inodesize);
1097 memset(buf, 0, blocksize);
1098 dir = (struct ext2_dir *)buf;
1100 // dump 2nd+ blocks of "/lost+found"
1101 STORE_LE(dir->rec_len1, blocksize); // e2fsck 1.41.4 compat (1.41.9 does not need this)
1102 for (i = 1; i < lost_and_found_blocks; ++i) {
1103 PUT(dev_desc,(uint64_t)(FETCH_LE32(gd[0].bg_inode_table) +
1104 inode_table_blocks + 1+i) * blocksize, buf, blocksize);
1106 // dump 1st block of "/lost+found"
1107 STORE_LE(dir->inode1, EXT2_GOOD_OLD_FIRST_INO);
1108 STORE_LE(dir->rec_len1, 12);
1109 STORE_LE(dir->name_len1, 1);
1110 STORE_LE(dir->file_type1, EXT2_FT_DIR);
1111 dir->name1[0] = '.';
1112 STORE_LE(dir->inode2, EXT2_ROOT_INO);
1113 STORE_LE(dir->rec_len2, blocksize - 12);
1114 STORE_LE(dir->name_len2, 2);
1115 STORE_LE(dir->file_type2, EXT2_FT_DIR);
1116 dir->name2[0] = '.'; dir->name2[1] = '.';
1117 PUT(dev_desc,(uint64_t)(FETCH_LE32(gd[0].bg_inode_table) +
1118 inode_table_blocks + 1) * blocksize, buf, blocksize);
1120 // dump root dir block
1121 STORE_LE(dir->inode1, EXT2_ROOT_INO);
1122 STORE_LE(dir->rec_len2, 12);
1123 STORE_LE(dir->inode3, EXT2_GOOD_OLD_FIRST_INO);
1124 STORE_LE(dir->rec_len3, blocksize - 12 - 12);
1125 STORE_LE(dir->name_len3, 10);
1126 STORE_LE(dir->file_type3, EXT2_FT_DIR);
1127 strcpy(dir->name3, "lost+found");
1128 PUT(dev_desc,(uint64_t)(FETCH_LE32(gd[0].bg_inode_table) +
1129 inode_table_blocks + 0) * blocksize, buf, blocksize);
1137 int ext2_register_device (block_dev_desc_t * dev_desc, int part_no)
1139 unsigned char buffer[SECTOR_SIZE];
1141 disk_partition_t info;
1143 if (!dev_desc->block_read)
1146 /* check if we have a MBR (on floppies we have only a PBR) */
1147 if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)buffer) != 1) {
1148 printf("** Can't read from device %d **\n",
1152 if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 ||
1153 buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) {
1154 /* no signature found */
1158 /* First we assume there is a MBR */
1159 if (!get_partition_info(dev_desc, part_no, &info)) {
1160 part_offset = info.start;
1162 part_size = info.size;
1163 } else if ((strncmp((char *)&buffer[DOS_FS_TYPE_OFFSET], "FAT", 3) == 0) ||
1164 (strncmp((char *)&buffer[DOS_FS32_TYPE_OFFSET], "FAT32", 5) == 0)) {
1165 /* ok, we assume we are on a PBR only */
1169 printf("** Partition %d not valid on device %d **\n",
1170 part_no, dev_desc->dev);
1177 int do_ext2_format (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1179 char *filename = "/";
1183 block_dev_desc_t *dev_desc=NULL;
1185 disk_partition_t info;
1188 return cmd_usage(cmdtp);
1190 dev = (int)simple_strtoul (argv[2], &ep, 16);
1191 dev_desc = get_dev(argv[1],dev);
1193 if (dev_desc == NULL) {
1194 printf ("\n** Block device %s %d not supported\n", argv[1], dev);
1200 puts ("\n** Invalid boot device, use `dev[:part]' **\n");
1203 part = (int)simple_strtoul(++ep, NULL, 16);
1209 PRINTF("Using device %s %d:%d, directory: %s\n", argv[1], dev, part, filename);
1211 if ((part_length = ext2fs_set_blk_dev(dev_desc, part)) == 0) {
1212 printf ("** Bad partition - %s %d:%d **\n", argv[1], dev, part);
1217 if (ext2_register_device(dev_desc,part)!=0) {
1218 printf("\n** Unable to use %s %d:%d for fattable **\n",
1219 argv[1], dev, part);
1223 if (!get_partition_info(dev_desc, part, &info)) {
1224 total_sector = (info.size * info.blksz) / SECTOR_SIZE;
1226 printf("error : get partition info\n");
1230 printf("formatting\n");
1231 if (mkfs_ext2(dev_desc, part))
1238 ext2format, 3, 1, do_ext2_format,
1239 "format device as EXT2 filesystem",
1240 "<interface> <dev[:part]>\n"
1241 " - format device as EXT2 filesystem on 'dev'"