⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mkfs.c

📁 类unix x86平台的简单操作系统
💻 C
字号:
#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#include <assert.h>#include "types.h"#include "param.h"#include "fs.h"int nblocks = 1008;int ninodes = 100;int size = 1024;int fsfd;struct superblock sb;char zeroes[512];uint freeblock;uint usedblocks;uint bitblocks;uint freeinode = 1;void balloc(int);void wsect(uint, void*);void winode(uint, struct dinode*);void rinode(uint inum, struct dinode *ip);void rsect(uint sec, void *buf);uint ialloc(ushort type);void iappend(uint inum, void *p, int n);// convert to intel byte orderushortxshort(ushort x){  ushort y;  uchar *a = (uchar*) &y;  a[0] = x;  a[1] = x >> 8;  return y;}uintxint(uint x){  uint y;  uchar *a = (uchar*) &y;  a[0] = x;  a[1] = x >> 8;  a[2] = x >> 16;  a[3] = x >> 24;  return y;}intmain(int argc, char *argv[]){  int i, cc, fd;  uint bn, 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 %d) free %d 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 == 1);  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);}voidwsect(uint sec, void *buf){  if(lseek(fsfd, sec * 512L, 0) != sec * 512L){    perror("lseek");    exit(1);  }  if(write(fsfd, buf, 512) != 512){    perror("write");    exit(1);  }}uinti2b(uint inum){  return (inum / IPB) + 2;}voidwinode(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);}voidrinode(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);  *ip = *dip;}voidrsect(uint sec, void *buf){  if(lseek(fsfd, sec * 512L, 0) != sec * 512L){    perror("lseek");    exit(1);  }  if(read(fsfd, buf, 512) != 512){    perror("read");    exit(1);  }}uintialloc(ushort type){  uint inum = freeinode++;  struct dinode din;  bzero(&din, sizeof(din));  din.type = xshort(type);  din.nlink = xshort(1);  din.size = xint(0);  winode(inum, &din);  return inum;}voidballoc(int used){  uchar buf[512];  int i;  printf("balloc: first %d blocks have been allocated\n", used);  assert(used < 512);  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 %d\n", ninodes/IPB + 3);  wsect(ninodes / IPB + 3, buf);}#define min(a, b) ((a) < (b) ? (a) : (b))voidiappend(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[INDIRECT]) == 0) {        // printf("allocate indirect block\n");        din.addrs[INDIRECT] = xint(freeblock++);        usedblocks++;      }      // printf("read indirect block\n");      rsect(xint(din.addrs[INDIRECT]), (char*) indirect);      if(indirect[fbn - NDIRECT] == 0) {        indirect[fbn - NDIRECT] = xint(freeblock++);        usedblocks++;        wsect(xint(din.addrs[INDIRECT]), (char*) indirect);      }      x = xint(indirect[fbn-NDIRECT]);    }    n1 = min(n, (fbn + 1) * 512 - off);    rsect(x, buf);    bcopy(p, buf + off - (fbn * 512), n1);    wsect(x, buf);    n -= n1;    off += n1;    p += n1;  }  din.size = xint(off);  winode(inum, &din);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -