2 /**************************************************
3 UZI (Unix Z80 Implementation) Utilities: mkfs.c
4 ***************************************************/
10 #include <sys/types.h>
16 /* This makes a filesystem
19 * ./mkfs ./blankfs.img 64 4096
20 * (this will write a 2MB filesystem with 64 blocks of inodes to ./blankfs.img)
31 struct dinode inode[8];
34 void mkfs(uint16_t fsize, uint16_t isize, uint8_t shift);
35 void dwrite(uint16_t blk, char *addr);
42 static void usage(void)
44 printf("Usage: mkfs [-X] [-b blocksize] device isize fsize\n");
48 static uint8_t validate(uint16_t bsize)
64 fprintf(stderr, "mkfs: unsupported block size.\n");
69 int main(int argc, char **argv)
71 uint16_t fsize, isize, bsize = 512, shift = 0;
76 while((opt = getopt(argc, argv, "Xb:")) != -1) {
83 shift = validate(bsize);
89 if (argc - optind != 3)
92 if (sizeof(inode) != 512) {
93 printf("inode is the wrong size -- %d\n",
97 isize = (uint16_t) atoi(argv[optind + 1]);
98 fsize = (uint16_t) atoi(argv[optind + 2]);
100 if (fsize < 3 || isize < 2 || isize >= fsize) {
101 printf("Bad parameter values\n");
105 memset(zero512, 0, 512);
107 printf("Making %d byte/block filesystem with %s byte order on device %s with fsize = %u and isize = %u.\n",
108 bsize, swizzling==0 ? "normal" : "reversed", argv[optind], fsize, isize);
110 if (fd_open(argv[optind])) {
111 printf("Can't open device");
117 /* Zero out the blocks */
118 for (j = 0; j < s; ++j)
121 /* Initialize the super-block */
123 fs_super.fs.s_mounted = swizzle16(SMOUNTED); /* Magic number */
124 fs_super.fs.s_isize = swizzle16(isize);
125 fs_super.fs.s_fsize = swizzle16(fsize);
126 fs_super.fs.s_nfree = swizzle16(1);
127 fs_super.fs.s_free[0] = 0;
128 fs_super.fs.s_tfree = 0;
129 fs_super.fs.s_ninode = 0;
130 fs_super.fs.s_tinode = swizzle16(8 * (isize - 2) - 2);
131 fs_super.fs.s_shift = shift;
133 /* Free each block, building the free list. This is done in
134 terms of the block shift, while isize is in 512 byte blocks.
135 Adjust isize so that it's in block terms and references the
136 block after the last inode */
140 /* Don't free the block isize because it's got the / directory in it */
141 for (j = fsize - 1; j > isize; --j) {
143 if (swizzle16(fs_super.fs.s_nfree) == 50) {
144 dwrite(j, (char *) &fs_super.fs.s_nfree);
145 fs_super.fs.s_nfree = 0;
148 fs_super.fs.s_tfree =
149 swizzle16(swizzle16(fs_super.fs.s_tfree) + 1);
150 n = swizzle16(fs_super.fs.s_nfree);
151 fs_super.fs.s_free[n++] = swizzle16(j);
152 fs_super.fs.s_nfree = swizzle16(n);
155 /* The inodes are already zeroed out */
156 /* create the root dir */
157 inode[ROOTINODE].i_mode = swizzle16(F_DIR | (0777 & MODE_MASK));
158 inode[ROOTINODE].i_nlink = swizzle16(3);
159 inode[ROOTINODE].i_size = swizzle32(64);
160 inode[ROOTINODE].i_addr[0] = swizzle16(isize);
162 /* Reserve reserved inode */
163 inode[0].i_nlink = swizzle16(1);
164 inode[0].i_mode = ~0;
166 dwrite(2, (char *) inode);
168 dirbuf[0].d_ino = swizzle16(dirbuf[0].d_ino);
169 dirbuf[1].d_ino = swizzle16(dirbuf[1].d_ino);
170 dwrite(isize, (char *) dirbuf);
172 /* Write out super block */
173 dwrite(1, (char *) &fs_super);
177 void dwrite(uint16_t blk, char *addr)
179 lseek(dev_fd, ((int) blk) * 512, SEEK_SET);
180 if (write(dev_fd, addr, 512) != 512) {