diff options
author | H. Peter Anvin <hpa@zytor.com> | 2007-07-11 15:18:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-12 13:55:55 -0400 |
commit | 4fd06960f120e02e9abc802a09f9511c400042a5 (patch) | |
tree | 4a7f26188d63ab01269aa6c6adfef01df3064ccd /arch/i386/boot | |
parent | f2d98ae63dc64dedb00499289e13a50677f771f9 (diff) |
Use the new x86 setup code for i386
This patch hooks the new x86 setup code into the Makefile machinery. It
also adapts boot/tools/build.c to a two-file (as opposed to three-file)
universe, and simplifies it substantially.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/i386/boot')
-rw-r--r-- | arch/i386/boot/Makefile | 48 | ||||
-rw-r--r-- | arch/i386/boot/compressed/Makefile | 7 | ||||
-rw-r--r-- | arch/i386/boot/tools/build.c | 160 |
3 files changed, 118 insertions, 97 deletions
diff --git a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile index bfbc32098a4a..08678a0a3d19 100644 --- a/arch/i386/boot/Makefile +++ b/arch/i386/boot/Makefile | |||
@@ -25,27 +25,56 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA | |||
25 | 25 | ||
26 | #RAMDISK := -DRAMDISK=512 | 26 | #RAMDISK := -DRAMDISK=512 |
27 | 27 | ||
28 | targets := vmlinux.bin bootsect bootsect.o \ | 28 | targets := vmlinux.bin setup.bin setup.elf zImage bzImage |
29 | setup setup.o zImage bzImage | ||
30 | subdir- := compressed | 29 | subdir- := compressed |
31 | 30 | ||
31 | setup-y += a20.o apm.o cmdline.o copy.o cpu.o cpucheck.o edd.o | ||
32 | setup-y += header.o main.o mca.o memory.o pm.o pmjump.o | ||
33 | setup-y += printf.o string.o tty.o video.o version.o voyager.o | ||
34 | |||
35 | # The link order of the video-*.o modules can matter. In particular, | ||
36 | # video-vga.o *must* be listed first, followed by video-vesa.o. | ||
37 | # Hardware-specific drivers should follow in the order they should be | ||
38 | # probed, and video-bios.o should typically be last. | ||
39 | setup-y += video-vga.o | ||
40 | setup-y += video-vesa.o | ||
41 | setup-y += video-bios.o | ||
42 | |||
32 | hostprogs-y := tools/build | 43 | hostprogs-y := tools/build |
33 | 44 | ||
34 | HOSTCFLAGS_build.o := $(LINUXINCLUDE) | 45 | HOSTCFLAGS_build.o := $(LINUXINCLUDE) |
35 | 46 | ||
36 | # --------------------------------------------------------------------------- | 47 | # --------------------------------------------------------------------------- |
37 | 48 | ||
49 | # How to compile the 16-bit code. Note we always compile for -march=i386, | ||
50 | # that way we can complain to the user if the CPU is insufficient. | ||
51 | cflags-i386 := | ||
52 | cflags-x86_64 := -m32 | ||
53 | CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \ | ||
54 | $(cflags-$(ARCH)) \ | ||
55 | -Wall -Wstrict-prototypes \ | ||
56 | -march=i386 -mregparm=3 \ | ||
57 | -include $(srctree)/$(src)/code16gcc.h \ | ||
58 | -fno-strict-aliasing -fomit-frame-pointer \ | ||
59 | $(call cc-option, -ffreestanding) \ | ||
60 | $(call cc-option, -fno-toplevel-reorder,\ | ||
61 | $(call cc-option, -fno-unit-at-a-time)) \ | ||
62 | $(call cc-option, -fno-stack-protector) \ | ||
63 | $(call cc-option, -mpreferred-stack-boundary=2) | ||
64 | AFLAGS := $(CFLAGS) -D__ASSEMBLY__ | ||
65 | |||
38 | $(obj)/zImage: IMAGE_OFFSET := 0x1000 | 66 | $(obj)/zImage: IMAGE_OFFSET := 0x1000 |
39 | $(obj)/zImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) | 67 | $(obj)/zImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) |
40 | $(obj)/bzImage: IMAGE_OFFSET := 0x100000 | 68 | $(obj)/bzImage: IMAGE_OFFSET := 0x100000 |
69 | $(obj)/bzImage: EXTRA_CFLAGS := -D__BIG_KERNEL__ | ||
41 | $(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__ | 70 | $(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__ |
42 | $(obj)/bzImage: BUILDFLAGS := -b | 71 | $(obj)/bzImage: BUILDFLAGS := -b |
43 | 72 | ||
44 | quiet_cmd_image = BUILD $@ | 73 | quiet_cmd_image = BUILD $@ |
45 | cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \ | 74 | cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/setup.bin \ |
46 | $(obj)/vmlinux.bin $(ROOT_DEV) > $@ | 75 | $(obj)/vmlinux.bin $(ROOT_DEV) > $@ |
47 | 76 | ||
48 | $(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \ | 77 | $(obj)/zImage $(obj)/bzImage: $(obj)/setup.bin \ |
49 | $(obj)/vmlinux.bin $(obj)/tools/build FORCE | 78 | $(obj)/vmlinux.bin $(obj)/tools/build FORCE |
50 | $(call if_changed,image) | 79 | $(call if_changed,image) |
51 | @echo 'Kernel: $@ is ready' ' (#'`cat .version`')' | 80 | @echo 'Kernel: $@ is ready' ' (#'`cat .version`')' |
@@ -53,12 +82,17 @@ $(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \ | |||
53 | $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE | 82 | $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE |
54 | $(call if_changed,objcopy) | 83 | $(call if_changed,objcopy) |
55 | 84 | ||
56 | LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary | 85 | SETUP_OBJS = $(addprefix $(obj)/,$(setup-y)) |
57 | LDFLAGS_setup := -Ttext 0x0 -s --oformat binary -e begtext | ||
58 | 86 | ||
59 | $(obj)/setup $(obj)/bootsect: %: %.o FORCE | 87 | LDFLAGS_setup.elf := -T |
88 | $(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE | ||
60 | $(call if_changed,ld) | 89 | $(call if_changed,ld) |
61 | 90 | ||
91 | OBJCOPYFLAGS_setup.bin := -O binary | ||
92 | |||
93 | $(obj)/setup.bin: $(obj)/setup.elf FORCE | ||
94 | $(call if_changed,objcopy) | ||
95 | |||
62 | $(obj)/compressed/vmlinux: FORCE | 96 | $(obj)/compressed/vmlinux: FORCE |
63 | $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@ | 97 | $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@ |
64 | 98 | ||
diff --git a/arch/i386/boot/compressed/Makefile b/arch/i386/boot/compressed/Makefile index a661217f33ec..189fa1dbefcc 100644 --- a/arch/i386/boot/compressed/Makefile +++ b/arch/i386/boot/compressed/Makefile | |||
@@ -9,9 +9,14 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o \ | |||
9 | EXTRA_AFLAGS := -traditional | 9 | EXTRA_AFLAGS := -traditional |
10 | 10 | ||
11 | LDFLAGS_vmlinux := -T | 11 | LDFLAGS_vmlinux := -T |
12 | CFLAGS_misc.o += -fPIC | ||
13 | hostprogs-y := relocs | 12 | hostprogs-y := relocs |
14 | 13 | ||
14 | CFLAGS := -m32 -D__KERNEL__ $(LINUX_INCLUDE) -O2 \ | ||
15 | -fno-strict-aliasing -fPIC \ | ||
16 | $(call cc-option,-ffreestanding) \ | ||
17 | $(call cc-option,-fno-stack-protector) | ||
18 | LDFLAGS := -m elf_i386 | ||
19 | |||
15 | $(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE | 20 | $(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE |
16 | $(call if_changed,ld) | 21 | $(call if_changed,ld) |
17 | @: | 22 | @: |
diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c index 05798419a6a9..886f47d8a488 100644 --- a/arch/i386/boot/tools/build.c +++ b/arch/i386/boot/tools/build.c | |||
@@ -1,13 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 1991, 1992 Linus Torvalds | 2 | * Copyright (C) 1991, 1992 Linus Torvalds |
3 | * Copyright (C) 1997 Martin Mares | 3 | * Copyright (C) 1997 Martin Mares |
4 | * Copyright (C) 2007 H. Peter Anvin | ||
4 | */ | 5 | */ |
5 | 6 | ||
6 | /* | 7 | /* |
7 | * This file builds a disk-image from three different files: | 8 | * This file builds a disk-image from three different files: |
8 | * | 9 | * |
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 | 10 | * - setup: 8086 machine code, sets up system parm |
12 | * - system: 80386 code for actual system | 11 | * - system: 80386 code for actual system |
13 | * | 12 | * |
@@ -21,6 +20,7 @@ | |||
21 | * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 | 20 | * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 |
22 | * Cross compiling fixes by Gertjan van Wingerde, July 1996 | 21 | * Cross compiling fixes by Gertjan van Wingerde, July 1996 |
23 | * Rewritten by Martin Mares, April 1997 | 22 | * Rewritten by Martin Mares, April 1997 |
23 | * Substantially overhauled by H. Peter Anvin, April 2007 | ||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <stdio.h> | 26 | #include <stdio.h> |
@@ -32,23 +32,25 @@ | |||
32 | #include <sys/sysmacros.h> | 32 | #include <sys/sysmacros.h> |
33 | #include <unistd.h> | 33 | #include <unistd.h> |
34 | #include <fcntl.h> | 34 | #include <fcntl.h> |
35 | #include <sys/mman.h> | ||
35 | #include <asm/boot.h> | 36 | #include <asm/boot.h> |
36 | 37 | ||
37 | typedef unsigned char byte; | 38 | typedef unsigned char u8; |
38 | typedef unsigned short word; | 39 | typedef unsigned short u16; |
39 | typedef unsigned long u32; | 40 | typedef unsigned long u32; |
40 | 41 | ||
41 | #define DEFAULT_MAJOR_ROOT 0 | 42 | #define DEFAULT_MAJOR_ROOT 0 |
42 | #define DEFAULT_MINOR_ROOT 0 | 43 | #define DEFAULT_MINOR_ROOT 0 |
43 | 44 | ||
44 | /* Minimal number of setup sectors (see also bootsect.S) */ | 45 | /* Minimal number of setup sectors */ |
45 | #define SETUP_SECTS 4 | 46 | #define SETUP_SECT_MIN 5 |
47 | #define SETUP_SECT_MAX 64 | ||
46 | 48 | ||
47 | byte buf[1024]; | 49 | /* This must be large enough to hold the entire setup */ |
48 | int fd; | 50 | u8 buf[SETUP_SECT_MAX*512]; |
49 | int is_big_kernel; | 51 | int is_big_kernel; |
50 | 52 | ||
51 | void die(const char * str, ...) | 53 | static void die(const char * str, ...) |
52 | { | 54 | { |
53 | va_list args; | 55 | va_list args; |
54 | va_start(args, str); | 56 | va_start(args, str); |
@@ -57,15 +59,9 @@ void die(const char * str, ...) | |||
57 | exit(1); | 59 | exit(1); |
58 | } | 60 | } |
59 | 61 | ||
60 | void file_open(const char *name) | 62 | static void usage(void) |
61 | { | 63 | { |
62 | if ((fd = open(name, O_RDONLY, 0)) < 0) | 64 | die("Usage: build [-b] setup system [rootdev] [> image]"); |
63 | die("Unable to open `%s': %m", name); | ||
64 | } | ||
65 | |||
66 | void usage(void) | ||
67 | { | ||
68 | die("Usage: build [-b] bootsect setup system [rootdev] [> image]"); | ||
69 | } | 65 | } |
70 | 66 | ||
71 | int main(int argc, char ** argv) | 67 | int main(int argc, char ** argv) |
@@ -73,27 +69,30 @@ int main(int argc, char ** argv) | |||
73 | unsigned int i, sz, setup_sectors; | 69 | unsigned int i, sz, setup_sectors; |
74 | int c; | 70 | int c; |
75 | u32 sys_size; | 71 | u32 sys_size; |
76 | byte major_root, minor_root; | 72 | u8 major_root, minor_root; |
77 | struct stat sb; | 73 | struct stat sb; |
74 | FILE *file; | ||
75 | int fd; | ||
76 | void *kernel; | ||
78 | 77 | ||
79 | if (argc > 2 && !strcmp(argv[1], "-b")) | 78 | if (argc > 2 && !strcmp(argv[1], "-b")) |
80 | { | 79 | { |
81 | is_big_kernel = 1; | 80 | is_big_kernel = 1; |
82 | argc--, argv++; | 81 | argc--, argv++; |
83 | } | 82 | } |
84 | if ((argc < 4) || (argc > 5)) | 83 | if ((argc < 3) || (argc > 4)) |
85 | usage(); | 84 | usage(); |
86 | if (argc > 4) { | 85 | if (argc > 3) { |
87 | if (!strcmp(argv[4], "CURRENT")) { | 86 | if (!strcmp(argv[3], "CURRENT")) { |
88 | if (stat("/", &sb)) { | 87 | if (stat("/", &sb)) { |
89 | perror("/"); | 88 | perror("/"); |
90 | die("Couldn't stat /"); | 89 | die("Couldn't stat /"); |
91 | } | 90 | } |
92 | major_root = major(sb.st_dev); | 91 | major_root = major(sb.st_dev); |
93 | minor_root = minor(sb.st_dev); | 92 | minor_root = minor(sb.st_dev); |
94 | } else if (strcmp(argv[4], "FLOPPY")) { | 93 | } else if (strcmp(argv[3], "FLOPPY")) { |
95 | if (stat(argv[4], &sb)) { | 94 | if (stat(argv[3], &sb)) { |
96 | perror(argv[4]); | 95 | perror(argv[3]); |
97 | die("Couldn't stat root device."); | 96 | die("Couldn't stat root device."); |
98 | } | 97 | } |
99 | major_root = major(sb.st_rdev); | 98 | major_root = major(sb.st_rdev); |
@@ -108,79 +107,62 @@ int main(int argc, char ** argv) | |||
108 | } | 107 | } |
109 | fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root); | 108 | fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root); |
110 | 109 | ||
111 | file_open(argv[1]); | 110 | /* Copy the setup code */ |
112 | i = read(fd, buf, sizeof(buf)); | 111 | file = fopen(argv[1], "r"); |
113 | fprintf(stderr,"Boot sector %d bytes.\n",i); | 112 | if (!file) |
114 | if (i != 512) | 113 | die("Unable to open `%s': %m", argv[1]); |
115 | die("Boot block must be exactly 512 bytes"); | 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"); | ||
116 | if (buf[510] != 0x55 || buf[511] != 0xaa) | 119 | if (buf[510] != 0x55 || buf[511] != 0xaa) |
117 | die("Boot block hasn't got boot flag (0xAA55)"); | 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 */ | ||
118 | buf[508] = minor_root; | 131 | buf[508] = minor_root; |
119 | buf[509] = major_root; | 132 | buf[509] = major_root; |
120 | if (write(1, buf, 512) != 512) | ||
121 | die("Write call failed"); | ||
122 | close (fd); | ||
123 | |||
124 | file_open(argv[2]); /* Copy the setup code */ | ||
125 | for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c ) | ||
126 | if (write(1, buf, c) != c) | ||
127 | die("Write call failed"); | ||
128 | if (c != 0) | ||
129 | die("read-error on `setup'"); | ||
130 | close (fd); | ||
131 | |||
132 | setup_sectors = (i + 511) / 512; /* Pad unused space with zeros */ | ||
133 | /* for compatibility with ancient versions of LILO. */ | ||
134 | if (setup_sectors < SETUP_SECTS) | ||
135 | setup_sectors = SETUP_SECTS; | ||
136 | fprintf(stderr, "Setup is %d bytes.\n", i); | ||
137 | memset(buf, 0, sizeof(buf)); | ||
138 | while (i < setup_sectors * 512) { | ||
139 | c = setup_sectors * 512 - i; | ||
140 | if (c > sizeof(buf)) | ||
141 | c = sizeof(buf); | ||
142 | if (write(1, buf, c) != c) | ||
143 | die("Write call failed"); | ||
144 | i += c; | ||
145 | } | ||
146 | 133 | ||
147 | file_open(argv[3]); | 134 | fprintf(stderr, "Setup is %d bytes (padded to %d bytes).\n", c, i); |
148 | if (fstat (fd, &sb)) | 135 | |
149 | die("Unable to stat `%s': %m", argv[3]); | 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]); | ||
150 | sz = sb.st_size; | 142 | sz = sb.st_size; |
151 | fprintf (stderr, "System is %d kB\n", sz/1024); | 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]); | ||
152 | sys_size = (sz + 15) / 16; | 147 | sys_size = (sz + 15) / 16; |
153 | if (!is_big_kernel && sys_size > DEF_SYSSIZE) | 148 | if (!is_big_kernel && sys_size > DEF_SYSSIZE) |
154 | die("System is too big. Try using bzImage or modules."); | 149 | die("System is too big. Try using bzImage or modules."); |
155 | while (sz > 0) { | 150 | |
156 | int l, n; | 151 | /* Patch the setup code with the appropriate size parameters */ |
157 | 152 | buf[0x1f1] = setup_sectors-1; | |
158 | l = (sz > sizeof(buf)) ? sizeof(buf) : sz; | 153 | buf[0x1f4] = sys_size; |
159 | if ((n=read(fd, buf, l)) != l) { | 154 | buf[0x1f5] = sys_size >> 8; |
160 | if (n < 0) | 155 | buf[0x1f6] = sys_size >> 16; |
161 | die("Error reading %s: %m", argv[3]); | 156 | buf[0x1f7] = sys_size >> 24; |
162 | else | 157 | |
163 | die("%s: Unexpected EOF", argv[3]); | 158 | if (fwrite(buf, 1, i, stdout) != i) |
164 | } | 159 | die("Writing setup failed"); |
165 | if (write(1, buf, l) != l) | 160 | |
166 | die("Write failed"); | 161 | /* Copy the kernel code */ |
167 | sz -= l; | 162 | if (fwrite(kernel, 1, sz, stdout) != sz) |
168 | } | 163 | die("Writing kernel failed"); |
169 | close(fd); | 164 | close(fd); |
170 | 165 | ||
171 | if (lseek(1, 497, SEEK_SET) != 497) /* Write sizes to the bootsector */ | 166 | /* Everything is OK */ |
172 | die("Output: seek failed"); | 167 | return 0; |
173 | buf[0] = setup_sectors; | ||
174 | if (write(1, buf, 1) != 1) | ||
175 | die("Write of setup sector count failed"); | ||
176 | if (lseek(1, 500, SEEK_SET) != 500) | ||
177 | die("Output: seek failed"); | ||
178 | buf[0] = (sys_size & 0xff); | ||
179 | buf[1] = ((sys_size >> 8) & 0xff); | ||
180 | buf[2] = ((sys_size >> 16) & 0xff); | ||
181 | buf[3] = ((sys_size >> 24) & 0xff); | ||
182 | if (write(1, buf, 4) != 4) | ||
183 | die("Write of image length failed"); | ||
184 | |||
185 | return 0; /* Everything is OK */ | ||
186 | } | 168 | } |