Commit 4fd06960 authored by H. Peter Anvin's avatar H. Peter Anvin Committed by Linus Torvalds

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: default avatarH. Peter Anvin <hpa@zytor.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent f2d98ae6
...@@ -25,27 +25,56 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA ...@@ -25,27 +25,56 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
#RAMDISK := -DRAMDISK=512 #RAMDISK := -DRAMDISK=512
targets := vmlinux.bin bootsect bootsect.o \ targets := vmlinux.bin setup.bin setup.elf zImage bzImage
setup setup.o zImage bzImage
subdir- := compressed subdir- := compressed
setup-y += a20.o apm.o cmdline.o copy.o cpu.o cpucheck.o edd.o
setup-y += header.o main.o mca.o memory.o pm.o pmjump.o
setup-y += printf.o string.o tty.o video.o version.o voyager.o
# The link order of the video-*.o modules can matter. In particular,
# video-vga.o *must* be listed first, followed by video-vesa.o.
# Hardware-specific drivers should follow in the order they should be
# probed, and video-bios.o should typically be last.
setup-y += video-vga.o
setup-y += video-vesa.o
setup-y += video-bios.o
hostprogs-y := tools/build hostprogs-y := tools/build
HOSTCFLAGS_build.o := $(LINUXINCLUDE) HOSTCFLAGS_build.o := $(LINUXINCLUDE)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# How to compile the 16-bit code. Note we always compile for -march=i386,
# that way we can complain to the user if the CPU is insufficient.
cflags-i386 :=
cflags-x86_64 := -m32
CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
$(cflags-$(ARCH)) \
-Wall -Wstrict-prototypes \
-march=i386 -mregparm=3 \
-include $(srctree)/$(src)/code16gcc.h \
-fno-strict-aliasing -fomit-frame-pointer \
$(call cc-option, -ffreestanding) \
$(call cc-option, -fno-toplevel-reorder,\
$(call cc-option, -fno-unit-at-a-time)) \
$(call cc-option, -fno-stack-protector) \
$(call cc-option, -mpreferred-stack-boundary=2)
AFLAGS := $(CFLAGS) -D__ASSEMBLY__
$(obj)/zImage: IMAGE_OFFSET := 0x1000 $(obj)/zImage: IMAGE_OFFSET := 0x1000
$(obj)/zImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) $(obj)/zImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK)
$(obj)/bzImage: IMAGE_OFFSET := 0x100000 $(obj)/bzImage: IMAGE_OFFSET := 0x100000
$(obj)/bzImage: EXTRA_CFLAGS := -D__BIG_KERNEL__
$(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__ $(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
$(obj)/bzImage: BUILDFLAGS := -b $(obj)/bzImage: BUILDFLAGS := -b
quiet_cmd_image = BUILD $@ quiet_cmd_image = BUILD $@
cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \ cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/setup.bin \
$(obj)/vmlinux.bin $(ROOT_DEV) > $@ $(obj)/vmlinux.bin $(ROOT_DEV) > $@
$(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \ $(obj)/zImage $(obj)/bzImage: $(obj)/setup.bin \
$(obj)/vmlinux.bin $(obj)/tools/build FORCE $(obj)/vmlinux.bin $(obj)/tools/build FORCE
$(call if_changed,image) $(call if_changed,image)
@echo 'Kernel: $@ is ready' ' (#'`cat .version`')' @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
...@@ -53,12 +82,17 @@ $(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \ ...@@ -53,12 +82,17 @@ $(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy) $(call if_changed,objcopy)
LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary SETUP_OBJS = $(addprefix $(obj)/,$(setup-y))
LDFLAGS_setup := -Ttext 0x0 -s --oformat binary -e begtext
$(obj)/setup $(obj)/bootsect: %: %.o FORCE LDFLAGS_setup.elf := -T
$(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE
$(call if_changed,ld) $(call if_changed,ld)
OBJCOPYFLAGS_setup.bin := -O binary
$(obj)/setup.bin: $(obj)/setup.elf FORCE
$(call if_changed,objcopy)
$(obj)/compressed/vmlinux: FORCE $(obj)/compressed/vmlinux: FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@ $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@
......
...@@ -9,9 +9,14 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o \ ...@@ -9,9 +9,14 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o \
EXTRA_AFLAGS := -traditional EXTRA_AFLAGS := -traditional
LDFLAGS_vmlinux := -T LDFLAGS_vmlinux := -T
CFLAGS_misc.o += -fPIC
hostprogs-y := relocs hostprogs-y := relocs
CFLAGS := -m32 -D__KERNEL__ $(LINUX_INCLUDE) -O2 \
-fno-strict-aliasing -fPIC \
$(call cc-option,-ffreestanding) \
$(call cc-option,-fno-stack-protector)
LDFLAGS := -m elf_i386
$(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE $(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
$(call if_changed,ld) $(call if_changed,ld)
@: @:
......
/* /*
* Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 1991, 1992 Linus Torvalds
* Copyright (C) 1997 Martin Mares * Copyright (C) 1997 Martin Mares
* Copyright (C) 2007 H. Peter Anvin
*/ */
/* /*
* This file builds a disk-image from three different files: * This file builds a disk-image from three different files:
* *
* - bootsect: compatibility mbr which prints an error message if
* someone tries to boot the kernel directly.
* - setup: 8086 machine code, sets up system parm * - setup: 8086 machine code, sets up system parm
* - system: 80386 code for actual system * - system: 80386 code for actual system
* *
...@@ -21,6 +20,7 @@ ...@@ -21,6 +20,7 @@
* High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
* Cross compiling fixes by Gertjan van Wingerde, July 1996 * Cross compiling fixes by Gertjan van Wingerde, July 1996
* Rewritten by Martin Mares, April 1997 * Rewritten by Martin Mares, April 1997
* Substantially overhauled by H. Peter Anvin, April 2007
*/ */
#include <stdio.h> #include <stdio.h>
...@@ -32,23 +32,25 @@ ...@@ -32,23 +32,25 @@
#include <sys/sysmacros.h> #include <sys/sysmacros.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/mman.h>
#include <asm/boot.h> #include <asm/boot.h>
typedef unsigned char byte; typedef unsigned char u8;
typedef unsigned short word; typedef unsigned short u16;
typedef unsigned long u32; typedef unsigned long u32;
#define DEFAULT_MAJOR_ROOT 0 #define DEFAULT_MAJOR_ROOT 0
#define DEFAULT_MINOR_ROOT 0 #define DEFAULT_MINOR_ROOT 0
/* Minimal number of setup sectors (see also bootsect.S) */ /* Minimal number of setup sectors */
#define SETUP_SECTS 4 #define SETUP_SECT_MIN 5
#define SETUP_SECT_MAX 64
byte buf[1024]; /* This must be large enough to hold the entire setup */
int fd; u8 buf[SETUP_SECT_MAX*512];
int is_big_kernel; int is_big_kernel;
void die(const char * str, ...) static void die(const char * str, ...)
{ {
va_list args; va_list args;
va_start(args, str); va_start(args, str);
...@@ -57,15 +59,9 @@ void die(const char * str, ...) ...@@ -57,15 +59,9 @@ void die(const char * str, ...)
exit(1); exit(1);
} }
void file_open(const char *name) static void usage(void)
{ {
if ((fd = open(name, O_RDONLY, 0)) < 0) die("Usage: build [-b] setup system [rootdev] [> image]");
die("Unable to open `%s': %m", name);
}
void usage(void)
{
die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
} }
int main(int argc, char ** argv) int main(int argc, char ** argv)
...@@ -73,27 +69,30 @@ int main(int argc, char ** argv) ...@@ -73,27 +69,30 @@ int main(int argc, char ** argv)
unsigned int i, sz, setup_sectors; unsigned int i, sz, setup_sectors;
int c; int c;
u32 sys_size; u32 sys_size;
byte major_root, minor_root; u8 major_root, minor_root;
struct stat sb; struct stat sb;
FILE *file;
int fd;
void *kernel;
if (argc > 2 && !strcmp(argv[1], "-b")) if (argc > 2 && !strcmp(argv[1], "-b"))
{ {
is_big_kernel = 1; is_big_kernel = 1;
argc--, argv++; argc--, argv++;
} }
if ((argc < 4) || (argc > 5)) if ((argc < 3) || (argc > 4))
usage(); usage();
if (argc > 4) { if (argc > 3) {
if (!strcmp(argv[4], "CURRENT")) { if (!strcmp(argv[3], "CURRENT")) {
if (stat("/", &sb)) { if (stat("/", &sb)) {
perror("/"); perror("/");
die("Couldn't stat /"); die("Couldn't stat /");
} }
major_root = major(sb.st_dev); major_root = major(sb.st_dev);
minor_root = minor(sb.st_dev); minor_root = minor(sb.st_dev);
} else if (strcmp(argv[4], "FLOPPY")) { } else if (strcmp(argv[3], "FLOPPY")) {
if (stat(argv[4], &sb)) { if (stat(argv[3], &sb)) {
perror(argv[4]); perror(argv[3]);
die("Couldn't stat root device."); die("Couldn't stat root device.");
} }
major_root = major(sb.st_rdev); major_root = major(sb.st_rdev);
...@@ -108,79 +107,62 @@ int main(int argc, char ** argv) ...@@ -108,79 +107,62 @@ int main(int argc, char ** argv)
} }
fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root); fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
file_open(argv[1]); /* Copy the setup code */
i = read(fd, buf, sizeof(buf)); file = fopen(argv[1], "r");
fprintf(stderr,"Boot sector %d bytes.\n",i); if (!file)
if (i != 512) die("Unable to open `%s': %m", argv[1]);
die("Boot block must be exactly 512 bytes"); c = fread(buf, 1, sizeof(buf), file);
if (ferror(file))
die("read-error on `setup'");
if (c < 1024)
die("The setup must be at least 1024 bytes");
if (buf[510] != 0x55 || buf[511] != 0xaa) if (buf[510] != 0x55 || buf[511] != 0xaa)
die("Boot block hasn't got boot flag (0xAA55)"); die("Boot block hasn't got boot flag (0xAA55)");
fclose(file);
/* Pad unused space with zeros */
setup_sectors = (c + 511) / 512;
if (setup_sectors < SETUP_SECT_MIN)
setup_sectors = SETUP_SECT_MIN;
i = setup_sectors*512;
memset(buf+c, 0, i-c);
/* Set the default root device */
buf[508] = minor_root; buf[508] = minor_root;
buf[509] = major_root; buf[509] = major_root;
if (write(1, buf, 512) != 512)
die("Write call failed");
close (fd);
file_open(argv[2]); /* Copy the setup code */
for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
if (write(1, buf, c) != c)
die("Write call failed");
if (c != 0)
die("read-error on `setup'");
close (fd);
setup_sectors = (i + 511) / 512; /* Pad unused space with zeros */
/* for compatibility with ancient versions of LILO. */
if (setup_sectors < SETUP_SECTS)
setup_sectors = SETUP_SECTS;
fprintf(stderr, "Setup is %d bytes.\n", i);
memset(buf, 0, sizeof(buf));
while (i < setup_sectors * 512) {
c = setup_sectors * 512 - i;
if (c > sizeof(buf))
c = sizeof(buf);
if (write(1, buf, c) != c)
die("Write call failed");
i += c;
}
file_open(argv[3]); fprintf(stderr, "Setup is %d bytes (padded to %d bytes).\n", c, i);
if (fstat (fd, &sb))
die("Unable to stat `%s': %m", argv[3]); /* Open and stat the kernel file */
fd = open(argv[2], O_RDONLY);
if (fd < 0)
die("Unable to open `%s': %m", argv[2]);
if (fstat(fd, &sb))
die("Unable to stat `%s': %m", argv[2]);
sz = sb.st_size; sz = sb.st_size;
fprintf (stderr, "System is %d kB\n", sz/1024); fprintf (stderr, "System is %d kB\n", (sz+1023)/1024);
kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
if (kernel == MAP_FAILED)
die("Unable to mmap '%s': %m", argv[2]);
sys_size = (sz + 15) / 16; sys_size = (sz + 15) / 16;
if (!is_big_kernel && sys_size > DEF_SYSSIZE) if (!is_big_kernel && sys_size > DEF_SYSSIZE)
die("System is too big. Try using bzImage or modules."); die("System is too big. Try using bzImage or modules.");
while (sz > 0) {
int l, n; /* Patch the setup code with the appropriate size parameters */
buf[0x1f1] = setup_sectors-1;
l = (sz > sizeof(buf)) ? sizeof(buf) : sz; buf[0x1f4] = sys_size;
if ((n=read(fd, buf, l)) != l) { buf[0x1f5] = sys_size >> 8;
if (n < 0) buf[0x1f6] = sys_size >> 16;
die("Error reading %s: %m", argv[3]); buf[0x1f7] = sys_size >> 24;
else
die("%s: Unexpected EOF", argv[3]); if (fwrite(buf, 1, i, stdout) != i)
} die("Writing setup failed");
if (write(1, buf, l) != l)
die("Write failed"); /* Copy the kernel code */
sz -= l; if (fwrite(kernel, 1, sz, stdout) != sz)
} die("Writing kernel failed");
close(fd); close(fd);
if (lseek(1, 497, SEEK_SET) != 497) /* Write sizes to the bootsector */ /* Everything is OK */
die("Output: seek failed"); return 0;
buf[0] = setup_sectors;
if (write(1, buf, 1) != 1)
die("Write of setup sector count failed");
if (lseek(1, 500, SEEK_SET) != 500)
die("Output: seek failed");
buf[0] = (sys_size & 0xff);
buf[1] = ((sys_size >> 8) & 0xff);
buf[2] = ((sys_size >> 16) & 0xff);
buf[3] = ((sys_size >> 24) & 0xff);
if (write(1, buf, 4) != 4)
die("Write of image length failed");
return 0; /* Everything is OK */
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment