/*
 *  linux/zBoot/xtract.c
 *
 *  
Copyright (C) 1993  Hannu Savolainen
 *
 *   
 Extracts the system image and writes it to the 
stdout.
 *    based on tools/build.c by Linus 
Torvalds
 */
#include <stdio.h>    /* 
fprintf */
#include <string.h>
#include <stdlib.h>   
 /* contains exit */
#include <sys/types.h>    /* 
unistd.h needs this */
#include <sys/stat.h>
#include 
<sys/sysmacros.h>
#include <unistd.h>    /* 
contains read/write */
#include <fcntl.h>
#include 
<a.out.h>
#include <linux/config.h>
#define GCC_HEADER 
1024
#define STRINGIFY(x) #x
//中断退出
void die(char * 
str)
{
    fprintf(stderr,"%s\n",str);
   
 exit(1);
}
//使用方法
void usage(void)
{
   
 die("Usage: xtract system [ | gzip | piggyback > 
piggy.s]");
}
//主函数
int main(int argc, char ** 
argv)
{
    int i,c,id, sz;
    char 
buf[1024];
    char major_root, minor_root;
   
 struct stat sb;
    //可执行文件指向缓冲区
   
 struct exec *ex = (struct exec *)buf;
   
 //参数一定是两个,否则提示使用方法
    if (argc  != 
2)
        usage();
   
 //打开第二个参数指定的文件
    if 
((id=open(argv[1],O_RDONLY,0))<0)
       
 die("Unable to open ‘system‘");
   
 //读取GCC文件头
    if (read(id,buf,GCC_HEADER) != 
GCC_HEADER)
        die("Unable to read header 
of ‘system‘");
    //校验
    if (N_MAGIC(*ex) 
!= ZMAGIC)
        die("Non-GCC header of 
‘system‘");
    //计算系统长度
    sz = 
N_SYMOFF(*ex) - GCC_HEADER + 4;    /* +4 to get the same result 
than tools/build */
    //输出系统长度
   
 fprintf(stderr, "System size is %d\n", sz);
   
 //遍历System文件
    while (sz)
   
 {
        int l, n;
   
     l = sz;
       
 //如果剩余长度大于buff长度,那么取buff长度
        if (l 
> sizeof(buf)) l = sizeof(buf);
       
 //读取一定长度
        if ((n=read(id, buf, l)) 
!=l)
        {
   
         if (n == -1) 
   
            
perror(argv[1]);
           
 else
           
    fprintf(stderr, "Unexpected EOF\n");
   
         die("Can‘t read 
system");
        }
   
     //将内容写入到标准输出中
       
 write(1, buf, l);
        sz -= 
l;
    }
    close(id);
   
 return(0);
}
原文地址:http://www.cnblogs.com/xiaofengwei/p/3753349.html