aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/boot
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2010-08-02 19:21:22 -0400
committerH. Peter Anvin <hpa@zytor.com>2010-08-02 23:32:20 -0400
commit8fee13a48e4879fba57725f6d9513df4bfa8e9f3 (patch)
tree77a12d8f6b5feb8991e2816bb065c48021a8f8bc /arch/x86/boot
parentf4ed2877b16e8146427306aea8819adac5c88374 (diff)
x86, setup: enable early console output from the decompressor
This enables the decompressor output to be seen on the serial console. Most of the code is shared with the regular boot code. We could add printf to the decompressor if needed, but currently there is no sufficiently compelling user. -v2: define BOOT_BOOT_H to avoid include boot.h -v3: early_serial_base need to be static in misc.c ? -v4: create seperate string.c printf.c cmdline.c early_serial_console.c after hpa's patch that allow global variables in compressed/misc stage -v5: remove printf.c related Signed-off-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86/boot')
-rw-r--r--arch/x86/boot/compressed/Makefile4
-rw-r--r--arch/x86/boot/compressed/cmdline.c21
-rw-r--r--arch/x86/boot/compressed/early_serial_console.c5
-rw-r--r--arch/x86/boot/compressed/misc.c56
-rw-r--r--arch/x86/boot/compressed/misc.h38
-rw-r--r--arch/x86/boot/compressed/string.c4
-rw-r--r--arch/x86/boot/main.c6
7 files changed, 105 insertions, 29 deletions
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index fbb47daf2459..0c229551eead 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -4,7 +4,7 @@
4# create a compressed vmlinux image from the original vmlinux 4# create a compressed vmlinux image from the original vmlinux
5# 5#
6 6
7targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.lzo head_$(BITS).o misc.o piggy.o 7targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.lzo head_$(BITS).o misc.o string.o cmdline.o early_serial_console.o piggy.o
8 8
9KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 9KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
10KBUILD_CFLAGS += -fno-strict-aliasing -fPIC 10KBUILD_CFLAGS += -fno-strict-aliasing -fPIC
@@ -23,7 +23,7 @@ LDFLAGS_vmlinux := -T
23 23
24hostprogs-y := mkpiggy 24hostprogs-y := mkpiggy
25 25
26$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/piggy.o FORCE 26$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/string.o $(obj)/cmdline.o $(obj)/early_serial_console.o $(obj)/piggy.o FORCE
27 $(call if_changed,ld) 27 $(call if_changed,ld)
28 @: 28 @:
29 29
diff --git a/arch/x86/boot/compressed/cmdline.c b/arch/x86/boot/compressed/cmdline.c
new file mode 100644
index 000000000000..cb62f786990d
--- /dev/null
+++ b/arch/x86/boot/compressed/cmdline.c
@@ -0,0 +1,21 @@
1#include "misc.h"
2
3static unsigned long fs;
4static inline void set_fs(unsigned long seg)
5{
6 fs = seg << 4; /* shift it back */
7}
8typedef unsigned long addr_t;
9static inline char rdfs8(addr_t addr)
10{
11 return *((char *)(fs + addr));
12}
13#include "../cmdline.c"
14int cmdline_find_option(const char *option, char *buffer, int bufsize)
15{
16 return __cmdline_find_option(real_mode->hdr.cmd_line_ptr, option, buffer, bufsize);
17}
18int cmdline_find_option_bool(const char *option)
19{
20 return __cmdline_find_option_bool(real_mode->hdr.cmd_line_ptr, option);
21}
diff --git a/arch/x86/boot/compressed/early_serial_console.c b/arch/x86/boot/compressed/early_serial_console.c
new file mode 100644
index 000000000000..261e81fb9582
--- /dev/null
+++ b/arch/x86/boot/compressed/early_serial_console.c
@@ -0,0 +1,5 @@
1#include "misc.h"
2
3int early_serial_base;
4
5#include "../early_serial_console.c"
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index 51e240779a44..8f7bef8e9fff 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -9,23 +9,7 @@
9 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 9 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
10 */ 10 */
11 11
12/* 12#include "misc.h"
13 * we have to be careful, because no indirections are allowed here, and
14 * paravirt_ops is a kind of one. As it will only run in baremetal anyway,
15 * we just keep it from happening
16 */
17#undef CONFIG_PARAVIRT
18#ifdef CONFIG_X86_32
19#define _ASM_X86_DESC_H 1
20#endif
21
22#include <linux/linkage.h>
23#include <linux/screen_info.h>
24#include <linux/elf.h>
25#include <linux/io.h>
26#include <asm/page.h>
27#include <asm/boot.h>
28#include <asm/bootparam.h>
29 13
30/* WARNING!! 14/* WARNING!!
31 * This code is compiled with -fPIC and it is relocated dynamically 15 * This code is compiled with -fPIC and it is relocated dynamically
@@ -123,15 +107,13 @@ static void error(char *m);
123/* 107/*
124 * This is set up by the setup-routine at boot-time 108 * This is set up by the setup-routine at boot-time
125 */ 109 */
126static struct boot_params *real_mode; /* Pointer to real-mode data */ 110struct boot_params *real_mode; /* Pointer to real-mode data */
127static int quiet; 111static int quiet;
112static int debug;
128 113
129void *memset(void *s, int c, size_t n); 114void *memset(void *s, int c, size_t n);
130void *memcpy(void *dest, const void *src, size_t n); 115void *memcpy(void *dest, const void *src, size_t n);
131 116
132static void __putstr(int, const char *);
133#define putstr(__x) __putstr(0, __x)
134
135#ifdef CONFIG_X86_64 117#ifdef CONFIG_X86_64
136#define memptr long 118#define memptr long
137#else 119#else
@@ -170,7 +152,21 @@ static void scroll(void)
170 vidmem[i] = ' '; 152 vidmem[i] = ' ';
171} 153}
172 154
173static void __putstr(int error, const char *s) 155#define XMTRDY 0x20
156
157#define TXR 0 /* Transmit register (WRITE) */
158#define LSR 5 /* Line Status */
159static void serial_putchar(int ch)
160{
161 unsigned timeout = 0xffff;
162
163 while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout)
164 cpu_relax();
165
166 outb(ch, early_serial_base + TXR);
167}
168
169void __putstr(int error, const char *s)
174{ 170{
175 int x, y, pos; 171 int x, y, pos;
176 char c; 172 char c;
@@ -179,6 +175,14 @@ static void __putstr(int error, const char *s)
179 if (!error) 175 if (!error)
180 return; 176 return;
181#endif 177#endif
178 if (early_serial_base) {
179 const char *str = s;
180 while (*str) {
181 if (*str == '\n')
182 serial_putchar('\r');
183 serial_putchar(*str++);
184 }
185 }
182 186
183 if (real_mode->screen_info.orig_video_mode == 0 && 187 if (real_mode->screen_info.orig_video_mode == 0 &&
184 lines == 0 && cols == 0) 188 lines == 0 && cols == 0)
@@ -305,8 +309,10 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,
305{ 309{
306 real_mode = rmode; 310 real_mode = rmode;
307 311
308 if (real_mode->hdr.loadflags & QUIET_FLAG) 312 if (cmdline_find_option_bool("quiet"))
309 quiet = 1; 313 quiet = 1;
314 if (cmdline_find_option_bool("debug"))
315 debug = 1;
310 316
311 if (real_mode->screen_info.orig_video_mode == 7) { 317 if (real_mode->screen_info.orig_video_mode == 7) {
312 vidmem = (char *) 0xb0000; 318 vidmem = (char *) 0xb0000;
@@ -319,6 +325,10 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,
319 lines = real_mode->screen_info.orig_video_lines; 325 lines = real_mode->screen_info.orig_video_lines;
320 cols = real_mode->screen_info.orig_video_cols; 326 cols = real_mode->screen_info.orig_video_cols;
321 327
328 console_init();
329 if (debug)
330 putstr("early console in decompress_kernel\n");
331
322 free_mem_ptr = heap; /* Heap */ 332 free_mem_ptr = heap; /* Heap */
323 free_mem_end_ptr = heap + BOOT_HEAP_SIZE; 333 free_mem_end_ptr = heap + BOOT_HEAP_SIZE;
324 334
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
new file mode 100644
index 000000000000..a267849ac1c9
--- /dev/null
+++ b/arch/x86/boot/compressed/misc.h
@@ -0,0 +1,38 @@
1#ifndef BOOT_COMPRESSED_MISC_H
2#define BOOT_COMPRESSED_MISC_H
3
4/*
5 * we have to be careful, because no indirections are allowed here, and
6 * paravirt_ops is a kind of one. As it will only run in baremetal anyway,
7 * we just keep it from happening
8 */
9#undef CONFIG_PARAVIRT
10#ifdef CONFIG_X86_32
11#define _ASM_X86_DESC_H 1
12#endif
13
14#include <linux/linkage.h>
15#include <linux/screen_info.h>
16#include <linux/elf.h>
17#include <linux/io.h>
18#include <asm/page.h>
19#include <asm/boot.h>
20#include <asm/bootparam.h>
21
22#define BOOT_BOOT_H
23
24/* misc.c */
25extern struct boot_params *real_mode; /* Pointer to real-mode data */
26void __putstr(int error, const char *s);
27#define putstr(__x) __putstr(0, __x)
28#define puts(__x) __putstr(0, __x)
29
30/* cmdline.c */
31int cmdline_find_option(const char *option, char *buffer, int bufsize);
32int cmdline_find_option_bool(const char *option);
33
34/* early_serial_console.c */
35extern int early_serial_base;
36void console_init(void);
37
38#endif
diff --git a/arch/x86/boot/compressed/string.c b/arch/x86/boot/compressed/string.c
new file mode 100644
index 000000000000..7995c6a49509
--- /dev/null
+++ b/arch/x86/boot/compressed/string.c
@@ -0,0 +1,4 @@
1#include "misc.h"
2
3#include "../isdigit.h"
4#include "../string.c"
diff --git a/arch/x86/boot/main.c b/arch/x86/boot/main.c
index 4ef1a33e8572..40358c8905be 100644
--- a/arch/x86/boot/main.c
+++ b/arch/x86/boot/main.c
@@ -132,6 +132,8 @@ void main(void)
132 132
133 /* Initialize the early-boot console */ 133 /* Initialize the early-boot console */
134 console_init(); 134 console_init();
135 if (cmdline_find_option_bool("debug"))
136 puts("early console in setup code\n");
135 137
136 /* End of heap check */ 138 /* End of heap check */
137 init_heap(); 139 init_heap();
@@ -171,10 +173,6 @@ void main(void)
171 /* Set the video mode */ 173 /* Set the video mode */
172 set_video(); 174 set_video();
173 175
174 /* Parse command line for 'quiet' and pass it to decompressor. */
175 if (cmdline_find_option_bool("quiet"))
176 boot_params.hdr.loadflags |= QUIET_FLAG;
177
178 /* Do the last things and invoke protected mode */ 176 /* Do the last things and invoke protected mode */
179 go_to_protected_mode(); 177 go_to_protected_mode();
180} 178}