Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2151601
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: LINUX

2016-09-12 16:37:23

1. mkfs.c
1.1 说明
a. linux 0.12使用的是minix的文件系统,现在发行版的ubuntu中没有这个工具
b. 在 里面有mkfs.c下载
c. 但是直接下载后不能直接编译,我作了一点点修改,使mkfs.c可以在Ubuntu 14.04.2 LTS 64位下编译运行
1.2 mkfs.c
  1. /*
  2.  * mkfs.c - make a linux (minix) file-system.
  3.  *
  4.  * (C) 1991 Linus Torvalds. This file may be redistributed as per
  5.  * the Linux copyright.
  6.  */

  7. /*
  8.  * 24.11.91 -    time began. Used the fsck sources to get started.
  9.  *
  10.  * 25.11.91 -    corrected some bugs. Added support for ".badblocks"
  11.  *        The algorithm for ".badblocks" is a bit weird, but
  12.  *        it should work. Oh, well.
  13.  *
  14.  * Usuage: mkfs [-c] device size-in-blocks
  15.  *
  16.  *    -c for readablility checking (
  17.  *
  18.  * The device may be a block device or a image of one, but this isn't
  19.  * enforced (but it's not much fun on a character device :-).
  20.  */

  21. #include <stdio.h>
  22. #include <unistd.h>
  23. #include <string.h>
  24. #include <fcntl.h>
  25. #include <ctype.h>
  26. #include <stdlib.h>
  27. #include <termios.h>
  28. #include <sys/stat.h>

  29. //#include "mkfs.h"
  30. #include "fs.h"

  31. #ifndef __GNUC__
  32. #error "needs gcc for the bitop-__asm__'s"
  33. #endif

  34. #ifndef __linux__
  35. #define volatile
  36. #endif

  37. #define ROOT_INO 1
  38. #define BAD_INO 2

  39. #define TEST_BUFFER_BLOCKS 32
  40. #define MAX_GOOD_BLOCKS 512

  41. #define UPPER(size,n) ((size+((n)-1))/(n))
  42. #define INODE_SIZE (sizeof(struct d_inode))
  43. #define INODE_BLOCKS UPPER(INODES,INODES_PER_BLOCK)
  44. #define INODE_BUFFER_SIZE (INODE_BLOCKS * BLOCK_SIZE)

  45. #define BITS_PER_BLOCK (BLOCK_SIZE<<3)

  46. static char * program_name = "mkfs";
  47. static char * device_name = NULL;
  48. static int DEV = -1;
  49. static long BLOCKS = 0;
  50. static int check = 0;
  51. static int badblocks = 0;

  52. #define ROOT_INO_STRING "\001\000"
  53. #define BAD_INO_STRING "\002\000"

  54. static char root_block[BLOCK_SIZE] =
  55. ROOT_INO_STRING ".\0\0\0\0\0\0\0\0\0\0\0\0\0"
  56. ROOT_INO_STRING "..\0\0\0\0\0\0\0\0\0\0\0\0"
  57. BAD_INO_STRING ".badblocks\0\0\0\0";

  58. static char * inode_buffer = NULL;
  59. #define Inode (((struct d_inode *) inode_buffer)-1)
  60. static char super_block_buffer[BLOCK_SIZE];
  61. #define Super (*(struct super_block *)super_block_buffer)
  62. #define INODES ((unsigned long)Super.s_ninodes)
  63. #define ZONES ((unsigned long)Super.s_nzones)
  64. #define IMAPS ((unsigned long)Super.s_imap_blocks)
  65. #define ZMAPS ((unsigned long)Super.s_zmap_blocks)
  66. #define FIRSTZONE ((unsigned long)Super.s_firstdatazone)
  67. #define ZONESIZE ((unsigned long)Super.s_log_zone_size)
  68. #define MAXSIZE ((unsigned long)Super.s_max_size)
  69. #define MAGIC (Super.s_magic)
  70. #define NORM_FIRSTZONE (2+IMAPS+ZMAPS+INODE_BLOCKS)

  71. static char inode_map[BLOCK_SIZE * I_MAP_SLOTS];
  72. static char zone_map[BLOCK_SIZE * Z_MAP_SLOTS];

  73. static unsigned short good_blocks_table[MAX_GOOD_BLOCKS];
  74. static int used_good_blocks = 0;

  75. #define bitop(name,op) \
  76.     static inline int name(char * addr,unsigned int nr) \
  77. { \
  78.     int __res; \
  79.     __asm__ __volatile__("bt" op " %1,%2; adcl $0,%0" \
  80.             :"=g" (__res) \
  81.             :"r" (nr),"m" (*(addr)),"0" (0)); \
  82.     return __res; \
  83. }

  84. bitop(bit,"")
  85. bitop(setbit,"s")
  86. bitop(clrbit,"r")

  87. #define inode_in_use(x) (bit(inode_map,(x)))
  88. #define zone_in_use(x) (bit(zone_map,(x)-FIRSTZONE+1))

  89. #define mark_inode(x) (setbit(inode_map,(x)))
  90. #define unmark_inode(x) (clrbit(inode_map,(x)))

  91. #define mark_zone(x) (setbit(zone_map,(x)-FIRSTZONE+1))
  92. #define unmark_zone(x) (clrbit(zone_map,(x)-FIRSTZONE+1))

  93. /*
  94.  * Volatile to let gcc know that this doesn't return. When trying
  95.  * to compile this under minix, volatile gives a warning, as
  96.  * exit() isn't defined as volatile under minix.
  97.  */
  98. void fatal_error(const char * fmt_string)
  99. {
  100.     fprintf(stderr,fmt_string,__func__, __LINE__, program_name,device_name);
  101.     exit(1);
  102. }

  103. #define usage() fatal_error("Usage: %s:[%d]%s [-c] %s blocks\n")
  104. #define die(str) fatal_error("%s: " str "\n")

  105. void write_tables(void)
  106. {
  107.     if (BLOCK_SIZE != lseek(DEV, BLOCK_SIZE, SEEK_SET))
  108.         die("seek failed in write_tables");
  109.     if (BLOCK_SIZE != write(DEV, super_block_buffer, BLOCK_SIZE))
  110.         die("unable to write super-block");
  111.     if (IMAPS*BLOCK_SIZE != write(DEV,inode_map,IMAPS*BLOCK_SIZE))
  112.         die("Unable to write inode map");
  113.     if (ZMAPS*BLOCK_SIZE != write(DEV,zone_map,ZMAPS*BLOCK_SIZE))
  114.         die("Unable to write zone map");
  115.     if (INODE_BUFFER_SIZE != write(DEV,inode_buffer,INODE_BUFFER_SIZE))
  116.         die("Unable to write inodes");
  117. }

  118. void write_block(int blk, char * buffer)
  119. {
  120.     if (blk*BLOCK_SIZE != lseek(DEV, blk*BLOCK_SIZE, SEEK_SET))
  121.         die("seek failed in write_block");
  122.     if (BLOCK_SIZE != write(DEV, buffer, BLOCK_SIZE))
  123.         die("write failed in write_block");
  124. }

  125. int get_free_block(void)
  126. {
  127.     int blk;

  128.     if (used_good_blocks+1 >= MAX_GOOD_BLOCKS)
  129.         die("too many bad blocks");
  130.     if (used_good_blocks)
  131.         blk = good_blocks_table[used_good_blocks-1]+1;
  132.     else
  133.         blk = FIRSTZONE;
  134.     while (blk < ZONES && zone_in_use(blk))
  135.         blk++;
  136.     if (blk >= ZONES)
  137.         die("not enough good blocks");
  138.     good_blocks_table[used_good_blocks] = blk;
  139.     used_good_blocks++;
  140.     return blk;
  141. }

  142. void mark_good_blocks(void)
  143. {
  144.     int blk;

  145.     for (blk=0 ; blk < used_good_blocks ; blk++)
  146.         mark_zone(good_blocks_table[blk]);
  147. }

  148. inline int next(int zone)
  149. {
  150.     if (!zone)
  151.         zone = FIRSTZONE-1;
  152.     while (++zone < ZONES)
  153.         if (zone_in_use(zone))
  154.             return zone;
  155.     return 0;
  156. }

  157. void make_bad_inode(void)
  158. {
  159.     struct d_inode * inode = &Inode[BAD_INO];
  160.     int i,j,zone;
  161.     int ind=0,dind=0;
  162.     unsigned short ind_block[BLOCK_SIZE>>1];
  163.     unsigned short dind_block[BLOCK_SIZE>>1];

  164. #define NEXT_BAD (zone = next(zone))

  165.     if (!badblocks)
  166.         return;
  167.     mark_inode(BAD_INO);
  168.     inode->i_nlinks = 1;
  169.     inode->i_time = time(NULL);
  170.     inode->i_mode = S_IFREG + 0000;
  171.     inode->i_size = badblocks*BLOCK_SIZE;
  172.     zone = next(0);
  173.     for (i=0 ; i<7 ; i++) {
  174.         inode->i_zone[i] = zone;
  175.         if (!NEXT_BAD)
  176.             goto end_bad;
  177.     }
  178.     inode->i_zone[7] = ind = get_free_block();
  179.     memset(ind_block,0,BLOCK_SIZE);
  180.     for (i=0 ; i<512 ; i++) {
  181.         ind_block[i] = zone;
  182.         if (!NEXT_BAD)
  183.             goto end_bad;
  184.     }
  185.     inode->i_zone[8] = dind = get_free_block();
  186.     memset(dind_block,0,BLOCK_SIZE);
  187.     for (i=0 ; i<512 ; i++) {
  188.         write_block(ind,(char *) ind_block);
  189.         dind_block[i] = ind = get_free_block();
  190.         memset(ind_block,0,BLOCK_SIZE);
  191.         for (j=0 ; j<512 ; j++) {
  192.             ind_block[j] = zone;
  193.             if (!NEXT_BAD)
  194.                 goto end_bad;
  195.         }
  196.     }
  197.     die("too many bad blocks");
  198. end_bad:
  199.     if (ind)
  200.         write_block(ind, (char *) ind_block);
  201.     if (dind)
  202.         write_block(dind, (char *) dind_block);
  203. }

  204. void make_root_inode(void)
  205. {
  206.     struct d_inode * inode = &Inode[ROOT_INO];

  207.     mark_inode(ROOT_INO);
  208.     inode->i_zone[0] = get_free_block();
  209.     inode->i_nlinks = 2;
  210.     inode->i_time = time(NULL);
  211.     if (badblocks)
  212.         inode->i_size = 48;
  213.     else
  214.         inode->i_size = 32;
  215.     inode->i_mode = S_IFDIR + 0755;
  216.     write_block(inode->i_zone[0],root_block);
  217. }

  218. void setup_tables(void)
  219. {
  220.     int i;
  221.     struct super_block * p;
  222.     p = (struct super_block*)super_block_buffer;
  223.     memset(inode_map,0xff,sizeof(inode_map));
  224.     memset(zone_map,0xff,sizeof(zone_map));
  225.     memset(super_block_buffer,0,BLOCK_SIZE);
  226.     MAGIC = SUPER_MAGIC;
  227.     p->s_log_zone_size = 0;
  228.     p->s_max_size = (7+512+512*512)*1024;
  229.     p->s_nzones = BLOCKS;
  230.     /* some magic nrs: 1 inode / 3 blocks */
  231.     p->s_ninodes = BLOCKS/3;
  232.     /* I don't want some off-by-one errors, so this hack... */
  233.     if ((p->s_ninodes & 8191) > 8188)
  234.         p->s_ninodes -= 5;
  235.     if ((p->s_ninodes & 8191) < 10)
  236.         p->s_ninodes -= 20;
  237.     if ((p->s_ninodes & 8191) > 8188)
  238.         p->s_ninodes = 5;
  239.     if ((p->s_ninodes & 8191) < 10)
  240.         p->s_ninodes -= 20;

  241.     p->s_imap_blocks = UPPER(p->s_ninodes, BITS_PER_BLOCK);
  242.     p->s_zmap_blocks = 0;
  243.     while (p->s_zmap_blocks != UPPER(BLOCKS - NORM_FIRSTZONE,BITS_PER_BLOCK))
  244.         p->s_zmap_blocks = UPPER(BLOCKS - NORM_FIRSTZONE, BITS_PER_BLOCK);
  245.     p->s_firstdatazone = NORM_FIRSTZONE;
  246.     for (i = p->s_firstdatazone; i<p->s_nzones; i++)
  247.         unmark_zone(i);
  248.     for (i = ROOT_INO ; i<p->s_ninodes; i++)
  249.         unmark_inode(i);
  250.     inode_buffer = malloc(INODE_BUFFER_SIZE);
  251.     if (!inode_buffer)
  252.         die("Unable to allocate buffer for inodes");
  253.     memset(inode_buffer,0,INODE_BUFFER_SIZE);
  254.     printf("%d inodes\n",p->s_ninodes);
  255.     printf("%d blocks\n", p->s_nzones);
  256.     printf("Firstdatazone=%d (%d)\n",p->s_firstdatazone,NORM_FIRSTZONE);
  257.     printf("Zonesize=%d\n",BLOCK_SIZE<<p->s_log_zone_size);
  258.     printf("Maxsize=%d\n\n", p->s_max_size);
  259. }

  260. void check_blocks(void)
  261. {
  262.     unsigned int current_block=0;
  263.     int try,got;
  264.     static char buffer[BLOCK_SIZE * TEST_BUFFER_BLOCKS];

  265.     while (current_block < ZONES) {
  266.         if (lseek(DEV,current_block*BLOCK_SIZE,SEEK_SET) !=
  267.                 current_block*BLOCK_SIZE)
  268.             die("seek failed in check_blocks");
  269.         try = TEST_BUFFER_BLOCKS;
  270.         if (current_block + try > ZONES)
  271.             try = ZONES-current_block;
  272.         got = read(DEV, buffer, try * BLOCK_SIZE);
  273.         if (got<0)
  274.             got = 0;
  275.         if (got & (BLOCK_SIZE-1))
  276.             printf("Weird values in check_blocks: probably bugs\n");
  277.         got /= BLOCK_SIZE;
  278.         current_block += got;
  279.         if (got == try)
  280.             continue;
  281.         if (current_block < FIRSTZONE)
  282.             die("bad blocks before data-area: cannot make fs");
  283.         mark_zone(current_block);
  284.         badblocks++;
  285.         current_block++;
  286.     }
  287.     if (badblocks)
  288.         printf("%d bad block%s\n",badblocks,(badblocks>1)?"s":"");
  289. }

  290. int main(int argc, char ** argv)
  291. {
  292.     char * tmp;
  293.     struct stat statbuf;

  294.     if (argc && *argv)
  295.         program_name = *argv;
  296.     //printf("INODE_SIZE=%d, INODES_PER_BLOCK=%d, BLOCK_SIZE=%d\n", INODE_SIZE, INODES_PER_BLOCK, BLOCK_SIZE);
  297.     if (INODE_SIZE * INODES_PER_BLOCK != BLOCK_SIZE)
  298.         die("bad inode size");
  299.     while (argc-- > 1) {
  300.         argv++;
  301.         if (argv[0][0] != '-')
  302.             if (device_name) {
  303.                 BLOCKS = strtol(argv[0],&tmp,0);
  304.                 if (*tmp)
  305.                 {
  306.                     printf("argv=%s, tmp!=0\n", argv[0]);
  307.                     return 0;
  308.                 }
  309.             } else
  310.                 device_name = argv[0];
  311.             else while (*++argv[0])
  312.                 switch (argv[0][0]) {
  313.                     case 'c': check=1; break;
  314.                     default: usage();
  315.                 }
  316.     }
  317.     printf("device_name=%s\n", device_name);
  318.     if (!device_name || BLOCKS<10 || BLOCKS > 65536)
  319.     {
  320.         printf("!device_name || BLOCKS<10 || BLOCKS > 65536\n");
  321.         return 0;
  322.     }
  323.     DEV = open(device_name,O_RDWR);
  324.     if (DEV<0)
  325.         die("unable to open %s");
  326.     if (fstat(DEV,&statbuf)<0)
  327.         die("unable to stat %s");
  328.     if (!S_ISBLK(statbuf.st_mode))
  329.         check=0;
  330.     else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0305)
  331.         die("Will not try to make filesystem on '%s'");
  332.     setup_tables();
  333.     if (check)
  334.         check_blocks();
  335.     make_root_inode();
  336.     make_bad_inode();
  337.     mark_good_blocks();
  338.     write_tables();
  339.     return 0;
  340. }
