Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Yinghai Lu and committed by
H. Peter Anvin
8fee13a4 f4ed2877

+105 -29
+2 -2
arch/x86/boot/compressed/Makefile
··· 4 4 # create a compressed vmlinux image from the original vmlinux 5 5 # 6 6 7 - targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.lzo head_$(BITS).o misc.o piggy.o 7 + targets := 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 9 9 KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 10 10 KBUILD_CFLAGS += -fno-strict-aliasing -fPIC ··· 23 23 24 24 hostprogs-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 27 $(call if_changed,ld) 28 28 @: 29 29
+21
arch/x86/boot/compressed/cmdline.c
··· 1 + #include "misc.h" 2 + 3 + static unsigned long fs; 4 + static inline void set_fs(unsigned long seg) 5 + { 6 + fs = seg << 4; /* shift it back */ 7 + } 8 + typedef unsigned long addr_t; 9 + static inline char rdfs8(addr_t addr) 10 + { 11 + return *((char *)(fs + addr)); 12 + } 13 + #include "../cmdline.c" 14 + int 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 + } 18 + int cmdline_find_option_bool(const char *option) 19 + { 20 + return __cmdline_find_option_bool(real_mode->hdr.cmd_line_ptr, option); 21 + }
+5
arch/x86/boot/compressed/early_serial_console.c
··· 1 + #include "misc.h" 2 + 3 + int early_serial_base; 4 + 5 + #include "../early_serial_console.c"
+33 -23
arch/x86/boot/compressed/misc.c
··· 9 9 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 10 10 */ 11 11 12 - /* 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> 12 + #include "misc.h" 29 13 30 14 /* WARNING!! 31 15 * This code is compiled with -fPIC and it is relocated dynamically ··· 107 123 /* 108 124 * This is set up by the setup-routine at boot-time 109 125 */ 110 - static struct boot_params *real_mode; /* Pointer to real-mode data */ 126 + struct boot_params *real_mode; /* Pointer to real-mode data */ 111 127 static int quiet; 128 + static int debug; 112 129 113 130 void *memset(void *s, int c, size_t n); 114 131 void *memcpy(void *dest, const void *src, size_t n); 115 - 116 - static void __putstr(int, const char *); 117 - #define putstr(__x) __putstr(0, __x) 118 132 119 133 #ifdef CONFIG_X86_64 120 134 #define memptr long ··· 152 170 vidmem[i] = ' '; 153 171 } 154 172 155 - static void __putstr(int error, const char *s) 173 + #define XMTRDY 0x20 174 + 175 + #define TXR 0 /* Transmit register (WRITE) */ 176 + #define LSR 5 /* Line Status */ 177 + static void serial_putchar(int ch) 178 + { 179 + unsigned timeout = 0xffff; 180 + 181 + while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout) 182 + cpu_relax(); 183 + 184 + outb(ch, early_serial_base + TXR); 185 + } 186 + 187 + void __putstr(int error, const char *s) 156 188 { 157 189 int x, y, pos; 158 190 char c; ··· 175 179 if (!error) 176 180 return; 177 181 #endif 182 + if (early_serial_base) { 183 + const char *str = s; 184 + while (*str) { 185 + if (*str == '\n') 186 + serial_putchar('\r'); 187 + serial_putchar(*str++); 188 + } 189 + } 178 190 179 191 if (real_mode->screen_info.orig_video_mode == 0 && 180 192 lines == 0 && cols == 0) ··· 309 305 { 310 306 real_mode = rmode; 311 307 312 - if (real_mode->hdr.loadflags & QUIET_FLAG) 308 + if (cmdline_find_option_bool("quiet")) 313 309 quiet = 1; 310 + if (cmdline_find_option_bool("debug")) 311 + debug = 1; 314 312 315 313 if (real_mode->screen_info.orig_video_mode == 7) { 316 314 vidmem = (char *) 0xb0000; ··· 324 318 325 319 lines = real_mode->screen_info.orig_video_lines; 326 320 cols = real_mode->screen_info.orig_video_cols; 321 + 322 + console_init(); 323 + if (debug) 324 + putstr("early console in decompress_kernel\n"); 327 325 328 326 free_mem_ptr = heap; /* Heap */ 329 327 free_mem_end_ptr = heap + BOOT_HEAP_SIZE;
+38
arch/x86/boot/compressed/misc.h
··· 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 */ 25 + extern struct boot_params *real_mode; /* Pointer to real-mode data */ 26 + void __putstr(int error, const char *s); 27 + #define putstr(__x) __putstr(0, __x) 28 + #define puts(__x) __putstr(0, __x) 29 + 30 + /* cmdline.c */ 31 + int cmdline_find_option(const char *option, char *buffer, int bufsize); 32 + int cmdline_find_option_bool(const char *option); 33 + 34 + /* early_serial_console.c */ 35 + extern int early_serial_base; 36 + void console_init(void); 37 + 38 + #endif
+4
arch/x86/boot/compressed/string.c
··· 1 + #include "misc.h" 2 + 3 + #include "../isdigit.h" 4 + #include "../string.c"
+2 -4
arch/x86/boot/main.c
··· 132 132 133 133 /* Initialize the early-boot console */ 134 134 console_init(); 135 + if (cmdline_find_option_bool("debug")) 136 + puts("early console in setup code\n"); 135 137 136 138 /* End of heap check */ 137 139 init_heap(); ··· 172 170 173 171 /* Set the video mode */ 174 172 set_video(); 175 - 176 - /* Parse command line for 'quiet' and pass it to decompressor. */ 177 - if (cmdline_find_option_bool("quiet")) 178 - boot_params.hdr.loadflags |= QUIET_FLAG; 179 173 180 174 /* Do the last things and invoke protected mode */ 181 175 go_to_protected_mode();