Skip to content

Commit

Permalink
Merge branch 'x86/setup' into x86/devel
Browse files Browse the repository at this point in the history
  • Loading branch information
Ingo Molnar committed Jul 8, 2008
2 parents 6924d1a + 6bcb13b commit 3c1ca43
Show file tree
Hide file tree
Showing 20 changed files with 209 additions and 147 deletions.
File renamed without changes.
79 changes: 46 additions & 33 deletions Documentation/i386/boot.txt → Documentation/x86/i386/boot.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
THE LINUX/I386 BOOT PROTOCOL
----------------------------
THE LINUX/x86 BOOT PROTOCOL
---------------------------

H. Peter Anvin <hpa@zytor.com>
Last update 2007-05-23

On the i386 platform, the Linux kernel uses a rather complicated boot
On the x86 platform, the Linux kernel uses a rather complicated boot
convention. This has evolved partially due to historical aspects, as
well as the desire in the early days to have the kernel itself be a
bootable image, the complicated PC memory model and due to changed
expectations in the PC industry caused by the effective demise of
real-mode DOS as a mainstream operating system.

Currently, the following versions of the Linux/i386 boot protocol exist.
Currently, the following versions of the Linux/x86 boot protocol exist.

Old kernels: zImage/Image support only. Some very early kernels
may not even support a command line.
Expand Down Expand Up @@ -372,10 +369,17 @@ Protocol: 2.00+
- If 0, the protected-mode code is loaded at 0x10000.
- If 1, the protected-mode code is loaded at 0x100000.

Bit 5 (write): QUIET_FLAG
- If 0, print early messages.
- If 1, suppress early messages.
This requests to the kernel (decompressor and early
kernel) to not write early messages that require
accessing the display hardware directly.

Bit 6 (write): KEEP_SEGMENTS
Protocol: 2.07+
- if 0, reload the segment registers in the 32bit entry point.
- if 1, do not reload the segment registers in the 32bit entry point.
- If 0, reload the segment registers in the 32bit entry point.
- If 1, do not reload the segment registers in the 32bit entry point.
Assume that %cs %ds %ss %es are all set to flat segments with
a base of 0 (or the equivalent for their environment).

Expand Down Expand Up @@ -504,7 +508,7 @@ Protocol: 2.06+
maximum size was 255.

Field name: hardware_subarch
Type: write
Type: write (optional, defaults to x86/PC)
Offset/size: 0x23c/4
Protocol: 2.07+

Expand All @@ -520,11 +524,13 @@ Protocol: 2.07+
0x00000002 Xen

Field name: hardware_subarch_data
Type: write
Type: write (subarch-dependent)
Offset/size: 0x240/8
Protocol: 2.07+

A pointer to data that is specific to hardware subarch
This field is currently unused for the default x86/PC environment,
do not modify.

Field name: payload_offset
Type: read
Expand All @@ -545,6 +551,34 @@ Protocol: 2.08+

The length of the payload.

Field name: setup_data
Type: write (special)
Offset/size: 0x250/8
Protocol: 2.09+

The 64-bit physical pointer to NULL terminated single linked list of
struct setup_data. This is used to define a more extensible boot
parameters passing mechanism. The definition of struct setup_data is
as follow:

struct setup_data {
u64 next;
u32 type;
u32 len;
u8 data[0];
};

Where, the next is a 64-bit physical pointer to the next node of
linked list, the next field of the last node is 0; the type is used
to identify the contents of data; the len is the length of data
field; the data holds the real payload.

This list may be modified at a number of points during the bootup
process. Therefore, when modifying this list one should always make
sure to consider the case where the linked list already contains
entries.


**** THE IMAGE CHECKSUM

From boot protocol version 2.08 onwards the CRC-32 is calculated over
Expand All @@ -553,6 +587,7 @@ initial remainder of 0xffffffff. The checksum is appended to the
file; therefore the CRC of the file up to the limit specified in the
syssize field of the header is always 0.


**** THE KERNEL COMMAND LINE

The kernel command line has become an important way for the boot
Expand Down Expand Up @@ -584,28 +619,6 @@ command line is entered using the following protocol:
covered by setup_move_size, so you may need to adjust this
field.

Field name: setup_data
Type: write (obligatory)
Offset/size: 0x250/8
Protocol: 2.09+

The 64-bit physical pointer to NULL terminated single linked list of
struct setup_data. This is used to define a more extensible boot
parameters passing mechanism. The definition of struct setup_data is
as follow:

struct setup_data {
u64 next;
u32 type;
u32 len;
u8 data[0];
};

Where, the next is a 64-bit physical pointer to the next node of
linked list, the next field of the last node is 0; the type is used
to identify the contents of data; the len is the length of data
field; the data holds the real payload.


**** MEMORY LAYOUT OF THE REAL-MODE CODE

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
8 changes: 8 additions & 0 deletions arch/x86/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ config NONPROMISC_DEVMEM

If in doubt, say Y.

config X86_VERBOSE_BOOTUP
bool "Enable verbose x86 bootup info messages"
default y
help
Enables the informational output from the decompression stage
(e.g. bzImage) of the boot. If you disable this you will still
see errors. Disable this if you want silent bootup.

