����16-1 linux/tools/build.c


  1 /*

  2  *  linux/tools/build.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  * This file builds a disk-image from three different files:

  9  *

 10  * - bootsect: max 510 bytes of 8086 machine code, loads the rest

 11  * - setup: max 4 sectors of 8086 machine code, sets up system parm

 12  * - system: 80386 code for actual system

 13  *

 14  * It does some checking that all files are of the correct type, and

 15  * just writes the result to stdout, removing headers and padding to

 16  * the right amount. It also writes some system data to stderr.

 17  */

    /*

     * �ó����������ͬ�ij����д�������ӳ���ļ���

     *

     * - bootsect�����ļ���8086�������Ϊ510�ֽڣ����ڼ�����������

     * - setup�����ļ���8086�������Ϊ4��������������������ϵͳ������

     * - system��ʵ��ϵͳ��80386���롣

     *

     * �ó������ȼ�����г���ģ��������Ƿ���ȷ��������������ն�����ʾ������

     * Ȼ��ɾ��ģ��ͷ�����������ȷ�ij��ȡ��ó���Ҳ�ὫһЩϵͳ����д��stderr��

     */

 18

 19 /*

 20  * Changes by tytso to allow root device specification

 21  *

 22  * Added swap-device specification: Linux 20.12.91

 23  */

    /*

     * tytso�Ըó��������޸ģ�������ָ�����ļ��豸��

     *

     * ������ָ�������豸���ܣ�Linus 20.12.91

     */

 24

 25 #include <stdio.h>      /* fprintf */              // ʹ�����е�fprintf()������

 26 #include <string.h>                                // �ַ�������������

 27 #include <stdlib.h>     /* contains exit */        // ��exit����ԭ��˵����

 28 #include <sys/types.h>  /* unistd.h needs this */  // ��ͷ�ļ���unistd.h�ļ�ʹ�á�

 29 #include <sys/stat.h>                              // ���ļ�״̬��Ϣ�ṹ���塣

 30 #include <linux/fs.h>                              // �ļ�ϵͳͷ�ļ���

 31 #include <unistd.h>     /* contains read/write */  // ��read/write����ԭ��˵����

 32 #include <fcntl.h>                                 // �����ļ�����ģʽ���ų�����

 33

 34 #define MINIX_HEADER 32              // minix������Ŀ���ļ�ģ��ͷ������Ϊ32�ֽڡ�

 35 #define GCC_HEADER 1024              // GCCͷ����Ϣ����Ϊ1024�ֽڡ�

 36

 37 #define SYS_SIZE 0x3000              // system�ļ������(�ֽ���ΪSYS_SIZE*16=128KB)��

 38

    // Ĭ�ϵذ�Linux���ļ�ϵͳ�����豸����Ϊ�ڵ�2��Ӳ�̵ĵ�1�������ϣ����豸��Ϊ0x0306����

    // ����ΪLinus��ʱ����Linuxʱ���ѵ�1��Ӳ������MINIXϵͳ�̣�����2��Ӳ������ΪLinux

    // �ĸ��ļ�ϵͳ�̡�

 39 #define DEFAULT_MAJOR_ROOT 3         // Ĭ�ϸ��豸���豸�� - 3��Ӳ�̣���

 40 #define DEFAULT_MINOR_ROOT 6         // Ĭ�ϸ��豸���豸�� - 6����2��Ӳ�̵ĵ�1��������

 41

 42 #define DEFAULT_MAJOR_SWAP 0         // Ĭ�Ͻ����豸���豸�š�

 43 #define DEFAULT_MINOR_SWAP 0         // Ĭ�Ͻ����豸���豸�š�

 44

 45 /* max nr of sectors of setup: don't change unless you also change

 46  * bootsect etc */

    /* ����ָ��setupģ��ռ���������������Ҫ�ı��ֵ������Ҳ�ı�bootsect����Ӧ�ļ���

 47 #define SETUP_SECTS 4                // setup��󳤶�Ϊ4��������2KB����

 48

 49 #define STRINGIFY(x) #x              // ��xת�����ַ������ͣ����ڳ�����ʾ����С�

 50

    //// ��ʾ������Ϣ������ֹ����

 51 void die(char * str)

 52 {

 53         fprintf(stderr,"%s\n",str);

 54         exit(1);

 55 }

 56

    // ��ʾ����ʹ�÷��������˳���

 57 void usage(void)

 58 {

 59         die("Usage: build bootsect setup system [rootdev] [> image]");

 60 }

 61

    // ������ʼ��

 62 int main(int argc, char ** argv)

 63 {

 64         int i,c,id;

 65         char buf[1024];

 66         char major_root, minor_root;

 67         char major_swap, minor_swap;

 68         struct stat sb;

 69

    // ���ȼ��build����ִ��ʱʵ�������в��������������ݲ�����������Ӧ���á����build����

    // �����в�����������4��6��������������1����������ʾ�����÷����˳���

 70         if ((argc < 4) || (argc > 6))

 71                 usage();

    // ���������������ж���4����������ô������豸���������̣�"FLOPPY"������ȡ���豸�ļ���

    // ״̬��Ϣ����ȡ״̬��������ʾ��Ϣ���˳�������ȡ���豸��״̬�ṹ�е����豸�źʹ��豸��

    // ��Ϊ���豸�š�������豸����FLOPPY�豸���������豸�źʹ��豸��ȡ0����ʾ���豸�ǵ�ǰ

    // ���������豸��

 72         if (argc > 4) {

 73                 if (strcmp(argv[4], "FLOPPY")) {

 74                         if (stat(argv[4], &sb)) {

 75                                 perror(argv[4]);

 76                                 die("Couldn't stat root device.");

 77                         }

 78                         major_root = MAJOR(sb.st_rdev);   // ȡ�豸��״̬�ṹ���豸�š�

 79                         minor_root = MINOR(sb.st_rdev);

 80                 } else {

 81                         major_root = 0;

 82                         minor_root = 0;

 83                 }

    // ������ֻ��4�����������豸�źʹ��豸�ŵ���ϵͳĬ�ϵĸ��豸�š�

 84         } else {

 85                 major_root = DEFAULT_MAJOR_ROOT;

 86                 minor_root = DEFAULT_MINOR_ROOT;

 87         }

    // ����������������6����������ô������һ����ʾ�����豸�IJ��������ޣ�"NONE"������ȡ��

    // �豸�ļ���״̬��Ϣ����ȡ״̬��������ʾ��Ϣ���˳�������ȡ���豸��״̬�ṹ�е����豸��

    // �ʹ��豸����Ϊ�����豸�š�������һ����������"NONE"�����ý����豸�����豸�źʹ��豸

    // ��ȡΪ0����ʾ�����豸���ǵ�ǰ���������豸��

 88         if (argc == 6) {

 89                 if (strcmp(argv[5], "NONE")) {

 90                         if (stat(argv[5], &sb)) {

 91                                 perror(argv[5]);

 92                                 die("Couldn't stat root device.");

 93                         }

 94                         major_swap = MAJOR(sb.st_rdev);   // ȡ�豸��״̬�ṹ���豸�š�

 95                         minor_swap = MINOR(sb.st_rdev);

 96                 } else {

 97                         major_swap = 0;

 98                         minor_swap = 0;

 99                 }

    // ������û��6������5������ʾ��������û�д������豸�������Ǿ��ý����豸���豸�źʹ��豸

    // �ŵ���ϵͳĬ�ϵĽ����豸�š�

100         } else {

101                 major_swap = DEFAULT_MAJOR_SWAP;

102                 minor_swap = DEFAULT_MINOR_SWAP;

103         }

 

    // �������ڱ�׼�����ն�����ʾ������ѡ��ĸ��豸�������豸�źͽ����豸�������豸�š����

    // ���豸�Ų�����2�����̣���3��Ӳ�̣���Ҳ��Ϊ0��ȡϵͳĬ���豸��������ʾ������Ϣ���˳���

    // �ն˵ı�׼����������ļ�Image����˱�������������ں˴������ݣ������ں�ӳ���ļ���

104         fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);

105         fprintf(stderr, "Swap device is (%d, %d)\n", major_swap, minor_swap);

106         if ((major_root != 2) && (major_root != 3) &&

107             (major_root != 0)) {

108                 fprintf(stderr, "Illegal root device (major = %d)\n",

109                         major_root);

110                 die("Bad root device --- major #");

111         }

112         if (major_swap && major_swap != 3) {

113                 fprintf(stderr, "Illegal swap device (major = %d)\n",

114                         major_swap);

115                 die("Bad root device --- major #");

116         }

    // ���濪ʼִ�ж�ȡ�����ļ����ݲ�������Ӧ�ĸ��ƴ��������ȳ�ʼ��1KB�ĸ��ƻ���������ȫ0��

    // Ȼ����ֻ����ʽ�򿪲���1ָ�����ļ���bootsect�������ж�ȡ32�ֽڵ�MINIXִ���ļ�ͷ�ṹ

    // ���ݣ��μ��б���˵������������buf�С�

117         for (i=0;i<sizeof buf; i++) buf[i]=0;

118         if ((id=open(argv[1],O_RDONLY,0))<0)

119                 die("Unable to open 'boot'");

120         if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)

121                 die("Unable to read header of 'boot'");

    // ����������MINIXͷ���ṹ�ж�bootsect�Ƿ�Ϊһ����Ч��MINIXִ���ļ������ǣ�����ļ���

    // ��ȡ512�ֽڵ�����������������ݡ�

    // 0x0301 - MINIXͷ��a_magicħ����0x10 - a_flag��ִ�У�0x04 - a_cpu, Intel 8086�����롣

122         if (((long *) buf)[0]!=0x04100301)

123                 die("Non-Minix header of 'boot'");

    // �ж�ͷ�������ֶ�a_hdrlen���ֽڣ��Ƿ���ȷ��32�ֽڣ����������ֽ�����û���ã���0��

124         if (((long *) buf)[1]!=MINIX_HEADER)

125                 die("Non-Minix header of 'boot'");

    // �ж����ݶγ�a_data�ֶ�(long)�����Ƿ�Ϊ0��

126         if (((long *) buf)[3]!=0)

127                 die("Illegal data segment in 'boot'");

    // �ж϶�a_bss�ֶ�(long)�����Ƿ�Ϊ0��

128         if (((long *) buf)[4]!=0)

129                 die("Illegal bss in 'boot'");

    // �ж�ִ�е�a_entry�ֶ�(long)�����Ƿ�Ϊ0��

130         if (((long *) buf)[5] != 0)

131                 die("Non-Minix header of 'boot'");

    // �жϷ��ű����ֶ�a_sym�������Ƿ�Ϊ0��

132         if (((long *) buf)[7] != 0)

133                 die("Illegal symbol table in 'boot'");

    // �������ж϶���ȷ�������¶�ȡ�ļ�������ʵ�ʴ������ݣ�Ӧ�÷��ض�ȡ�ֽ���Ϊ512�ֽڡ�

    // ��Ϊbootsect�ļ��а�������1������������������������ݣ��������2�ֽ�Ӧ���ǿ�����

    // ��־0xAA55��

134         i=read(id,buf,sizeof buf);

135         fprintf(stderr,"Boot sector %d bytes.\n",i);

136         if (i != 512)

137                 die("Boot block must be exactly 512 bytes");

138         if ((*(unsigned short *)(buf+510)) != 0xAA55)

139                 die("Boot block hasn't got boot flag (0xAA55)");

    // ����������506��507ƫ�ƴ����Ž����豸�ţ�508��509ƫ�ƴ����Ÿ��豸�š�

140         buf[506] = (char) minor_swap;

141         buf[507] = (char) major_swap;

142         buf[508] = (char) minor_root;

143         buf[509] = (char) major_root;  

    // Ȼ�󽫸�512�ֽڵ�����д����׼���stdout����д���ֽ������ԣ�����ʾ������Ϣ���˳���

    // ��linux/Makefile�У�build�����׼������ض����ں�ӳ���ļ���Image�ϣ��������

    // ������������ݻᱻд��Image��ʼ��512�ֽڴ������ر�bootsectģ���ļ���

144         i=write(1,buf,512);

145         if (i!=512)

146                 die("Write call failed");

147         close (id);

148        

    // ������ֻ����ʽ�򿪲���2ָ�����ļ���setup�������ж�ȡ32�ֽڵ�MINIXִ���ļ�ͷ�ṹ

    // ���ݵ�������buf�С�������ʽ��������ͬ��������ֻ����ʽ��ָ�����ļ�setup�����ж�

    // ȡ32�ֽڵ�MINIXִ���ļ�ͷ�ṹ���ݵ�������buf�С�

149         if ((id=open(argv[2],O_RDONLY,0))<0)

150                 die("Unable to open 'setup'");

151         if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)

152                 die("Unable to read header of 'setup'");

    // ����������MINIXͷ���ṹ�ж�setup�Ƿ�Ϊһ����Ч��MINIXִ���ļ������ǣ�����ļ���

    // ��ȡ512�ֽڵ�����������������ݡ�

    // 0x0301- MINIXͷ��a_magicħ����0x10- a_flag��ִ�У�0x04- a_cpu, Intel 8086�����롣

153         if (((long *) buf)[0]!=0x04100301)

154                 die("Non-Minix header of 'setup'");

    // �ж�ͷ�������ֶ�a_hdrlen���ֽڣ��Ƿ���ȷ��32�ֽڣ����������ֽ�����û���ã���0��

155         if (((long *) buf)[1]!=MINIX_HEADER)

156                 die("Non-Minix header of 'setup'");

    // �ж����ݶγ��ֶ�a_data�����ֶ�a_bss����ʼִ�е��ֶ�a_entry�ͷ��ű��ֶ�a_sym������

    // �Ƿ�Ϊ0�����붼Ϊ0��

157         if (((long *) buf)[3]!=0)                      // ���ݶγ�a_data�ֶΡ�

158                 die("Illegal data segment in 'setup'");

159         if (((long *) buf)[4]!=0)                      // ��a_bss�ֶΡ�

160                 die("Illegal bss in 'setup'");

161         if (((long *) buf)[5] != 0)                    // ִ����ʼ��a_entry�ֶΡ�

162                 die("Non-Minix header of 'setup'");

163         if (((long *) buf)[7] != 0)

164                 die("Illegal symbol table in 'setup'");

    // �������ж϶���ȷ�������¶�ȡ�ļ�������ʵ�ʴ������ݣ�����д���ն˱�׼�����ͬʱͳ��

    // д�ij��ȣ�i�������ڲ���������ر�setup�ļ���֮���ж�һ������setupִ��д�����Ĵ���

    // �����ݳ���ֵ����ֵ���ܴ���(SETUP_SECTS * 512)�ֽڣ�����͵������޸�build��bootsect

    // ��setup�������趨��setup��ռ�����������±����ںˡ���һ����������ʾsetupʵ�ʳ���ֵ��

165         for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c )

166                 if (write(1,buf,c)!=c)

167                         die("Write call failed");

168         close (id);                                   //�ر�setupģ���ļ���

169         if (i > SETUP_SECTS*512)

170                 die("Setup exceeds " STRINGIFY(SETUP_SECTS)

171                         " sectors - rewrite build/boot/setup");

172         fprintf(stderr,"Setup is %d bytes.\n",i);

    // �ڽ�������buf����֮���ж�ʵ��д��setup������(SETUP_SECTS4*512)����ֵ���setup

    // ����С�ڸó��ȣ�4*512�ֽڣ�������NULL�ַ���setup����Ϊ4*512�ֽڡ�

173         for (c=0 ; c<sizeof(buf) ; c++)

174                 buf[c] = '\0';

175         while (i<SETUP_SECTS*512) {

176                 c = SETUP_SECTS*512-i;

177                 if (c > sizeof(buf))

178                         c = sizeof(buf);

179                 if (write(1,buf,c) != c)

180                         die("Write call failed");

181                 i += c;

182         }

183        

    // ���濪ʼ����systemģ���ļ������ļ�ʹ��gas���룬��˾���GNU a.outĿ���ļ���ʽ��

    // ������ֻ����ʽ���ļ�������ȡ����a.out��ʽͷ���ṹ��Ϣ��1KB���ȣ������ж�system

    // ��һ����Ч��a.out��ʽ�ļ�֮�󣬾ͰѸ��ļ������������ݶ�д����׼�����Image�ļ���

    // �У����رո��ļ���Ȼ����ʾsystemģ��ij��ȡ���system��������ݳ��ȳ���SYS_SIZE��

    // ����128KB�ֽڣ�������ʾ������Ϣ���˳������޴����򷵻�0����ʾ�����˳���

184         if ((id=open(argv[3],O_RDONLY,0))<0)

185                 die("Unable to open 'system'");

186         if (read(id,buf,GCC_HEADER) != GCC_HEADER)

187                 die("Unable to read header of 'system'");

188         if (((long *) buf)[5] != 0)               // ִ����ڵ��ֶ�a_entryֵӦΪ0��

189                 die("Non-GCC header of 'system'");

190         for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c )

191                 if (write(1,buf,c)!=c)

192                         die("Write call failed");

193         close(id);

194         fprintf(stderr,"System is %d bytes.\n",i);

195         if (i > SYS_SIZE*16)

196                 die("System is too big");

197         return(0);

198 }

199