1.3 mkfs.c编译的Makefile
  1. cong@msi:/work/os/linux12/tools/mkfs$ cat Makefile
  2. mkfs:mkfs.c
  3.     gcc -m32 -g -o $@ $^
  4. clean:
  5.     -rm -rf *.o mkfs
2. 创建系统的脚本如下
有了mkfs之后就可以正常的构建linux0.12的文件系统了,脚本如下:
  1. #!/bin/sh
  2. create_fs()
  3. {
  4.     #create filesystem
  5.     cd /tmp/minix

  6.     #先创建系统目录
  7.     sudo mkdir -pv etc dev bin usr usr/bin var
  8.     sudo mknod ./dev/tty1 c 4 1                      -->需要打开tty1
  9.     sudo cp /work/os/linux12/tools/sh/init ./bin/    -->这儿随意写了个init
  10. }


  11. #fdisk hdc.img to minix 80
  12. make_fs()
  13. {
  14.     #sector的数目=524288=256M/512=256*1024*1024/512
  15.     dd if=/dev/zero of=./hdc.img bs=512 count=524288
  16.     fdisk ./hdc.img <<EOF       --->对hdc.img进行分区,只分一个主分区,并设置分区为80(old minix)    
  17.     n
  18.     p
  19.     1
  20.     2048                        -->分区开始
  21.     524159                      -->分区结束 
  22.     t                           -->t   change a partition's system id
  23.     80
  24.     w
  25. EOF                              --->注意这个EOF必须顶格写,要不会出错
  26.     sleep 1
  27.     fdisk -l ./hdc.img
  28.     losetup /dev/loop0 ./hdc.img               -->将整个的hdc.img镜像关联到/dev/loop0上去
  29.     #512*2048=1048576                          -->分区是从2048个sector开始的
  30.     losetup -o 1048576 /dev/loop1 /dev/loop0   -->所以这儿 -o 加上偏移
  31.     losetup -a                                 --> list all used losetup
  32.     ./mkfs -c /dev/loop1 65535                 -->对分区1格式化为 old minix分区
  33.     mkdir /tmp/minix                           
  34.     sudo mount -t minix /dev/loop1 /tmp/minix/  -->格式化后就可以挂载
  35.     create_fs
  36. }
  37. umount_fs()
  38. {
  39.     sudo umount /tmp/minix
  40.     losetup -d /dev/loop0
  41.     losetup -d /dev/loop1
  42.     losetup -a
  43. }

  44. clean_fs()
  45. {
  46.     sudo umount /tmp/minix
  47.     losetup -d /dev/loop0
  48.     losetup -d /dev/loop1
  49.     rm -rf ./hdc.img
  50. }

  51. case "$1" in
  52.     fs)
  53.         make_fs
  54.         ;;
  55.     clean)
  56.         clean_fs
  57.         ;;
  58.     umount)
  59.         umount_fs
  60.         ;;
  61.     *)
  62.         make_fs
  63.         ;;
  64. esac