config EARLY_PRINTK
bool "Early printk" if EMBEDDED
default y
Expand Down
5 changes: 4 additions & 1 deletion arch/x86/boot/a20.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* -*- linux-c -*- ------------------------------------------------------- *
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
* Copyright 2007-2008 rPath, Inc. - All Rights Reserved
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
Expand Down Expand Up @@ -95,6 +95,9 @@ static void enable_a20_kbc(void)

outb(0xdf, 0x60); /* A20 on */
empty_8042();

outb(0xff, 0x64); /* Null command, but UHCI wants it */
empty_8042();
}

static void enable_a20_fast(void)
Expand Down
55 changes: 32 additions & 23 deletions arch/x86/boot/compressed/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <asm/io.h>
#include <asm/page.h>
#include <asm/boot.h>
#include <asm/bootparam.h>

/* WARNING!!
* This code is compiled with -fPIC and it is relocated dynamically
Expand Down Expand Up @@ -187,13 +188,8 @@ static void gzip_release(void **);
/*
* This is set up by the setup-routine at boot-time
*/
static unsigned char *real_mode; /* Pointer to real-mode data */

#define RM_EXT_MEM_K (*(unsigned short *)(real_mode + 0x2))
#ifndef STANDARD_MEMORY_BIOS_CALL
#define RM_ALT_MEM_K (*(unsigned long *)(real_mode + 0x1e0))
#endif
#define RM_SCREEN_INFO (*(struct screen_info *)(real_mode+0))
static struct boot_params *real_mode; /* Pointer to real-mode data */
static int quiet;

extern unsigned char input_data[];
extern int input_len;
Expand All @@ -206,7 +202,8 @@ static void free(void *where);
static void *memset(void *s, int c, unsigned n);
static void *memcpy(void *dest, const void *src, unsigned n);

static void putstr(const char *);
static void __putstr(int, const char *);
#define putstr(__x) __putstr(0, __x)

#ifdef CONFIG_X86_64
#define memptr long
Expand Down Expand Up @@ -270,18 +267,24 @@ static void scroll(void)
vidmem[i] = ' ';
}

static void putstr(const char *s)
static void __putstr(int error, const char *s)
{
int x, y, pos;
char c;

#ifndef CONFIG_X86_VERBOSE_BOOTUP
if (!error)
return;
#endif

#ifdef CONFIG_X86_32
if (RM_SCREEN_INFO.orig_video_mode == 0 && lines == 0 && cols == 0)
if (real_mode->screen_info.orig_video_mode == 0 &&
lines == 0 && cols == 0)
return;
#endif

x = RM_SCREEN_INFO.orig_x;
y = RM_SCREEN_INFO.orig_y;
x = real_mode->screen_info.orig_x;
y = real_mode->screen_info.orig_y;

while ((c = *s++) != '\0') {
if (c == '\n') {
Expand All @@ -302,8 +305,8 @@ static void putstr(const char *s)
}
}

RM_SCREEN_INFO.orig_x = x;
RM_SCREEN_INFO.orig_y = y;
real_mode->screen_info.orig_x = x;
real_mode->screen_info.orig_y = y;

pos = (x + cols * y) * 2; /* Update cursor position */
outb(14, vidport);
Expand Down Expand Up @@ -366,9 +369,9 @@ static void flush_window(void)

static void error(char *x)
{
putstr("\n\n");
putstr(x);
putstr("\n\n -- System halted");
__putstr(1, "\n\n");
__putstr(1, x);
__putstr(1, "\n\n -- System halted");

while (1)
asm("hlt");
Expand All @@ -395,7 +398,8 @@ static void parse_elf(void *output)
return;
}

putstr("Parsing ELF... ");
if (!quiet)
putstr("Parsing ELF... ");

phdrs = malloc(sizeof(*phdrs) * ehdr.e_phnum);
if (!phdrs)
Expand Down Expand Up @@ -430,16 +434,19 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,
{
real_mode = rmode;

if (RM_SCREEN_INFO.orig_video_mode == 7) {
if (real_mode->hdr.loadflags & QUIET_FLAG)
quiet = 1;

if (real_mode->screen_info.orig_video_mode == 7) {
vidmem = (char *) 0xb0000;
vidport = 0x3b4;
} else {
vidmem = (char *) 0xb8000;
vidport = 0x3d4;
}

lines = RM_SCREEN_INFO.orig_video_lines;
cols = RM_SCREEN_INFO.orig_video_cols;
lines = real_mode->screen_info.orig_video_lines;
cols = real_mode->screen_info.orig_video_cols;

window = output; /* Output buffer (Normally at 1M) */
free_mem_ptr = heap; /* Heap */
Expand All @@ -465,9 +472,11 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,
#endif

makecrc();
putstr("\nDecompressing Linux... ");
if (!quiet)
putstr("\nDecompressing Linux... ");
gunzip();
parse_elf(output);
putstr("done.\nBooting the kernel.\n");
if (!quiet)
putstr("done.\nBooting the kernel.\n");
return;
}
Loading

0 comments on commit 3c1ca43

Please sign in to comment.