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
-
/*
-
* mkfs.c - make a linux (minix) file-system.
-
*
-
* (C) 1991 Linus Torvalds. This file may be redistributed as per
-
* the Linux copyright.
-
*/
-
-
/*
-
* 24.11.91 - time began. Used the fsck sources to get started.
-
*
-
* 25.11.91 - corrected some bugs. Added support for ".badblocks"
-
* The algorithm for ".badblocks" is a bit weird, but
-
* it should work. Oh, well.
-
*
-
* Usuage: mkfs [-c] device size-in-blocks
-
*
-
* -c for readablility checking (
-
*
-
* The device may be a block device or a image of one, but this isn't
-
* enforced (but it's not much fun on a character device :-).
-
*/
-
-
#include <stdio.h>
-
#include <unistd.h>
-
#include <string.h>
-
#include <fcntl.h>
-
#include <ctype.h>
-
#include <stdlib.h>
-
#include <termios.h>
-
#include <sys/stat.h>
-
-
//#include "mkfs.h"
-
#include "fs.h"
-
-
#ifndef __GNUC__
-
#error "needs gcc for the bitop-__asm__'s"
-
#endif
-
-
#ifndef __linux__
-
#define volatile
-
#endif
-
-
#define ROOT_INO 1
-
#define BAD_INO 2
-
-
#define TEST_BUFFER_BLOCKS 32
-
#define MAX_GOOD_BLOCKS 512
-
-
#define UPPER(size,n) ((size+((n)-1))/(n))
-
#define INODE_SIZE (sizeof(struct d_inode))
-
#define INODE_BLOCKS UPPER(INODES,INODES_PER_BLOCK)
-
#define INODE_BUFFER_SIZE (INODE_BLOCKS * BLOCK_SIZE)
-
-
#define BITS_PER_BLOCK (BLOCK_SIZE<<3)
-
-
static char * program_name = "mkfs";
-
static char * device_name = NULL;
-
static int DEV = -1;
-
static long BLOCKS = 0;
-
static int check = 0;
-
static int badblocks = 0;
-
-
#define ROOT_INO_STRING "\001\000"
-
#define BAD_INO_STRING "\002\000"
-
-
static char root_block[BLOCK_SIZE] =
-
ROOT_INO_STRING ".\0\0\0\0\0\0\0\0\0\0\0\0\0"
-
ROOT_INO_STRING "..\0\0\0\0\0\0\0\0\0\0\0\0"
-
BAD_INO_STRING ".badblocks\0\0\0\0";
-
-
static char * inode_buffer = NULL;
-
#define Inode (((struct d_inode *) inode_buffer)-1)
-
static char super_block_buffer[BLOCK_SIZE];
-
#define Super (*(struct super_block *)super_block_buffer)
-
#define INODES ((unsigned long)Super.s_ninodes)
-
#define ZONES ((unsigned long)Super.s_nzones)
-
#define IMAPS ((unsigned long)Super.s_imap_blocks)
-
#define ZMAPS ((unsigned long)Super.s_zmap_blocks)
-
#define FIRSTZONE ((unsigned long)Super.s_firstdatazone)
-
#define ZONESIZE ((unsigned long)Super.s_log_zone_size)
-
#define MAXSIZE ((unsigned long)Super.s_max_size)
-
#define MAGIC (Super.s_magic)
-
#define NORM_FIRSTZONE (2+IMAPS+ZMAPS+INODE_BLOCKS)
-
-
static char inode_map[BLOCK_SIZE * I_MAP_SLOTS];
-
static char zone_map[BLOCK_SIZE * Z_MAP_SLOTS];
-
-
static unsigned short good_blocks_table[MAX_GOOD_BLOCKS];
-
static int used_good_blocks = 0;
-
-
#define bitop(name,op) \
-
static inline int name(char * addr,unsigned int nr) \
-
{ \
-
int __res; \
-
__asm__ __volatile__("bt" op " %1,%2; adcl $0,%0" \
-
:"=g" (__res) \
-
:"r" (nr),"m" (*(addr)),"0" (0)); \
-
return __res; \
-
}
-
-
bitop(bit,"")
-
bitop(setbit,"s")
-
bitop(clrbit,"r")
-
-
#define inode_in_use(x) (bit(inode_map,(x)))
-
#define zone_in_use(x) (bit(zone_map,(x)-FIRSTZONE+1))
-
-
#define mark_inode(x) (setbit(inode_map,(x)))
-
#define unmark_inode(x) (clrbit(inode_map,(x)))
-
-
#define mark_zone(x) (setbit(zone_map,(x)-FIRSTZONE+1))
-
#define unmark_zone(x) (clrbit(zone_map,(x)-FIRSTZONE+1))
-
-
/*
-
* Volatile to let gcc know that this doesn't return. When trying
-
* to compile this under minix, volatile gives a warning, as
-
* exit() isn't defined as volatile under minix.
-
*/
-
void fatal_error(const char * fmt_string)
-
{
-
fprintf(stderr,fmt_string,__func__, __LINE__, program_name,device_name);
-
exit(1);
-
}
-
-
#define usage() fatal_error("Usage: %s:[%d]%s [-c] %s blocks\n")
-
#define die(str) fatal_error("%s: " str "\n")
-
-
void write_tables(void)
-
{
-
if (BLOCK_SIZE != lseek(DEV, BLOCK_SIZE, SEEK_SET))
-
die("seek failed in write_tables");
-
if (BLOCK_SIZE != write(DEV, super_block_buffer, BLOCK_SIZE))
-
die("unable to write super-block");
-
if (IMAPS*BLOCK_SIZE != write(DEV,inode_map,IMAPS*BLOCK_SIZE))
-
die("Unable to write inode map");
-
if (ZMAPS*BLOCK_SIZE != write(DEV,zone_map,ZMAPS*BLOCK_SIZE))
-
die("Unable to write zone map");
-
if (INODE_BUFFER_SIZE != write(DEV,inode_buffer,INODE_BUFFER_SIZE))
-
die("Unable to write inodes");
-
}
-
-
void write_block(int blk, char * buffer)
-
{
-
if (blk*BLOCK_SIZE != lseek(DEV, blk*BLOCK_SIZE, SEEK_SET))
-
die("seek failed in write_block");
-
if (BLOCK_SIZE != write(DEV, buffer, BLOCK_SIZE))
-
die("write failed in write_block");
-
}
-
-
int get_free_block(void)
-
{
-
int blk;
-
-
if (used_good_blocks+1 >= MAX_GOOD_BLOCKS)
-
die("too many bad blocks");
-
if (used_good_blocks)
-
blk = good_blocks_table[used_good_blocks-1]+1;
-
else
-
blk = FIRSTZONE;
-
while (blk < ZONES && zone_in_use(blk))
-
blk++;
-
if (blk >= ZONES)
-
die("not enough good blocks");
-
good_blocks_table[used_good_blocks] = blk;
-
used_good_blocks++;
-
return blk;
-
}
-
-
void mark_good_blocks(void)
-
{
-
int blk;
-
-
for (blk=0 ; blk < used_good_blocks ; blk++)
-
mark_zone(good_blocks_table[blk]);
-
}
-
-
inline int next(int zone)
-
{
-
if (!zone)
-
zone = FIRSTZONE-1;
-
while (++zone < ZONES)
-
if (zone_in_use(zone))
-
return zone;
-
return 0;
-
}
-
-
void make_bad_inode(void)
-
{
-
struct d_inode * inode = &Inode[BAD_INO];
-
int i,j,zone;
-
int ind=0,dind=0;
-
unsigned short ind_block[BLOCK_SIZE>>1];
-
unsigned short dind_block[BLOCK_SIZE>>1];
-
-
#define NEXT_BAD (zone = next(zone))
-
-
if (!badblocks)
-
return;
-
mark_inode(BAD_INO);
-
inode->i_nlinks = 1;
-
inode->i_time = time(NULL);
-
inode->i_mode = S_IFREG + 0000;
-
inode->i_size = badblocks*BLOCK_SIZE;
-
zone = next(0);
-
for (i=0 ; i<7 ; i++) {
-
inode->i_zone[i] = zone;
-
if (!NEXT_BAD)
-
goto end_bad;
-
}
-
inode->i_zone[7] = ind = get_free_block();
-
memset(ind_block,0,BLOCK_SIZE);
-
for (i=0 ; i<512 ; i++) {
-
ind_block[i] = zone;
-
if (!NEXT_BAD)
-
goto end_bad;
-
}
-
inode->i_zone[8] = dind = get_free_block();
-
memset(dind_block,0,BLOCK_SIZE);
-
for (i=0 ; i<512 ; i++) {
-
write_block(ind,(char *) ind_block);
-
dind_block[i] = ind = get_free_block();
-
memset(ind_block,0,BLOCK_SIZE);
-
for (j=0 ; j<512 ; j++) {
-
ind_block[j] = zone;
-
if (!NEXT_BAD)
-
goto end_bad;
-
}
-
}
-
die("too many bad blocks");
-
end_bad:
-
if (ind)
-
write_block(ind, (char *) ind_block);
-
if (dind)
-
write_block(dind, (char *) dind_block);
-
}
-
-
void make_root_inode(void)
-
{
-
struct d_inode * inode = &Inode[ROOT_INO];
-
-
mark_inode(ROOT_INO);
-
inode->i_zone[0] = get_free_block();
-
inode->i_nlinks = 2;
-
inode->i_time = time(NULL);
-
if (badblocks)
-
inode->i_size = 48;
-
else
-
inode->i_size = 32;
-
inode->i_mode = S_IFDIR + 0755;
-
write_block(inode->i_zone[0],root_block);
-
}
-
-
void setup_tables(void)
-
{
-
int i;
-
struct super_block * p;
-
p = (struct super_block*)super_block_buffer;
-
memset(inode_map,0xff,sizeof(inode_map));
-
memset(zone_map,0xff,sizeof(zone_map));
-
memset(super_block_buffer,0,BLOCK_SIZE);
-
MAGIC = SUPER_MAGIC;
-
p->s_log_zone_size = 0;
-
p->s_max_size = (7+512+512*512)*1024;
-
p->s_nzones = BLOCKS;
-
/* some magic nrs: 1 inode / 3 blocks */
-
p->s_ninodes = BLOCKS/3;
-
/* I don't want some off-by-one errors, so this hack... */
-
if ((p->s_ninodes & 8191) > 8188)
-
p->s_ninodes -= 5;
-
if ((p->s_ninodes & 8191) < 10)
-
p->s_ninodes -= 20;
-
if ((p->s_ninodes & 8191) > 8188)
-
p->s_ninodes = 5;
-
if ((p->s_ninodes & 8191) < 10)
-
p->s_ninodes -= 20;
-
-
p->s_imap_blocks = UPPER(p->s_ninodes, BITS_PER_BLOCK);
-
p->s_zmap_blocks = 0;
-
while (p->s_zmap_blocks != UPPER(BLOCKS - NORM_FIRSTZONE,BITS_PER_BLOCK))
-
p->s_zmap_blocks = UPPER(BLOCKS - NORM_FIRSTZONE, BITS_PER_BLOCK);
-
p->s_firstdatazone = NORM_FIRSTZONE;
-
for (i = p->s_firstdatazone; i<p->s_nzones; i++)
-
unmark_zone(i);
-
for (i = ROOT_INO ; i<p->s_ninodes; i++)
-
unmark_inode(i);
-
inode_buffer = malloc(INODE_BUFFER_SIZE);
-
if (!inode_buffer)
-
die("Unable to allocate buffer for inodes");
-
memset(inode_buffer,0,INODE_BUFFER_SIZE);
-
printf("%d inodes\n",p->s_ninodes);
-
printf("%d blocks\n", p->s_nzones);
-
printf("Firstdatazone=%d (%d)\n",p->s_firstdatazone,NORM_FIRSTZONE);
-
printf("Zonesize=%d\n",BLOCK_SIZE<<p->s_log_zone_size);
-
printf("Maxsize=%d\n\n", p->s_max_size);
-
}
-
-
void check_blocks(void)
-
{
-
unsigned int current_block=0;
-
int try,got;
-
static char buffer[BLOCK_SIZE * TEST_BUFFER_BLOCKS];
-
-
while (current_block < ZONES) {
-
if (lseek(DEV,current_block*BLOCK_SIZE,SEEK_SET) !=
-
current_block*BLOCK_SIZE)
-
die("seek failed in check_blocks");
-
try = TEST_BUFFER_BLOCKS;
-
if (current_block + try > ZONES)
-
try = ZONES-current_block;
-
got = read(DEV, buffer, try * BLOCK_SIZE);
-
if (got<0)
-
got = 0;
-
if (got & (BLOCK_SIZE-1))
-
printf("Weird values in check_blocks: probably bugs\n");
-
got /= BLOCK_SIZE;
-
current_block += got;
-
if (got == try)
-
continue;
-
if (current_block < FIRSTZONE)
-
die("bad blocks before data-area: cannot make fs");
-
mark_zone(current_block);
-
badblocks++;
-
current_block++;
-
}
-
if (badblocks)
-
printf("%d bad block%s\n",badblocks,(badblocks>1)?"s":"");
-
}
-
-
int main(int argc, char ** argv)
-
{
-
char * tmp;
-
struct stat statbuf;
-
-
if (argc && *argv)
-
program_name = *argv;
-
//printf("INODE_SIZE=%d, INODES_PER_BLOCK=%d, BLOCK_SIZE=%d\n", INODE_SIZE, INODES_PER_BLOCK, BLOCK_SIZE);
-
if (INODE_SIZE * INODES_PER_BLOCK != BLOCK_SIZE)
-
die("bad inode size");
-
while (argc-- > 1) {
-
argv++;
-
if (argv[0][0] != '-')
-
if (device_name) {
-
BLOCKS = strtol(argv[0],&tmp,0);
-
if (*tmp)
-
{
-
printf("argv=%s, tmp!=0\n", argv[0]);
-
return 0;
-
}
-
} else
-
device_name = argv[0];
-
else while (*++argv[0])
-
switch (argv[0][0]) {
-
case 'c': check=1; break;
-
default: usage();
-
}
-
}
-
printf("device_name=%s\n", device_name);
-
if (!device_name || BLOCKS<10 || BLOCKS > 65536)
-
{
-
printf("!device_name || BLOCKS<10 || BLOCKS > 65536\n");
-
return 0;
-
}
-
DEV = open(device_name,O_RDWR);
-
if (DEV<0)
-
die("unable to open %s");
-
if (fstat(DEV,&statbuf)<0)
-
die("unable to stat %s");
-
if (!S_ISBLK(statbuf.st_mode))
-
check=0;
-
else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0305)
-
die("Will not try to make filesystem on '%s'");
-
setup_tables();
-
if (check)
-
check_blocks();
-
make_root_inode();
-
make_bad_inode();
-
mark_good_blocks();
-
write_tables();
-
return 0;
-
}
1.3 mkfs.c编译的Makefile
-
cong@msi:/work/os/linux12/tools/mkfs$ cat Makefile
-
mkfs:mkfs.c
-
gcc -m32 -g -o $@ $^
-
clean:
-
-rm -rf *.o mkfs
2. 创建系统的脚本如下
有了mkfs之后就可以正常的构建linux0.12的文件系统了,脚本如下:
-
#!/bin/sh
-
create_fs()
-
{
-
#create filesystem
-
cd /tmp/minix
-
-
#先创建系统目录
-
sudo mkdir -pv etc dev bin usr usr/bin var
-
sudo mknod ./dev/tty1 c 4 1 -->需要打开tty1
-
sudo cp /work/os/linux12/tools/sh/init ./bin/ -->这儿随意写了个init
-
}
-
-
-
#fdisk hdc.img to minix 80
-
make_fs()
-
{
-
#sector的数目=524288=256M/512=256*1024*1024/512
-
dd if=/dev/zero of=./hdc.img bs=512 count=524288
-
fdisk ./hdc.img <<EOF --->对hdc.img进行分区,只分一个主分区,并设置分区为80(old minix)
-
n
-
p
-
1
-
2048 -->分区开始
-
524159 -->分区结束
-
t -->t change a partition's system id
-
80
-
w
-
EOF --->注意这个EOF必须顶格写,要不会出错
-
sleep 1
-
fdisk -l ./hdc.img
-
losetup /dev/loop0 ./hdc.img -->将整个的hdc.img镜像关联到/dev/loop0上去
-
#512*2048=1048576 -->分区是从2048个sector开始的
-
losetup -o 1048576 /dev/loop1 /dev/loop0 -->所以这儿 -o 加上偏移
-
losetup -a --> list all used losetup
-
./mkfs -c /dev/loop1 65535 -->对分区1格式化为 old minix分区
-
mkdir /tmp/minix
-
sudo mount -t minix /dev/loop1 /tmp/minix/ -->格式化后就可以挂载了
-
create_fs
-
}
-
umount_fs()
-
{
-
sudo umount /tmp/minix
-
losetup -d /dev/loop0
-
losetup -d /dev/loop1
-
losetup -a
-
}
-
-
clean_fs()
-
{
-
sudo umount /tmp/minix
-
losetup -d /dev/loop0
-
losetup -d /dev/loop1
-
rm -rf ./hdc.img
-
}
-
-
case "$1" in
-
fs)
-
make_fs
-
;;
-
clean)
-
clean_fs
-
;;
-
umount)
-
umount_fs
-
;;
-
*)
-
make_fs
-
;;
-
esac
3.代码打包
-
cong@msi:/work/os/linux12/tools/mkfs$ tree
-
.
-
├── fs.h
-
├── Makefile
-
├── mkfs
-
├── mkfs.c
-
├── mkfs.c_bak
-
└── mkfs_notation.c
mkfs.rar(下载后改名为mkfs.tar.gz)
4.运行结果
说明在建文件系统时init进程不正确导致,但至少文件系统是成功了。
5. 对于己建好的例如: rootimage-0.12-hd如何访问里面的内容呢?
-
cong@msi:/work/os/linux12$ fdisk -l ./rootimage-0.12-hd -->查看分区
-
-
Disk ./rootimage-0.12-hd: 251 MB, 251338752 bytes
-
16 heads, 63 sectors/track, 487 cylinders, total 490896 sectors
-
Units = sectors of 1 * 512 = 512 bytes
-
Sector size (logical/physical): 512 bytes / 512 bytes
-
I/O size (minimum/optimal): 512 bytes / 512 bytes
-
Disk identifier: 0x00000000
-
-
Device Boot Start End Blocks Id System
-
./rootimage-0.12-hd1 * 1 132047 66023+ 81 Minix / old Linux -->第1个分区是在偏移1*512处
-
./rootimage-0.12-hd2 132048 264095 66024 81 Minix / old Linux
-
./rootimage-0.12-hd3 264096 396143 66024 81 Minix / old Linux
-
./rootimage-0.12-hd4 396144 478799 41328 82 Linux swap / Solaris
-
-
-
cong@msi:/work/os/linux12$ losetup /dev/loop0 ./rootimage-0.12-hd -->losetup整个镜像
-
cong@msi:/work/os/linux12$ losetup -a
-
/dev/loop0: [0808]:49164984 (/work/os/linux12/rootimage-0.12-hd)
-
-
cong@msi:/work/os/linux12$ losetup -o 512 /dev/loop1 /dev/loop0 -->losetup分区1
-
-
cong@msi:/work/os/linux12$ losetup -a -->查看losetup
-
/dev/loop0: [0808]:49164984 (/work/os/linux12/rootimage-0.12-hd)
-
/dev/loop1: [0005]:1164 (/dev/loop0), offset 512
-
-
cong@msi:/work/os/linux12$ sudo mount -t minix /dev/loop0 /tmp/linux011/ -->挂载分区1
-
-
cong@msi:/work/os/linux12$ ls /tmp/linux011/
-
bin dev etc hdd home image MCC-0.12 mnt mnt1 README root tmp usr vmlinux
-
cong@msi:/work/os/linux12$ ls /tmp/linux011/bin/
-
agetty chage clock echo fdisk groupadd init logoutd mkswap newusers pwunconv sleep true userdel zic
-
awk chfn crond env fsck groupdel kdb mkfs mount passwd rm su umount usermod
-
bash chpasswd date faillog gawk groupmod lex.yy.c mknod mv ps sh sulogin update vi
-
bash.old chsh dpasswd false gpasswd id login mkpasswd newgrp pwconv sh.old sync useradd zdump
-
cong@msi:/work/os/linux12$ sudo file /tmp/linux011/bin/bash
-
/tmp/linux011/bin/bash: a.out little-endian 32-bit demand paged pure executable -->说明正确
根据上面的步骤就可以把己移植好的程序放到自己的hdc.img里面去了。
阅读(1454) | 评论(0) | 转发(0) |