3.代码打包
  1. cong@msi:/work/os/linux12/tools/mkfs$ tree
  2. .
  3. ├── fs.h
  4. ├── Makefile
  5. ├── mkfs
  6. ├── mkfs.c
  7. ├── mkfs.c_bak
  8. └── mkfs_notation.c
mkfs.rar(下载后改名为mkfs.tar.gz)
4.运行结果

说明在建文件系统时init进程不正确导致,但至少文件系统是成功了。
5. 对于己建好的例如: rootimage-0.12-hd如何访问里面的内容呢?
  1. cong@msi:/work/os/linux12$ fdisk -l ./rootimage-0.12-hd                 -->查看分区

  2. Disk ./rootimage-0.12-hd: 251 MB, 251338752 bytes
  3. 16 heads, 63 sectors/track, 487 cylinders, total 490896 sectors
  4. Units = sectors of 1 * 512 = 512 bytes
  5. Sector size (logical/physical): 512 bytes / 512 bytes
  6. I/O size (minimum/optimal): 512 bytes / 512 bytes
  7. Disk identifier: 0x00000000

  8.               Device Boot Start End Blocks Id System
  9. ./rootimage-0.12-hd1 * 1 132047 66023+ 81 Minix / old Linux             -->第1个分区是在偏移1*512处
  10. ./rootimage-0.12-hd2 132048 264095 66024 81 Minix / old Linux
  11. ./rootimage-0.12-hd3 264096 396143 66024 81 Minix / old Linux
  12. ./rootimage-0.12-hd4 396144 478799 41328 82 Linux swap / Solaris


  13. cong@msi:/work/os/linux12$ losetup /dev/loop0 ./rootimage-0.12-hd       -->losetup整个镜像
  14. cong@msi:/work/os/linux12$ losetup -a                                   
  15. /dev/loop0: [0808]:49164984 (/work/os/linux12/rootimage-0.12-hd)

  16. cong@msi:/work/os/linux12$ losetup -o 512 /dev/loop1 /dev/loop0         -->losetup分区1

  17. cong@msi:/work/os/linux12$ losetup -a                                   -->查看losetup
  18. /dev/loop0: [0808]:49164984 (/work/os/linux12/rootimage-0.12-hd)
  19. /dev/loop1: [0005]:1164 (/dev/loop0), offset 512

  20. cong@msi:/work/os/linux12$ sudo mount -t minix /dev/loop0 /tmp/linux011/  -->挂载分区1

  21. cong@msi:/work/os/linux12$ ls /tmp/linux011/
  22. bin dev etc hdd home image MCC-0.12 mnt mnt1 README root tmp usr vmlinux
  23. cong@msi:/work/os/linux12$ ls /tmp/linux011/bin/
  24. agetty chage clock echo fdisk groupadd init logoutd mkswap newusers pwunconv sleep true userdel zic
  25. awk chfn crond env fsck groupdel kdb mkfs mount passwd rm su umount usermod
  26. bash chpasswd date faillog gawk groupmod lex.yy.c mknod mv ps sh sulogin update vi
  27. bash.old chsh dpasswd false gpasswd id login mkpasswd newgrp pwconv sh.old sync useradd zdump
  28. cong@msi:/work/os/linux12$ sudo file /tmp/linux011/bin/bash
  29. /tmp/linux011/bin/bash: a.out little-endian 32-bit demand paged pure executable  -->说明正确
根据上面的步骤就可以把己移植好的程序放到自己的hdc.img里面去了。
阅读(1454) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~