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