From: "Eric W. Biederman" <ebiederm@xmission.com>
To: <fastboot@osdl.org>
Cc: <linux-kernel@vger.kernel.org>, Horms <horms@verge.net.au>,
Jan Kratochvil <lace@jankratochvil.net>,
"H. Peter Anvin" <hpa@zytor.com>,
Magnus Damm <magnus.damm@gmail.com>,
Vivek Goyal <vgoyal@in.ibm.com>, Linda Wang <lwang@redhat.com>,
"Eric W. Biederman" <ebiederm@xmission.com>
Subject: [PATCH 9/33] i386 boot: Add serial output support to the decompressor
Date: Tue, 1 Aug 2006 05:03:24 -0600 [thread overview]
Message-ID: <115443023544-git-send-email-ebiederm@xmission.com> (raw)
In-Reply-To: <m1d5bk2046.fsf@ebiederm.dsl.xmission.com>
This patch does two very simple things.
It adds a serial output capability to the decompressor.
It adds a command line parser for the early_printk
option so we know which output method to use for the decompressor.
This makes debugging the decompressor a little easier, and
keeps us from assuming we always have a vga console on all
hardware.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/i386/boot/compressed/misc.c | 258 +++++++++++++++++++++++++++++++++++---
1 files changed, 241 insertions(+), 17 deletions(-)
diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c
index 905c37e..fcaa9f0 100644
--- a/arch/i386/boot/compressed/misc.c
+++ b/arch/i386/boot/compressed/misc.c
@@ -9,11 +9,14 @@
* High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
*/
+#define __init
#include <linux/config.h>
#include <linux/linkage.h>
#include <linux/vmalloc.h>
+#include <linux/serial_reg.h>
#include <linux/screen_info.h>
#include <asm/io.h>
+#include <asm/setup.h>
/*
* gzip declarations
@@ -24,7 +27,9 @@ #define STATIC static
#undef memset
#undef memcpy
+#undef memcmp
#define memzero(s, n) memset ((s), 0, (n))
+char *strstr(const char *haystack, const char *needle);
typedef unsigned char uch;
typedef unsigned short ush;
@@ -78,12 +83,17 @@ 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 */
+static char saved_command_line[COMMAND_LINE_SIZE];
#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))
+#define RM_NEW_CL_POINTER ((char *)(unsigned long)(*(unsigned *)(real_mode+0x228)))
+#define RM_OLD_CL_MAGIC (*(unsigned short *)(real_mode + 0x20))
+#define RM_OLD_CL_OFFSET (*(unsigned short *)(real_mode + 0x22))
+#define OLD_CL_MAGIC 0xA33F
extern unsigned char input_data[];
extern int input_len;
@@ -97,8 +107,10 @@ 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 int memcmp(const void *s1, const void *s2, unsigned n);
static void putstr(const char *);
+static unsigned simple_strtou(const char *cp,char **endp,unsigned base);
extern int end;
static long free_mem_ptr = (long)&end;
@@ -112,14 +124,25 @@ static unsigned int low_buffer_end, low_
static int high_loaded =0;
static uch *high_buffer_start /* = (uch *)(((ulg)&end) + HEAP_SIZE)*/;
-static char *vidmem = (char *)0xb8000;
+static char *vidmem;
static int vidport;
static int lines, cols;
#ifdef CONFIG_X86_NUMAQ
-static void * xquad_portio = NULL;
+static void * xquad_portio;
#endif
+/* The early serial console */
+
+#define DEFAULT_BAUD 9600
+#define DEFAULT_BASE 0x3f8 /* ttyS0 */
+static unsigned serial_base = DEFAULT_BASE;
+
+#define CONSOLE_NOOP 0
+#define CONSOLE_VID 1
+#define CONSOLE_SERIAL 2
+static int console = CONSOLE_NOOP;
+
#include "../../../../lib/inflate.c"
static void *malloc(int size)
@@ -154,7 +177,8 @@ static void gzip_release(void **ptr)
free_mem_ptr = (long) *ptr;
}
-static void scroll(void)
+/* The early video console */
+static void vid_scroll(void)
{
int i;
@@ -163,7 +187,7 @@ static void scroll(void)
vidmem[i] = ' ';
}
-static void putstr(const char *s)
+static void vid_putstr(const char *s)
{
int x,y,pos;
char c;
@@ -175,7 +199,7 @@ static void putstr(const char *s)
if ( c == '\n' ) {
x = 0;
if ( ++y >= lines ) {
- scroll();
+ vid_scroll();
y--;
}
} else {
@@ -183,7 +207,7 @@ static void putstr(const char *s)
if ( ++x >= cols ) {
x = 0;
if ( ++y >= lines ) {
- scroll();
+ vid_scroll();
y--;
}
}
@@ -200,6 +224,178 @@ static void putstr(const char *s)
outb_p(0xff & (pos >> 1), vidport+1);
}
+static void vid_console_init(void)
+{
+ if (RM_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;
+}
+
+/* The early serial console */
+static void serial_putc(int ch)
+{
+ if (ch == '\n') {
+ serial_putc('\r');
+ }
+ /* Wait until I can send a byte */
+ while ((inb(serial_base + UART_LSR) & UART_LSR_THRE) == 0)
+ ;
+
+ /* Send the byte */
+ outb(ch, serial_base + UART_TX);
+
+ /* Wait until the byte is transmitted */
+ while (!(inb(serial_base + UART_LSR) & UART_LSR_TEMT))
+ ;
+}
+
+static void serial_putstr(const char *str)
+{
+ int ch;
+ while((ch = *str++) != '\0') {
+ if (ch == '\n') {
+ serial_putc('\r');
+ }
+ serial_putc(ch);
+ }
+}
+
+static void serial_console_init(char *s)
+{
+ unsigned base = DEFAULT_BASE;
+ unsigned baud = DEFAULT_BAUD;
+ unsigned divisor;
+ char *e;
+
+ if (*s == ',')
+ ++s;
+ if (*s && (*s != ' ')) {
+ if (memcmp(s, "0x", 2) == 0) {
+ base = simple_strtou(s, &e, 16);
+ } else {
+ static const unsigned bases[] = { 0x3f8, 0x2f8 };
+ unsigned port;
+
+ if (memcmp(s, "ttyS", 4) == 0)
+ s += 4;
+ port = simple_strtou(s, &e, 10);
+ if ((port > 1) || (s == e))
+ port = 0;
+ base = bases[port];
+ }
+ s = e;
+ if (*s == ',')
+ ++s;
+ }
+ if (*s && (*s != ' ')) {
+ baud = simple_strtou(s, &e, 0);
+ if ((baud == 0) || (s == e))
+ baud = DEFAULT_BAUD;
+ }
+ divisor = 115200 / baud;
+ serial_base = base;
+
+ outb(0x00, serial_base + UART_IER); /* no interrupt */
+ outb(0x00, serial_base + UART_FCR); /* no fifo */
+ outb(0x03, serial_base + UART_MCR); /* DTR + RTS */
+
+ /* Set Baud Rate divisor */
+ outb(0x83, serial_base + UART_LCR);
+ outb(divisor & 0xff, serial_base + UART_DLL);
+ outb(divisor >> 8, serial_base + UART_DLM);
+ outb(0x03, serial_base + UART_LCR); /* 8n1 */
+
+}
+
+static void putstr(const char *str)
+{
+ if (console == CONSOLE_VID) {
+ vid_putstr(str);
+ } else if (console == CONSOLE_SERIAL) {
+ serial_putstr(str);
+ }
+}
+
+static void console_init(char *cmdline)
+{
+ cmdline = strstr(cmdline, "earlyprintk=");
+ if (!cmdline)
+ return;
+ cmdline += 12;
+ if (memcmp(cmdline, "vga", 3) == 0) {
+ vid_console_init();
+ console = CONSOLE_VID;
+ } else if (memcmp(cmdline, "serial", 6) == 0) {
+ serial_console_init(cmdline + 6);
+ console = CONSOLE_SERIAL;
+ } else if (memcmp(cmdline, "ttyS", 4) == 0) {
+ serial_console_init(cmdline);
+ console = CONSOLE_SERIAL;
+ }
+}
+
+static inline int tolower(int ch)
+{
+ return ch | 0x20;
+}
+
+static inline int isdigit(int ch)
+{
+ return (ch >= '0') && (ch <= '9');
+}
+
+static inline int isxdigit(int ch)
+{
+ ch = tolower(ch);
+ return isdigit(ch) || ((ch >= 'a') && (ch <= 'f'));
+}
+
+
+static inline int digval(int ch)
+{
+ return isdigit(ch)? (ch - '0') : tolower(ch) - 'a' + 10;
+}
+
+/**
+ * simple_strtou - convert a string to an unsigned
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+static unsigned simple_strtou(const char *cp, char **endp, unsigned base)
+{
+ unsigned result = 0,value;
+
+ if (!base) {
+ base = 10;
+ if (*cp == '0') {
+ base = 8;
+ cp++;
+ if ((tolower(*cp) == 'x') && isxdigit(cp[1])) {
+ cp++;
+ base = 16;
+ }
+ }
+ } else if (base == 16) {
+ if (cp[0] == '0' && tolower(cp[1]) == 'x')
+ cp += 2;
+ }
+ while (isxdigit(*cp) && ((value = digval(*cp)) < base)) {
+ result = result*base + value;
+ cp++;
+ }
+ if (endp)
+ *endp = (char *)cp;
+ return result;
+}
+
static void* memset(void* s, int c, unsigned n)
{
int i;
@@ -218,6 +414,29 @@ static void* memcpy(void* dest, const vo
return dest;
}
+static int memcmp(const void *s1, const void *s2, unsigned n)
+{
+ const unsigned char *str1 = s1, *str2 = s2;
+ size_t i;
+ int result = 0;
+ for(i = 0; (result == 0) && (i < n); i++) {
+ result = *str1++ - *str2++;
+ }
+ return result;
+}
+
+char *strstr(const char *haystack, const char *needle)
+{
+ size_t len;
+ len = strlen(needle);
+ while(*haystack) {
+ if (memcmp(haystack, needle, len) == 0)
+ return (char *)haystack;
+ haystack++;
+ }
+ return NULL;
+}
+
/* ===========================================================================
* Fill the input buffer. This is called only when the buffer is empty
* and at least one byte is really needed.
@@ -346,20 +565,25 @@ static void close_output_buffer_if_we_ru
}
}
-asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode)
+static void save_command_line(void)
{
- real_mode = rmode;
-
- if (RM_SCREEN_INFO.orig_video_mode == 7) {
- vidmem = (char *) 0xb0000;
- vidport = 0x3b4;
- } else {
- vidmem = (char *) 0xb8000;
- vidport = 0x3d4;
+ /* Find the command line */
+ char *cmdline;
+ cmdline = saved_command_line;
+ if (RM_NEW_CL_POINTER) {
+ cmdline = RM_NEW_CL_POINTER;
+ } else if (OLD_CL_MAGIC == RM_OLD_CL_MAGIC) {
+ cmdline = real_mode + RM_OLD_CL_OFFSET;
}
+ memcpy(saved_command_line, cmdline, COMMAND_LINE_SIZE);
+ saved_command_line[COMMAND_LINE_SIZE - 1] = '\0';
+}
- lines = RM_SCREEN_INFO.orig_video_lines;
- cols = RM_SCREEN_INFO.orig_video_cols;
+asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode)
+{
+ real_mode = rmode;
+ save_command_line();
+ console_init(saved_command_line);
if (free_mem_ptr < 0x100000) setup_normal_output_buffer();
else setup_output_buffer_if_we_run_high(mv);
--
1.4.2.rc2.g5209e
next prev parent reply other threads:[~2006-08-01 11:09 UTC|newest]
Thread overview: 105+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-08-01 10:58 [RFC] ELF Relocatable x86 and x86_64 bzImages Eric W. Biederman
2006-08-01 11:03 ` [PATCH 1/33] i386: vmlinux.lds.S Distinguish absolute symbols Eric W. Biederman
2006-08-01 19:06 ` Sam Ravnborg
2006-08-01 11:03 ` [PATCH 2/33] i386: define __pa_symbol Eric W. Biederman
2006-08-01 19:06 ` Andi Kleen
2006-08-02 2:19 ` Eric W. Biederman
2006-08-02 3:04 ` Andi Kleen
2006-08-01 11:03 ` [PATCH 3/33] i386 setup.c: Reserve kernel memory starting from _text Eric W. Biederman
2006-08-01 11:03 ` [PATCH 4/33] i386: CONFIG_PHYSICAL_START cleanup Eric W. Biederman
2006-08-01 19:08 ` Sam Ravnborg
2006-08-02 2:23 ` Eric W. Biederman
2006-08-02 16:14 ` Eric W. Biederman
2006-08-03 14:05 ` Sam Ravnborg
2006-08-01 11:03 ` [PATCH 5/33] i386 Kconfig: Add a range definition to config PHYSICAL_START Eric W. Biederman
2006-08-01 11:03 ` [PATCH 6/33] Make linux/elf.h safe to be included in assembly files Eric W. Biederman
2006-08-01 11:03 ` [PATCH 7/33] elf: Add ELFOSABI_STANDALONE to elf.h Eric W. Biederman
2006-08-01 11:03 ` [PATCH 8/33] kallsyms.c: Generate relocatable symbols Eric W. Biederman
2006-08-01 11:36 ` Paulo Marques
2006-08-01 11:52 ` Eric W. Biederman
2006-08-01 11:03 ` Eric W. Biederman [this message]
2006-08-01 19:19 ` [PATCH 9/33] i386 boot: Add serial output support to the decompressor Andi Kleen
2006-08-02 2:30 ` Eric W. Biederman
2006-08-02 3:07 ` Andi Kleen
2006-08-02 4:57 ` Eric W. Biederman
2006-08-02 5:21 ` Andi Kleen
2006-08-02 6:44 ` Eric W. Biederman
2006-08-02 3:06 ` Eric W. Biederman
2006-08-02 3:10 ` Andi Kleen
2006-08-02 5:27 ` Eric W. Biederman
2006-08-02 5:44 ` Andi Kleen
2006-08-02 7:14 ` Eric W. Biederman
2006-08-01 11:03 ` [PATCH 10/33] i386: Relocatable kernel support Eric W. Biederman
2006-08-01 13:34 ` Mika Penttilä
2006-08-01 18:07 ` Eric W. Biederman
2006-08-01 18:11 ` Sam Ravnborg
2006-08-01 18:16 ` Mika Penttilä
2006-08-01 11:03 ` [PATCH 11/33] i386 boot: Add an ELF header to bzImage Eric W. Biederman
2006-08-01 22:10 ` Jeremy Fitzhardinge
2006-08-02 2:38 ` Eric W. Biederman
2006-08-01 11:03 ` [PATCH 12/33] x86_64: fixup indentation in e820.c Eric W. Biederman
2006-08-01 11:03 ` [PATCH 13/33] x86_64: Remove assumptions about the kernel start address from e820/bad_addr() Eric W. Biederman
2006-08-01 11:03 ` [PATCH 14/33] x86_64: Properly report in /proc/iomem the kernel address Eric W. Biederman
2006-08-01 11:03 ` [PATCH 15/33] x86_64: Fix kernel direct mapping size check Eric W. Biederman
2006-08-01 11:03 ` [PATCH 16/33] x86_64: Assembly safe page.h and pgtable.h Eric W. Biederman
2006-08-01 11:03 ` [PATCH 17/33] x86_64: Separate normal memory map initialization from the hotplug case Eric W. Biederman
2006-08-01 11:03 ` [PATCH 18/33] x86_64: Kill temp_boot_pmds Eric W. Biederman
2006-08-01 19:02 ` Andi Kleen
2006-08-02 2:08 ` Eric W. Biederman
2006-08-01 19:04 ` [PATCH 18/33] x86_64: Kill temp_boot_pmds II Andi Kleen
2006-08-02 2:11 ` Eric W. Biederman
2006-08-02 3:07 ` Andi Kleen
2006-08-02 5:35 ` Eric W. Biederman
2006-08-01 11:03 ` [PATCH 19/33] x86_64: Cleanup the early boot page table Eric W. Biederman
2006-08-01 11:03 ` [PATCH 20/33] x86_64: fix early_printk to use the standard ISA mapping Eric W. Biederman
2006-08-01 11:03 ` [PATCH 21/33] x86_64: modify copy_bootdata to use virtual addresses Eric W. Biederman
2006-08-01 11:03 ` [PATCH 22/33] x86_64: Fix gdt table size in trampoline.S Eric W. Biederman
2006-08-01 18:59 ` Andi Kleen
2006-08-01 11:03 ` [PATCH 23/33] x86_64: cleanup segments Eric W. Biederman
2006-08-01 11:03 ` [PATCH 24/33] x86_64: Add EFER to the set registers saved by save_processor_state Eric W. Biederman
2006-08-01 11:03 ` [PATCH 25/33] x86_64: 64bit PIC SMP trampoline Eric W. Biederman
2006-08-01 19:13 ` Andi Kleen
2006-08-01 11:03 ` [PATCH 26/33] x86_64: 64bit PIC ACPI wakeup Eric W. Biederman
2006-08-01 19:10 ` Andi Kleen
2006-08-01 11:03 ` [PATCH 27/33] x86_64: Modify discover_ebda to use virtual addresses Eric W. Biederman
2006-08-01 11:03 ` [PATCH 28/33] x86_64: Remove the identity mapping as early as possible Eric W. Biederman
2006-08-01 19:15 ` Andi Kleen
2006-08-01 11:03 ` [PATCH 29/33] x86_64: __pa and __pa_symbol address space separation Eric W. Biederman
2006-08-01 11:03 ` [PATCH 30/33] x86_64: Remove CONFIG_PHYSICAL_START Eric W. Biederman
2006-08-01 11:03 ` [PATCH 31/33] x86_64 boot: Add serial output support to the decompressor Eric W. Biederman
2006-08-01 11:03 ` [PATCH 32/33] x86_64: Relocatable kernel support Eric W. Biederman
2006-08-01 19:11 ` Andi Kleen
2006-08-02 2:25 ` Eric W. Biederman
2006-11-05 6:02 ` Yinghai Lu
2006-11-05 6:52 ` Eric W. Biederman
2006-11-05 7:15 ` Yinghai Lu
2006-08-01 11:03 ` [PATCH 33/33] x86_64: Make bzImage a valid 64bit elf executable Eric W. Biederman
2006-08-01 19:26 ` [RFC] ELF Relocatable x86 and x86_64 bzImages Vivek Goyal
2006-08-01 20:13 ` Jan Kratochvil
2006-08-01 20:25 ` H. Peter Anvin
2006-08-02 2:02 ` Eric W. Biederman
2006-08-01 20:40 ` Vivek Goyal
2006-08-02 2:40 ` Eric W. Biederman
2006-08-02 6:34 ` Magnus Damm
2006-08-02 7:09 ` Eric W. Biederman
2006-08-02 8:34 ` Magnus Damm
2006-08-02 9:59 ` Eric W. Biederman
2006-08-02 18:37 ` [Fastboot] " Don Zickus
2006-08-03 1:00 ` Eric W. Biederman
2006-08-03 4:53 ` H. Peter Anvin
2006-08-04 22:56 ` Vivek Goyal
2006-08-04 23:14 ` Eric W. Biederman
2006-08-04 23:38 ` Dave Jones
2006-08-04 23:47 ` H. Peter Anvin
2006-08-05 8:01 ` Eric W. Biederman
2006-08-08 3:34 ` Horms
2006-08-08 4:32 ` H. Peter Anvin
2006-08-08 4:57 ` Magnus Damm
2006-08-08 5:04 ` Eric W. Biederman
2006-08-08 6:09 ` Horms
2006-08-08 7:23 ` Eric W. Biederman
2006-08-08 7:58 ` Horms
2006-08-09 14:56 ` D. Hazelton
2006-08-17 18:44 ` Vivek Goyal
2006-08-11 13:11 ` [Fastboot] " Rachita Kothiyal
2006-08-11 13:36 ` Vivek Goyal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=115443023544-git-send-email-ebiederm@xmission.com \
--to=ebiederm@xmission.com \
--cc=fastboot@osdl.org \
--cc=horms@verge.net.au \
--cc=hpa@zytor.com \
--cc=lace@jankratochvil.net \
--cc=linux-kernel@vger.kernel.org \
--cc=lwang@redhat.com \
--cc=magnus.damm@gmail.com \
--cc=vgoyal@in.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox