From: H. Peter Anvin on
On 08/02/2010 12:13 AM, Yinghai Lu wrote:
> also make main.c to include printf.c/string.c/cmdline.c

No. We don't include .c files that way.

-hpa

--
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel. I don't speak on their behalf.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: H. Peter Anvin on
On 08/02/2010 12:13 AM, Yinghai Lu wrote:
>
> Seperate early_console_setup from tty.c
> also make main.c to include printf.c/string.c/cmdline.c
>
> will reuse early_serial_console.c/string.c/printf.c/cmdline.c in compressed/misc.c
>


The way to reuse files in boot/compressed/ would be just to create .c
files in boot/compressed/ with, for example:

/* string.c */
#include "../string.c"

-hpa

--
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel. I don't speak on their behalf.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: Cyrill Gorcunov on
On Mon, Aug 02, 2010 at 12:13:31AM -0700, Yinghai Lu wrote:
>
> Seperate early_console_setup from tty.c
> also make main.c to include printf.c/string.c/cmdline.c
>
> will reuse early_serial_console.c/string.c/printf.c/cmdline.c in compressed/misc.c
>
> Signed-off-by: Yinghai Lu <yinghai(a)kernel.org>
>
> ---

Hi Yinghai, I'll try to find some time for review though it looks somehow
too 'big' for me :)

Actually by reading your initial approach (which was much smaller in size) I
thought we end up in something like the patch below, though I'll review this
seris. So just to share (I've tested it under qemu). The idea is the same as
your was, so I pushed all constant parts into header and use it when needed
passing serial line base port via boot_params.

---
arch/x86/boot/boot.h | 2 -
arch/x86/boot/compressed/misc.c | 18 +++++++++++++
arch/x86/boot/main.c | 2 -
arch/x86/boot/tty.c | 51 ++++++++++-----------------------------
arch/x86/boot/tty.h | 45 ++++++++++++++++++++++++++++++++++
arch/x86/include/asm/bootparam.h | 2 -
arch/x86/kernel/early_printk.c | 36 +++------------------------
7 files changed, 85 insertions(+), 71 deletions(-)

Index: linux-2.6.git/arch/x86/boot/boot.h
=====================================================================
--- linux-2.6.git.orig/arch/x86/boot/boot.h
+++ linux-2.6.git/arch/x86/boot/boot.h
@@ -348,7 +348,7 @@ unsigned int atou(const char *s);
unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base);

/* tty.c */
-void console_init(void);
+void console_init(struct boot_params *boot_params);
void puts(const char *);
void putchar(int);
int getchar(void);
Index: linux-2.6.git/arch/x86/boot/compressed/misc.c
=====================================================================
--- linux-2.6.git.orig/arch/x86/boot/compressed/misc.c
+++ linux-2.6.git/arch/x86/boot/compressed/misc.c
@@ -27,6 +27,8 @@
#include <asm/boot.h>
#include <asm/bootparam.h>

+#include "../tty.h"
+
/* WARNING!!
* This code is compiled with -fPIC and it is relocated dynamically
* at run time, but no relocation processing is performed.
@@ -180,6 +182,21 @@ static void __putstr(int error, const ch
return;
#endif

+ /*
+ * write to early serial console first
+ * then we may write to video memory
+ */
+ if (real_mode->early_serial_base) {
+ int ch, base = real_mode->early_serial_base;
+ const char *str = s;
+ while ((ch = *str++)) {
+ /* \n -> \r\n */
+ if (ch == '\n')
+ __serial_putchar('\r', base);
+ __serial_putchar(ch, base);
+ }
+ }
+
if (real_mode->screen_info.orig_video_mode == 0 &&
lines == 0 && cols == 0)
return;
@@ -342,5 +359,6 @@ asmlinkage void decompress_kernel(void *
parse_elf(output);
if (!quiet)
putstr("done.\nBooting the kernel.\n");
+
return;
}
Index: linux-2.6.git/arch/x86/boot/main.c
=====================================================================
--- linux-2.6.git.orig/arch/x86/boot/main.c
+++ linux-2.6.git/arch/x86/boot/main.c
@@ -131,7 +131,7 @@ void main(void)
copy_boot_params();

/* Initialize the early-boot console */
- console_init();
+ console_init(&boot_params);

/* End of heap check */
init_heap();
Index: linux-2.6.git/arch/x86/boot/tty.c
=====================================================================
--- linux-2.6.git.orig/arch/x86/boot/tty.c
+++ linux-2.6.git/arch/x86/boot/tty.c
@@ -14,44 +14,15 @@
*/

#include "boot.h"
+#include "tty.h"

