diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2007-10-11 05:16:41 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2007-10-11 05:16:41 -0400 |
commit | 19d8d79ccfd2fb67b1eb86e3c634a2e68a4c4b11 (patch) | |
tree | 276f8ddde0ae94d52040d804133c1792019dbaed /arch/x86 | |
parent | c750a66b0ebfcd8f4cb353ab37b286c8cd93ad10 (diff) |
i386: move boot
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/boot/tools/.gitignore | 1 | ||||
-rw-r--r-- | arch/x86/boot/tools/build.c | 168 |
2 files changed, 169 insertions, 0 deletions
diff --git a/arch/x86/boot/tools/.gitignore b/arch/x86/boot/tools/.gitignore new file mode 100644 index 000000000000..378eac25d311 --- /dev/null +++ b/arch/x86/boot/tools/.gitignore | |||
@@ -0,0 +1 @@ | |||
build | |||
diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c new file mode 100644 index 000000000000..b4248740ff0d --- /dev/null +++ b/arch/x86/boot/tools/build.c | |||
@@ -0,0 +1,168 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1991, 1992 Linus Torvalds | ||
3 | * Copyright (C) 1997 Martin Mares | ||
4 | * Copyright (C) 2007 H. Peter Anvin | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * This file builds a disk-image from two different files: | ||
9 | * | ||
10 | * - setup: 8086 machine code, sets up system parm | ||
11 | * - system: 80386 code for actual system | ||
12 | * | ||
13 | * It does some checking that all files are of the correct type, and | ||
14 | * just writes the result to stdout, removing headers and padding to | ||
15 | * the right amount. It also writes some system data to stderr. | ||
16 | */ | ||
17 | |||
18 | /* | ||
19 | * Changes by tytso to allow root device specification | ||
20 | * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 | ||
21 | * Cross compiling fixes by Gertjan van Wingerde, July 1996 | ||
22 | * Rewritten by Martin Mares, April 1997 | ||
23 | * Substantially overhauled by H. Peter Anvin, April 2007 | ||
24 | */ | ||
25 | |||
26 | #include <stdio.h> | ||
27 | #include <string.h> | ||
28 | #include <stdlib.h> | ||
29 | #include <stdarg.h> | ||
30 | #include <sys/types.h> | ||
31 | #include <sys/stat.h> | ||
32 | #include <sys/sysmacros.h> | ||
33 | #include <unistd.h> | ||
34 | #include <fcntl.h> | ||
35 | #include <sys/mman.h> | ||
36 | #include <asm/boot.h> | ||
37 | |||
38 | typedef unsigned char u8; | ||
39 | typedef unsigned short u16; | ||
40 | typedef unsigned long u32; | ||
41 | |||
42 | #define DEFAULT_MAJOR_ROOT 0 | ||
43 | #define DEFAULT_MINOR_ROOT 0 | ||
44 | |||
45 | /* Minimal number of setup sectors */ | ||
46 | #define SETUP_SECT_MIN 5 | ||
47 | #define SETUP_SECT_MAX 64 | ||
48 | |||
49 | /* This must be large enough to hold the entire setup */ | ||
50 | u8 buf[SETUP_SECT_MAX*512]; | ||
51 | int is_big_kernel; | ||
52 | |||
53 | static void die(const char * str, ...) | ||
54 | { | ||
55 | va_list args; | ||
56 | va_start(args, str); | ||
57 | vfprintf(stderr, str, args); | ||
58 | fputc('\n', stderr); | ||
59 | exit(1); | ||
60 | } | ||
61 | |||
62 | static void usage(void) | ||
63 | { | ||
64 | die("Usage: build [-b] setup system [rootdev] [> image]"); | ||
65 | } | ||
66 | |||
67 | int main(int argc, char ** argv) | ||
68 | { | ||
69 | unsigned int i, sz, setup_sectors; | ||
70 | int c; | ||
71 | u32 sys_size; | ||
72 | u8 major_root, minor_root; | ||
73 | struct stat sb; | ||
74 | FILE *file; | ||
75 | int fd; | ||
76 | void *kernel; | ||
77 | |||
78 | if (argc > 2 && !strcmp(argv[1], "-b")) | ||
79 | { | ||
80 | is_big_kernel = 1; | ||
81 | argc--, argv++; | ||
82 | } | ||
83 | if ((argc < 3) || (argc > 4)) | ||
84 | usage(); | ||
85 | if (argc > 3) { | ||
86 | if (!strcmp(argv[3], "CURRENT")) { | ||
87 | if (stat("/", &sb)) { | ||
88 | perror("/"); | ||
89 | die("Couldn't stat /"); | ||
90 | } | ||
91 | major_root = major(sb.st_dev); | ||
92 | minor_root = minor(sb.st_dev); | ||
93 | } else if (strcmp(argv[3], "FLOPPY")) { | ||
94 | if (stat(argv[3], &sb)) { | ||
95 | perror(argv[3]); | ||
96 | die("Couldn't stat root device."); | ||
97 | } | ||
98 | major_root = major(sb.st_rdev); | ||
99 | minor_root = minor(sb.st_rdev); | ||
100 | } else { | ||
101 | major_root = 0; | ||
102 | minor_root = 0; | ||
103 | } | ||
104 | } else { | ||
105 | major_root = DEFAULT_MAJOR_ROOT; | ||
106 | minor_root = DEFAULT_MINOR_ROOT; | ||
107 | } | ||
108 | fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root); | ||
109 | |||
110 | /* Copy the setup code */ | ||
111 | file = fopen(argv[1], "r"); | ||
112 | if (!file) | ||
113 | die("Unable to open `%s': %m", argv[1]); | ||
114 | c = fread(buf, 1, sizeof(buf), file); | ||
115 | if (ferror(file)) | ||
116 | die("read-error on `setup'"); | ||
117 | if (c < 1024) | ||
118 | die("The setup must be at least 1024 bytes"); | ||
119 | if (buf[510] != 0x55 || buf[511] != 0xaa) | ||
120 | die("Boot block hasn't got boot flag (0xAA55)"); | ||
121 | fclose(file); | ||
122 | |||
123 | /* Pad unused space with zeros */ | ||
124 | setup_sectors = (c + 511) / 512; | ||
125 | if (setup_sectors < SETUP_SECT_MIN) | ||
126 | setup_sectors = SETUP_SECT_MIN; | ||
127 | i = setup_sectors*512; | ||
128 | memset(buf+c, 0, i-c); | ||
129 | |||
130 | /* Set the default root device */ | ||
131 | buf[508] = minor_root; | ||
132 | buf[509] = major_root; | ||
133 | |||
134 | fprintf(stderr, "Setup is %d bytes (padded to %d bytes).\n", c, i); | ||
135 | |||
136 | /* Open and stat the kernel file */ | ||
137 | fd = open(argv[2], O_RDONLY); | ||
138 | if (fd < 0) | ||
139 | die("Unable to open `%s': %m", argv[2]); | ||
140 | if (fstat(fd, &sb)) | ||
141 | die("Unable to stat `%s': %m", argv[2]); | ||
142 | sz = sb.st_size; | ||
143 | fprintf (stderr, "System is %d kB\n", (sz+1023)/1024); | ||
144 | kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0); | ||
145 | if (kernel == MAP_FAILED) | ||
146 | die("Unable to mmap '%s': %m", argv[2]); | ||
147 | sys_size = (sz + 15) / 16; | ||
148 | if (!is_big_kernel && sys_size > DEF_SYSSIZE) | ||
149 | die("System is too big. Try using bzImage or modules."); | ||
150 | |||
151 | /* Patch the setup code with the appropriate size parameters */ | ||
152 | buf[0x1f1] = setup_sectors-1; | ||
153 | buf[0x1f4] = sys_size; | ||
154 | buf[0x1f5] = sys_size >> 8; | ||
155 | buf[0x1f6] = sys_size >> 16; | ||
156 | buf[0x1f7] = sys_size >> 24; | ||
157 | |||
158 | if (fwrite(buf, 1, i, stdout) != i) | ||
159 | die("Writing setup failed"); | ||
160 | |||
161 | /* Copy the kernel code */ | ||
162 | if (fwrite(kernel, 1, sz, stdout) != sz) | ||
163 | die("Writing kernel failed"); | ||
164 | close(fd); | ||
165 | |||
166 | /* Everything is OK */ | ||
167 | return 0; | ||
168 | } | ||