Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios.git] / kitten / arch / x86_64 / boot / tools / build.c
1 /*
2  *  Copyright (C) 1991, 1992  Linus Torvalds
3  *  Copyright (C) 1997 Martin Mares
4  */
5
6 /*
7  * This file builds a disk-image from three different files:
8  *
9  * - bootsect:  Compatibility mbr which prints an error message if
10  *              someone tries to boot the kernel directly.
11  * - setup:     8086 machine code, sets up system parm
12  * - vmlwk.bin: The "piggy" LWK kernel image.  The first part of the
13  *              image is the decompression code (compressed/head.o),
14  *              which begins executing at startup_32.  startup_32 then
15  *              uncompresses the real kernel image that follows it.
16  *
17  * It does some checking that all files are of the correct type, and
18  * just writes the result to stdout, removing headers and padding to
19  * the right amount. It also writes some system data to stderr.
20  */
21
22 /*
23  * Changes by tytso to allow root device specification
24  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
25  * Cross compiling fixes by Gertjan van Wingerde, July 1996
26  * Rewritten by Martin Mares, April 1997
27  */
28
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include <stdarg.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <sys/sysmacros.h>
36 #include <unistd.h>
37 #include <fcntl.h>
38 #include <asm/boot.h>
39
40 typedef unsigned char byte;
41 typedef unsigned short word;
42 typedef unsigned long u32;
43
44 #define DEFAULT_MAJOR_ROOT 0
45 #define DEFAULT_MINOR_ROOT 0
46
47 /* Minimal number of setup sectors (see also bootsect.S) */
48 #define SETUP_SECTS 4
49
50 byte buf[1024];
51 int fd;
52 int is_big_kernel;
53
54 void die(const char * str, ...)
55 {
56         va_list args;
57         va_start(args, str);
58         vfprintf(stderr, str, args);
59         fputc('\n', stderr);
60         exit(1);
61 }
62
63 void file_open(const char *name)
64 {
65         if ((fd = open(name, O_RDONLY, 0)) < 0)
66                 die("Unable to open `%s': %m", name);
67 }
68
69 void usage(void)
70 {
71         die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
72 }
73
74 int main(int argc, char ** argv)
75 {
76         unsigned int i, c, sz, setup_sectors;
77         u32 sys_size;
78         byte major_root, minor_root;
79         struct stat sb;
80
81         if (argc > 2 && !strcmp(argv[1], "-b"))
82           {
83             is_big_kernel = 1;
84             argc--, argv++;
85           }
86         if ((argc < 4) || (argc > 5))
87                 usage();
88         if (argc > 4) {
89                 if (!strcmp(argv[4], "CURRENT")) {
90                         if (stat("/", &sb)) {
91                                 perror("/");
92                                 die("Couldn't stat /");
93                         }
94                         major_root = major(sb.st_dev);
95                         minor_root = minor(sb.st_dev);
96                 } else if (strcmp(argv[4], "FLOPPY")) {
97                         if (stat(argv[4], &sb)) {
98                                 perror(argv[4]);
99                                 die("Couldn't stat root device.");
100                         }
101                         major_root = major(sb.st_rdev);
102                         minor_root = minor(sb.st_rdev);
103                 } else {
104                         major_root = 0;
105                         minor_root = 0;
106                 }
107         } else {
108                 major_root = DEFAULT_MAJOR_ROOT;
109                 minor_root = DEFAULT_MINOR_ROOT;
110         }
111         fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
112
113         file_open(argv[1]);
114         i = read(fd, buf, sizeof(buf));
115         fprintf(stderr,"Boot sector %d bytes.\n",i);
116         if (i != 512)
117                 die("Boot block must be exactly 512 bytes");
118         if (buf[510] != 0x55 || buf[511] != 0xaa)
119                 die("Boot block hasn't got boot flag (0xAA55)");
120         buf[508] = minor_root;
121         buf[509] = major_root;
122         if (write(1, buf, 512) != 512)
123                 die("Write call failed");
124         close (fd);
125
126         file_open(argv[2]);                                 /* Copy the setup code */
127         for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
128                 if (write(1, buf, c) != c)
129                         die("Write call failed");
130         if (c != 0)
131                 die("read-error on `setup'");
132         close (fd);
133
134         setup_sectors = (i + 511) / 512;        /* Pad unused space with zeros */
135         /* for compatibility with ancient versions of LILO. */
136         if (setup_sectors < SETUP_SECTS)
137                 setup_sectors = SETUP_SECTS;
138         fprintf(stderr, "Setup is %d bytes.\n", i);
139         memset(buf, 0, sizeof(buf));
140         while (i < setup_sectors * 512) {
141                 c = setup_sectors * 512 - i;
142                 if (c > sizeof(buf))
143                         c = sizeof(buf);
144                 if (write(1, buf, c) != c)
145                         die("Write call failed");
146                 i += c;
147         }
148
149         file_open(argv[3]);
150         if (fstat (fd, &sb))
151                 die("Unable to stat `%s': %m", argv[3]);
152         sz = sb.st_size;
153         fprintf (stderr, "System is %d kB\n", sz/1024);
154         sys_size = (sz + 15) / 16;
155         /* 0x40000*16 = 4.0 MB, reasonable estimate for the current maximum */
156         if (sys_size > (is_big_kernel ? 0x40000 : DEF_SYSSIZE))
157                 die("System is too big. Try using %smodules.",
158                         is_big_kernel ? "" : "bzImage or ");
159         while (sz > 0) {
160                 int l, n;
161
162                 l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
163                 if ((n=read(fd, buf, l)) != l) {
164                         if (n < 0)
165                                 die("Error reading %s: %m", argv[3]);
166                         else
167                                 die("%s: Unexpected EOF", argv[3]);
168                 }
169                 if (write(1, buf, l) != l)
170                         die("Write failed");
171                 sz -= l;
172         }
173         close(fd);
174
175         if (lseek(1, 497, SEEK_SET) != 497)                 /* Write sizes to the bootsector */
176                 die("Output: seek failed");
177         buf[0] = setup_sectors;
178         if (write(1, buf, 1) != 1)
179                 die("Write of setup sector count failed");
180         if (lseek(1, 500, SEEK_SET) != 500)
181                 die("Output: seek failed");
182         buf[0] = (sys_size & 0xff);
183         buf[1] = ((sys_size >> 8) & 0xff);
184         buf[2] = ((sys_size >> 16) & 0xff);
185         buf[3] = ((sys_size >> 24) & 0xff);
186         if (write(1, buf, 4) != 4)
187                 die("Write of image length failed");
188
189         return 0;                                           /* Everything is OK */
190 }