-#define DEFAULT_SERIAL_PORT 0x3f8 /* ttyS0 */
-
-static int early_serial_base;
-
-#define XMTRDY 0x20
-
-#define DLAB 0x80
-
-#define TXR 0 /* Transmit register (WRITE) */
-#define RXR 0 /* Receive register (READ) */
-#define IER 1 /* Interrupt Enable */
-#define IIR 2 /* Interrupt ID */
-#define FCR 2 /* FIFO control */
-#define LCR 3 /* Line control */
-#define MCR 4 /* Modem control */
-#define LSR 5 /* Line Status */
-#define MSR 6 /* Modem Status */
-#define DLL 0 /* Divisor Latch Low */
-#define DLH 1 /* Divisor latch High */
-
-#define DEFAULT_BAUD 9600
+static int early_serial_base;

/*
* These functions are in .inittext so they can be used to signal
* error during initialization.
*/

-static void __attribute__((section(".inittext"))) serial_putchar(int ch)
-{
- unsigned timeout = 0xffff;
-
- while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout)
- cpu_relax();
-
- outb(ch, early_serial_base + TXR);
-}
-
static void __attribute__((section(".inittext"))) bios_putchar(int ch)
{
struct biosregs ireg;
@@ -66,13 +37,14 @@ static void __attribute__((section(".ini

void __attribute__((section(".inittext"))) putchar(int ch)
{
+ /* \n -> \r\n */
if (ch == '\n')
- putchar('\r'); /* \n -> \r\n */
+ putchar('\r');

bios_putchar(ch);

- if (early_serial_base != 0)
- serial_putchar(ch);
+ if (early_serial_base)
+ __serial_putchar(ch, early_serial_base);
}

void __attribute__((section(".inittext"))) puts(const char *str)
@@ -193,7 +165,10 @@ static void parse_earlyprintk(void)
pos++;

if (!strncmp(arg, "ttyS", 4)) {
- static const int bases[] = { 0x3f8, 0x2f8 };
+ static const int bases[] = {
+ SERIAL_PORT_TTYS0,
+ SERIAL_PORT_TTYS1,
+ };
int idx = 0;

if (!strncmp(arg + pos, "ttyS", 4))
@@ -217,7 +192,6 @@ static void parse_earlyprintk(void)
early_serial_init(port, baud);
}

-#define BASE_BAUD (1843200/16)
static unsigned int probe_baud(int port)
{
unsigned char lcr, dll, dlh;
@@ -264,10 +238,13 @@ static void parse_console_uart8250(void)
early_serial_init(port, baud);
}

-void console_init(void)
+void console_init(struct boot_params *boot_params)
{
parse_earlyprintk();

if (!early_serial_base)
parse_console_uart8250();
+
+ if (early_serial_base)
+ boot_params->early_serial_base = early_serial_base;
}
Index: linux-2.6.git/arch/x86/boot/tty.h
=====================================================================
--- /dev/null
+++ linux-2.6.git/arch/x86/boot/tty.h
@@ -0,0 +1,45 @@
+#ifndef BOOT_TTY_H
+#define BOOT_TTY_H
+
+#include <linux/compiler.h>
+#include <asm/boot.h>
+
+#define SERIAL_PORT_TTYS0 0x3f8
+#define SERIAL_PORT_TTYS1 0x2f8
+
+#define DEFAULT_SERIAL_PORT SERIAL_PORT_TTYS0
+
+#define XMTRDY 0x20
+#define DLAB 0x80
+
+#define TXR 0 /* Transmit register (WRITE) */
+#define RXR 0 /* Receive register (READ) */
+#define IER 1 /* Interrupt Enable */
+#define IIR 2 /* Interrupt ID */
+#define FCR 2 /* FIFO control */
+#define LCR 3 /* Line control */
+#define MCR 4 /* Modem control */
+#define LSR 5 /* Line Status */
+#define MSR 6 /* Modem Status */
+#define DLL 0 /* Divisor Latch Low */
+#define DLH 1 /* Divisor latch High */
+
+#define DEFAULT_BAUD 9600
+#define BASE_BAUD (1843200 / 16)
+
+/*
+ * wait for serial line being ready to transmit data
+ * and write out a character then
+ */
+static __always_inline int __serial_putchar(int ch, int base)
+{
+ unsigned int timeout = 0xffff;
+
+ while ((inb(base + LSR) & XMTRDY) == 0 && --timeout)
+ cpu_relax();
+
+ outb(ch, base + TXR);
+ return timeout ? 0 : -1;
+}
+
+#endif /* BOOT_TTY_H */
Index: linux-2.6.git/arch/x86/include/asm/bootparam.h
=====================================================================
--- linux-2.6.git.orig/arch/x86/include/asm/bootparam.h
+++ linux-2.6.git/arch/x86/include/asm/bootparam.h
@@ -93,7 +93,7 @@ struct efi_info {
struct boot_params {
struct screen_info screen_info; /* 0x000 */
struct apm_bios_info apm_bios_info; /* 0x040 */
- __u8 _pad2[4]; /* 0x054 */
+ __u32 early_serial_base; /* 0x054 */
__u64 tboot_addr; /* 0x058 */
struct ist_info ist_info; /* 0x060 */
__u8 _pad3[16]; /* 0x070 */
Index: linux-2.6.git/arch/x86/kernel/early_printk.c
=====================================================================
--- linux-2.6.git.orig/arch/x86/kernel/early_printk.c
+++ linux-2.6.git/arch/x86/kernel/early_printk.c
@@ -17,6 +17,8 @@
#include <asm/pgtable.h>
#include <linux/usb/ehci_def.h>

+#include "../boot/tty.h"
+
/* Simple VGA output */
#define VGABASE (__ISA_IO_base + 0xb8000)

@@ -73,46 +75,18 @@ static struct console early_vga_console

/* Serial functions loosely based on a similar package from Klaus P. Gerlicher */

-static int early_serial_base = 0x3f8; /* ttyS0 */
-
-#define XMTRDY 0x20
-
-#define DLAB 0x80
-
-#define TXR 0 /* Transmit register (WRITE) */
-#define RXR 0 /* Receive register (READ) */
-#define IER 1 /* Interrupt Enable */
-#define IIR 2 /* Interrupt ID */
-#define FCR 2 /* FIFO control */
-#define LCR 3 /* Line control */
-#define MCR 4 /* Modem control */
-#define LSR 5 /* Line Status */
-#define MSR 6 /* Modem Status */
-#define DLL 0 /* Divisor Latch Low */
-#define DLH 1 /* Divisor latch High */
-
-static int early_serial_putc(unsigned char ch)
-{
- unsigned timeout = 0xffff;
-
- while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout)
- cpu_relax();
- outb(ch, early_serial_base + TXR);
- return timeout ? 0 : -1;
-}
+static int early_serial_base = DEFAULT_SERIAL_PORT;

static void early_serial_write(struct console *con, const char *s, unsigned n)
{
while (*s && n-- > 0) {
if (*s == '\n')
- early_serial_putc('\r');
- early_serial_putc(*s);
+ __serial_putchar('\r', early_serial_base);
+ __serial_putchar(*s, early_serial_base);
s++;
}
}

-#define DEFAULT_BAUD 9600
-
static __init void early_serial_init(char *s)
{
unsigned char c;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: Cyrill Gorcunov on
On Mon, Aug 02, 2010 at 02:17:31AM -0700, Yinghai Lu wrote:
....
> Index: linux-2.6/arch/x86/boot/printf.c
> ===================================================================
> --- linux-2.6.orig/arch/x86/boot/printf.c
> +++ linux-2.6/arch/x86/boot/printf.c
> @@ -34,7 +34,7 @@ static int skip_atoi(const char **s)
> #define SMALL 32 /* Must be 32 == 0x20 */
> #define SPECIAL 64 /* 0x */
>
> -#define do_div(n,base) ({ \
> +#define __do_div(n, base) ({ \
> int __res; \
> __res = ((unsigned long) n) % (unsigned) base; \
> n = ((unsigned long) n) / (unsigned) base; \
> @@ -83,7 +83,7 @@ static char *number(char *str, long num,
> tmp[i++] = '0';
> else
> while (num != 0)
> - tmp[i++] = (digits[do_div(num, base)] | locase);
> + tmp[i++] = (digits[__do_div(num, base)] | locase);

Yinghai, what was wrong with the origin do_div? After inclusion it as "printf.c"
in another *.c do_div gets clashed?

-- Cyrill
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: Thiago Farina on
On Mon, Aug 2, 2010 at 4:13 AM, Yinghai Lu <yinghai(a)kernel.org> wrote:
> Index: linux-2.6/arch/x86/boot/string.c
> ===================================================================
> --- linux-2.6.orig/arch/x86/boot/string.c
> +++ linux-2.6/arch/x86/boot/string.c
> @@ -12,7 +12,21 @@
>  * Very basic string functions
>  */
>
> -#include "boot.h"
> +static inline int isdigit(int ch)
> +{
> +       return (ch >= '0') && (ch <= '9');
> +}
> +
> +static inline int isxdigit(int ch)
> +{
> +       if (isdigit(ch))
> +               return true;
> +
> +       if ((ch >= 'a') && (ch <= 'f'))
> +               return true;
> +
> +       return (ch >= 'A') && (ch <= 'F');
> +}
>

These to functions above can be fairly simplified by writting as:

static bool inline is_hex_digit(int c) {
return (c >= '0' && c <= '9') ||
(c >= 'A' && c <= 'F') ||
(c >= 'a' && c <= 'f');
}

Thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/