int mkfs(int nblocks, int ninodes, int size) { int i; char buf[BLOCK_SIZE]; sb.size = xint(size); sb.nblocks = xint(nblocks); // so whole disk is size sectors sb.ninodes = xint(ninodes); bitblocks = size/(512*8) + 1; usedblocks = ninodes / IPB + 3 + bitblocks; freeblock = usedblocks; printf("used %d (bit %d ninode %zu) free %u total %d\n", usedblocks, bitblocks, ninodes/IPB + 1, freeblock, nblocks+usedblocks); assert(nblocks + usedblocks == size); for(i = 0; i < nblocks + usedblocks; i++) wsect(i, zeroes); memset(buf, 0, sizeof(buf)); memmove(buf, &sb, sizeof(sb)); wsect(1, buf); return 0; }
void iappend(uint inum, void *xp, int n) { char *p = (char *)xp; uint fbn, off, n1; struct dinode din; char buf[512]; uint indirect[NINDIRECT]; uint x; rinode(inum, &din); off = xint(din.size); while (n > 0) { fbn = off / 512; assert(fbn < MAXFILE); if (fbn < NDIRECT) { if (xint(din.addrs[fbn]) == 0) { din.addrs[fbn] = xint(freeblock++); usedblocks++; } x = xint(din.addrs[fbn]); } else { if (xint(din.addrs[NDIRECT]) == 0) { // printf("allocate indirect block\n"); din.addrs[NDIRECT] = xint(freeblock++); usedblocks++; } // printf("read indirect block\n"); rsect(xint(din.addrs[NDIRECT]), (char *)indirect); if (indirect[fbn - NDIRECT] == 0) { indirect[fbn - NDIRECT] = xint(freeblock++); usedblocks++; wsect(xint(din.addrs[NDIRECT]), (char *)indirect); } x = xint(indirect[fbn - NDIRECT]); } n1 = min(n, (fbn + 1) * 512 - off); rsect(x, buf); memcpy(buf + off - (fbn * 512), p, n1); wsect(x, buf); n -= n1; off += n1; p += n1; } din.size = xint(off); winode(inum, &din); }
void balloc(int used) { uchar buf[512]; int i; int j = 0; int temp; printf("balloc: first %d blocks have been allocated\n", used); //assert(used < 512*8); while(used > 0) { bzero(buf, 512); if (used > 4096) { temp = 4096; } else { temp = used; } for(i = 0; i < temp; i++){ buf[i/8] = buf[i/8] | (0x1 << (i%8)); } used -= 4096; printf("balloc: write bitmap block at sector %zu\n", ninodes/IPB + 3 + j); wsect(ninodes / IPB + 3 + j, buf); j++; } }
void iappend(uint inum, void *xp, int n) { char *p = (char*)xp; uint fbn, off, n1; struct dinode din; char buf[BSIZE]; uint indirect[NINDIRECT]; uint x; rinode(inum, &din); off = xint(din.size); // printf("append inum %d at off %d sz %d\n", inum, off, n); while(n > 0){ fbn = off / BSIZE; assert(fbn < MAXFILE); if(fbn < NDIRECT){ if(xint(din.addrs[fbn]) == 0){ din.addrs[fbn] = xint(freeblock++); } x = xint(din.addrs[fbn]); } else { if(xint(din.addrs[NDIRECT]) == 0){ din.addrs[NDIRECT] = xint(freeblock++); } rsect(xint(din.addrs[NDIRECT]), (char*)indirect); if(indirect[fbn - NDIRECT] == 0){ indirect[fbn - NDIRECT] = xint(freeblock++); wsect(xint(din.addrs[NDIRECT]), (char*)indirect); } x = xint(indirect[fbn-NDIRECT]); } n1 = min(n, (fbn + 1) * BSIZE - off); rsect(x, buf); bcopy(p, buf + off - (fbn * BSIZE), n1); wsect(x, buf); n -= n1; off += n1; p += n1; } din.size = xint(off); winode(inum, &din); }
void winode(uint inum, struct dinode *ip) { char buf[512]; uint bn; struct dinode *dip; bn = i2b(inum); rsect(bn, buf); dip = ((struct dinode *)buf) + (inum % IPB); *dip = *ip; wsect(bn, buf); }
void winode(uint inum, struct dinode *ip) { char buf[BSIZE]; uint bn; struct dinode *dip; bn = IBLOCK(inum, sb); rsect(bn, buf); dip = ((struct dinode*)buf) + (inum % IPB); *dip = *ip; wsect(bn, buf); }
void winode(uint inum, struct dinode *ip) { char buf[BSIZE]; uint bn; struct dinode *dip; bn = IBLOCK(inum); rsect(bn, buf); dip = ((struct dinode*)buf) + (inum % IPB); *dip = *ip; printf("winode %d bn %d\n", inum, bn); wsect(bn, buf); }
void balloc(int used) { uchar buf[BSIZE]; int i; printf("balloc: first %d blocks have been allocated\n", used); assert(used < BSIZE*8); bzero(buf, BSIZE); for(i = 0; i < used; i++){ buf[i/8] = buf[i/8] | (0x1 << (i%8)); } printf("balloc: write bitmap block at sector %d\n", sb.bmapstart); wsect(sb.bmapstart, buf); }
void balloc(int used) { uchar buf[512]; int i; printf("balloc: first %d blocks have been allocated\n", used); assert(used < 512*8); bzero(buf, 512); for(i = 0; i < used; i++){ buf[i/8] = buf[i/8] | (0x1 << (i%8)); } printf("balloc: write bitmap block at sector %zu\n", ninodes/IPB + 3); wsect(ninodes / IPB + 3, buf); }
void balloc(int used) { uchar buf[1024]; int i; uint sz = sizeof(buf)/sizeof(buf[0]); printf("balloc: first %d blocks have been allocated\n", used); assert(used < sz); bzero(buf, sz); for(i = 0; i < used; i++) { buf[i/8] = buf[i/8] | (0x1 << (i%8)); } printf("balloc: write bitmap block at sector %zu\n", ninodes/IPB + 3); wsect(ninodes / IPB + 3, buf); }
void balloc(int used) { uchar buf[512]; int i, j = 0; printf("balloc: first %d blocks have been allocated\n", used); //assert(used < 512*8); while(used > 0) { bzero(buf, 512); for(i = 0; i < used && i < 512; i++){ buf[i/8] = buf[i/8] | (0x1 << (i%8)); } used -= 512; printf("%dballoc: write bitmap block at sector %zu\n", used, ninodes/IPB + 3+j); wsect(ninodes / IPB + 3 + j, buf); j ++; } printf("balloc finished."); }
int main(int argc, char *argv[]) { int i, cc, fd; uint rootino, inum, off; struct dirent de; char buf[512]; struct dinode din; static_assert(sizeof(int) == 4, "Integers must be 4 bytes!"); if(argc < 2){ fprintf(stderr, "Usage: mkfs fs.img files...\n"); exit(1); } assert((512 % sizeof(struct dinode)) == 0); assert((512 % sizeof(struct dirent)) == 0); fsfd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666); if(fsfd < 0){ perror(argv[1]); exit(1); } sb.size = xint(size); sb.nblocks = xint(nblocks); // so whole disk is size sectors sb.ninodes = xint(ninodes); sb.nlog = xint(nlog); bitblocks = size/(512*8) + 1; usedblocks = ninodes / IPB + 3 + bitblocks; freeblock = usedblocks; printf("used %d (bit %d ninode %zu) free %u log %u total %d\n", usedblocks, bitblocks, ninodes/IPB + 1, freeblock, nlog, nblocks+usedblocks+nlog); assert(nblocks + usedblocks + nlog == size); for(i = 0; i < nblocks + usedblocks + nlog; i++) wsect(i, zeroes); memset(buf, 0, sizeof(buf)); memmove(buf, &sb, sizeof(sb)); wsect(1, buf); rootino = ialloc(T_DIR); assert(rootino == ROOTINO); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, "."); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(rootino, &de, sizeof(de)); for(i = 2; i < argc; i++){ char *name = argv[i]; if (!strncmp(name, "fs/", 3)) name += 3; assert(index(name, '/') == 0); if((fd = open(argv[i], 0)) < 0){ perror(argv[i]); exit(1); } inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, name, DIRSIZ); iappend(rootino, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) iappend(inum, buf, cc); close(fd); } // fix size of root inode dir rinode(rootino, &din); off = xint(din.size); off = ((off/BSIZE) + 1) * BSIZE; din.size = xint(off); winode(rootino, &din); balloc(usedblocks); exit(0); }
int main(int argc, char *argv[]) { int i, cc, fd; uint rootino, inum, off; struct dirent de; char buf[BSIZE]; struct dinode din; static_assert(sizeof(int) == 4, "Integers must be 4 bytes!"); if(argc < 2){ fprintf(stderr, "Usage: mkfs fs.img files...\n"); exit(1); } assert((BSIZE % sizeof(struct dinode)) == 0); assert((BSIZE % sizeof(struct dirent)) == 0); fsfd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666); if(fsfd < 0){ perror(argv[1]); exit(1); } // 1 fs block = 1 disk sector nmeta = 2 + nlog + ninodeblocks + nbitmap; nblocks = FSSIZE - nmeta; sb.size = xint(FSSIZE); sb.nblocks = xint(nblocks); sb.ninodes = xint(NINODES); sb.nlog = xint(nlog); sb.logstart = xint(2); sb.inodestart = xint(2+nlog); sb.bmapstart = xint(2+nlog+ninodeblocks); printf("nmeta %d (boot, super, log blocks %u inode blocks %u, bitmap blocks %u) blocks %d total %d\n", nmeta, nlog, ninodeblocks, nbitmap, nblocks, FSSIZE); freeblock = nmeta; // the first free block that we can allocate for(i = 0; i < FSSIZE; i++) wsect(i, zeroes); memset(buf, 0, sizeof(buf)); memmove(buf, &sb, sizeof(sb)); wsect(1, buf); rootino = ialloc(T_DIR); assert(rootino == ROOTINO); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, "."); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(rootino, &de, sizeof(de)); for(i = 2; i < argc; i++){ assert(index(argv[i], '/') == 0); if((fd = open(argv[i], 0)) < 0){ perror(argv[i]); exit(1); } // Skip leading _ in name when writing to file system. // The binaries are named _rm, _cat, etc. to keep the // build operating system from trying to execute them // in place of system binaries like rm and cat. if(argv[i][0] == '_') ++argv[i]; inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, argv[i], DIRSIZ); iappend(rootino, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) iappend(inum, buf, cc); close(fd); } // fix size of root inode dir rinode(rootino, &din); off = xint(din.size); off = ((off/BSIZE) + 1) * BSIZE; din.size = xint(off); winode(rootino, &din); balloc(freeblock); exit(0); }
int main(int argc, char *argv[]) { int i, cc, fd; uint rootino, inum, off, bin_inum, tests_inum, sbin_inum; //dir_inum struct dirent de; char buf[BSIZE]; struct dinode din; static_assert(sizeof(int) == 4, "Integers must be 4 bytes!"); if(argc < 2) { fprintf(stderr, "Usage: mkfs fs.img files...\n"); exit(1); } assert((BSIZE % sizeof(struct dinode)) == 0); assert((BSIZE % sizeof(struct dirent)) == 0); fsfd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, 0666); if(fsfd < 0) { perror(argv[1]); exit(1); } // 1 fs block = 1 disk sector nmeta = 2 + nlog + ninodeblocks + nbitmap; nblocks = FSSIZE - nmeta; sb.size = xint(FSSIZE); sb.nblocks = xint(nblocks); sb.ninodes = xint(NINODES); sb.nlog = xint(nlog); sb.logstart = xint(2); sb.inodestart = xint(2 + nlog); sb.bmapstart = xint(2 + nlog + ninodeblocks); printf("nmeta %d (boot, super, log blocks %u inode blocks %u, bitmap blocks %u) blocks %d total %d\n", nmeta, nlog, ninodeblocks, nbitmap, nblocks, FSSIZE); freeblock = nmeta; // the first free block that we can allocate for(i = 0; i < FSSIZE; i++) { wsect(i, zeroes); } memset(buf, 0, sizeof(buf)); memmove(buf, &sb, sizeof(sb)); wsect(1, buf); rootino = ialloc(T_DIR); assert(rootino == ROOTINO); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, "."); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(rootino, &de, sizeof(de)); // create /bin folder bin_inum = ialloc(T_DIR); bzero(&de, sizeof(de)); de.inum = xshort(bin_inum); strcpy(de.name, "bin"); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(bin_inum); strcpy(de.name, "."); iappend(bin_inum, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(bin_inum, &de, sizeof(de)); // create /dev folder inum = ialloc(T_DIR); bzero(&de, sizeof(de)); de.inum = xshort(inum); strcpy(de.name, "dev"); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(inum); strcpy(de.name, "."); iappend(inum, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(inum, &de, sizeof(de)); // create /sbin folder sbin_inum = ialloc(T_DIR); bzero(&de, sizeof(de)); de.inum = xshort(sbin_inum); strcpy(de.name, "sbin"); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(sbin_inum); strcpy(de.name, "."); iappend(sbin_inum, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(sbin_inum, &de, sizeof(de)); // create /tests folder tests_inum = ialloc(T_DIR); bzero(&de, sizeof(de)); de.inum = xshort(tests_inum); strcpy(de.name, "tests"); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(tests_inum); strcpy(de.name, "."); iappend(tests_inum, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(tests_inum, &de, sizeof(de)); for(i = 2; i < argc; i++) { printf("argv[i]: %s and index: %s\n", argv[i], index(argv[i], '/')); //assert(index(argv[i], '/') == 0); if((fd = open(argv[i], 0)) < 0) { perror(argv[i]); exit(1); } if(index(argv[i], '/') != 0) { char foldername[256]; char *progname = malloc(sizeof(char) * 256); strcpy(progname, skipelem(argv[i], foldername)); if(progname[0] == '_') { progname++; } if(strcmp(foldername, "bin") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(bin_inum, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else if(strcmp(foldername, "tests") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(tests_inum, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else if(strcmp(foldername, "sbin") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(sbin_inum, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else if(strcmp(foldername, "docs") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(rootino, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else if(strcmp(foldername, "shell") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(bin_inum, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else { printf("\nERROR: Found folder other than bin and tests: %s\n", foldername); exit(1); } } else { // Skip leading _ in name when writing to file system. // The binaries are named _rm, _cat, etc. to keep the // build operating system from trying to execute them // in place of system binaries like rm and cat. if(argv[i][0] == '_') { ++argv[i]; } inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, argv[i], DIRSIZ); iappend(rootino, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } } // fix size of root inode dir rinode(rootino, &din); off = xint(din.size); off = ((off / BSIZE) + 1) * BSIZE; din.size = xint(off); winode(rootino, &din); balloc(freeblock); exit(0); }
void iappend(uint inum, void *xp, int n) { char *p = (char*)xp; uint fbn, off, n1; struct dinode din; char buf[512]; uint indirect[512]; uint x; rinode(inum, &din); int temp_fbn, d1, d2, k1, k2, k3, a1, a2, a3; off = xint(din.size); while(n > 0){ //printf("%d\n", n); fbn = off / 512; //assert(fbn < MAXFILE); if(fbn < NDIRECT){ //printf("hjw 1 %d\n", n); if(xint(din.addrs[fbn]) == 0){ din.addrs[fbn] = xint(freeblock++); usedblocks++; } x = xint(din.addrs[fbn]); } else { temp_fbn = fbn; temp_fbn -= NDIRECT; d1 = temp_fbn / 128; k1 = temp_fbn % 128; d2 = d1 / 128; k2 = d1 % 128; //d3 = d2 / 128; k3 = d2 % 128; if((a1 = din.addrs[NDIRECT]) == 0) { a1 = din.addrs[NDIRECT] = xint(freeblock++); usedblocks ++; } rsect(xint(a1), (char*)indirect); if((a2 = indirect[k3]) == 0) { a2 = indirect[k3] = xint(freeblock++); usedblocks ++; wsect(xint(a1), (char*)indirect); } rsect(xint(a2), (char*)indirect); if((a3 = indirect[k2]) == 0) { a3 = indirect[k2] = xint(freeblock++); usedblocks ++; wsect(xint(a2), (char*)indirect); } rsect(xint(a3), (char*)indirect); if((x = indirect[k1]) == 0) { x = indirect[k1] = xint(freeblock++); usedblocks ++; wsect(xint(a3), (char*)indirect); } x = xint(x); //printf("%d--", fbn); } //printf("%d\n", x); n1 = min(n, (fbn + 1) * 512 - off); rsect(x, buf); //printf("hjw 2 %d %d %d %d\n", n, off - (fbn * 512), n1, sizeof(p)); bcopy(p, buf + off - (fbn * 512), n1); // printf("hjw 3 %d\n", n); wsect(x, buf); n -= n1; off += n1; p += n1; } din.size = xint(off); winode(inum, &din); }
void szero(uint sec) { uchar buf[SECSIZE]; memset(buf, 0, SECSIZE); wsect(sec, buf); }
int main(int argc, char *argv[]) { // 局部变量 char buf[SECSIZE]; // FAT表表头标记 uchar fatStartContent[8] = {0xf8,0xff,0xff,0x0f,0xff,0xff,0xff,0xff}; struct direntry dire; uint dirClusNum; // 为文件分配的簇号 uint wClusNum; // 根目录簇号 uint fileSize; // 文件大小 uint cc, fd; // cc一次读取文件的字节数,打开文件的fd int rootWSize = 0; // 已向根目录写入的字节数 int fileWSize = 0; // 已向文件中写入的字节数 char filename[FNSIZE]; // 文件名 int i; static_assert(sizeof(int) == 4, "Integers must be 4 bytes!"); if(argc < 2){ fprintf(stderr, "Usage: mkfs fs.img files...\n"); exit(1); } initDat(); // 是否有需要断言 // ? fsfd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666); if(fsfd < 0){ perror(argv[1]); exit(1); } printf("DBR : %d, retain sectors: %d, FAT sector: %d, 2 FATs, data sectors: %d, clusters: %d", nDBR, nRetain, nFAT, nData, nDataClus); // 清零fs for(i = 0; i < FSSIZE; i++) szero(i); // 向第0扇区写入DBR initDBR(); memset(buf, 0, sizeof(buf)); memmove(buf, &fatDBR, sizeof(fatDBR)); wsect(0, buf); // 写入FAT表头标记 rsect4bytes(fatFstSec, 0, fatStartContent); rsect4bytes(fatFstSec, 1, fatStartContent + 4); // 写入根目录 dire = mkFCB(T_DIR, "/", sizeof(DIR)*argc, &dirClusNum); dirClusNum = appendBuf(dirClusNum, &dire, sizeof(DIR), rootWSize); rootWSize += sizeof(DIR); wClusNum = dirClusNum; dire = mkFCB(T_DIR, ".", sizeof(DIR)*argc, &dirClusNum); wClusNum = appendBuf(wClusNum, &dire, sizeof(DIR), rootWSize); rootWSize += sizeof(DIR); dire = mkFCB(T_DIR, "..", 0, &dirClusNum); wClusNum = appendBuf(wClusNum, &dire, sizeof(DIR), rootWSize); rootWSize += sizeof(DIR); // 写入其他文件 for(i = 2; i < argc; i++){ fileWSize = 0; assert(index(argv[i], '/') == 0); fileSize = retFileSize(argv[i]); if((fd = open(argv[i], 0)) < 0){ perror(argv[i]); exit(1); } if(argv[i][0] == '_') ++argv[i]; // 写到目录区 strncpy(filename, argv[i], FNSIZE); dire = mkFCB(T_FILE, filename, fileSize, &dirClusNum); wClusNum = appendBuf(wClusNum, &dire, sizeof(DIR), rootWSize); rootWSize += sizeof(DIR); // 写入文件 while((cc = read(fd, buf, sizeof(buf))) > 0) { dirClusNum = appendBuf(dirClusNum, buf, cc, fileWSize); fileWSize += cc; } close(fd); } // 向第1扇区写入FSI initFSI(); memset(buf, 0, sizeof(buf)); memmove(buf, &fsi, sizeof(fsi)); wsect(1, buf); // 向备份FAT中写入相同的内容 for(i = fatFstSec; i < fatFstSec + nFAT; i++) { rsect(i, buf); wsect((i+nFAT), buf); } // // fix size of root inode dir // rinode(rootino, &din); // off = xint(din.size); // off = ((off/BSIZE) + 1) * BSIZE; // din.size = xint(off); // winode(rootino, &din); // balloc(freeblock); exit(0); }
int main(int argc, char *argv[]) { int i, cc, fd; uint rootino, inum, off; struct dirent de; char buf[512]; struct dinode din; if(argc < 2){ fprintf(stderr, "Usage: mkfs fs.img files...\n"); exit(1); } assert((512 % sizeof(struct dinode)) == 0); assert((512 % sizeof(struct dirent)) == 0); fsfd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666); if(fsfd < 0){ perror(argv[1]); exit(1); } sb.size = xint(size); sb.nblocks = xint(nblocks); // so whole disk is size sectors sb.ninodes = xint(ninodes); bitblocks = size/(512*8) + 1; usedblocks = ninodes / IPB + 3 + bitblocks; freeblock = usedblocks; printf("used %d (bit %d ninode %zu) free %u total %d\n", usedblocks, bitblocks, ninodes/IPB + 1, freeblock, nblocks+usedblocks); assert(nblocks + usedblocks == size); for(i = 0; i < nblocks + usedblocks; i++) wsect(i, zeroes); wsect(1, &sb); rootino = ialloc(T_DIR); assert(rootino == ROOTINO); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, "."); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(rootino, &de, sizeof(de)); for(i = 2; i < argc; i++){ assert(index(argv[i], '/') == 0); if((fd = open(argv[i], 0)) < 0){ perror(argv[i]); exit(1); } // Skip leading _ in name when writing to file system. // The binaries are named _rm, _cat, etc. to keep the // build operating system from trying to execute them // in place of system binaries like rm and cat. if(argv[i][0] == '_') ++argv[i]; inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, argv[i], DIRSIZ); iappend(rootino, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) iappend(inum, buf, cc); close(fd); } // fix size of root inode dir rinode(rootino, &din); off = xint(din.size); off = ((off/BSIZE) + 1) * BSIZE; din.size = xint(off); winode(rootino, &din); balloc(usedblocks); exit(0); }
int main(int argc, char *argv[]) { int i; uint rootino, off; struct dirent de; char buf[512]; struct dinode din; static_assert(sizeof(int) == 4, "Integers must be 4 bytes!"); if(argc != 3) { fprintf(stderr, "Usage: mkfs.xv6 <image name> <test|release>\n"); exit(1); } assert((512 % sizeof(struct dinode)) == 0); assert((512 % sizeof(struct dirent)) == 0); fsfd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666); if(fsfd < 0){ perror(argv[1]); exit(1); } sb.size = xint(size); sb.nblocks = xint(nblocks); // so whole disk is size sectors sb.ninodes = xint(ninodes); sb.nlog = xint(nlog); bitblocks = size/(512*8) + 1; usedblocks = ninodes / IPB + 3 + bitblocks; freeblock = usedblocks; if (0) { printf("used %d (bit %d ninode %zu) free %u log %u total %d\n", usedblocks, bitblocks, ninodes/IPB + 1, freeblock, nlog, nblocks+usedblocks+nlog); } assert(nblocks + usedblocks + nlog == size); for(i = 0; i < nblocks + usedblocks + nlog; i++) wsect(i, zeroes); memset(buf, 0, sizeof(buf)); memmove(buf, &sb, sizeof(sb)); wsect(1, buf); rootino = ialloc(T_DIR); assert(rootino == ROOTINO); bzero(&de, sizeof(de)); de.d_ino = xshort(rootino); strcpy(de.d_name, "."); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.d_ino = xshort(rootino); strcpy(de.d_name, ".."); iappend(rootino, &de, sizeof(de)); if (!strcmp(argv[2], "release")) { create_fhs(rootino, "coreutils/init"); } else if (!strcmp(argv[2], "test")) { create_fhs(rootino, "tests/init"); create_tests(rootino); } // fix size of root inode dir rinode(rootino, &din); off = xint(din.size); off = ((off/BSIZE) + 1) * BSIZE; din.size = xint(off); winode(rootino, &din); balloc(usedblocks); exit(0); }