[syslinux:elflink] ldlinux: Fix serial output and delete eprintf( )

syslinux-bot for Matt Fleming matt.fleming at intel.com
Thu Jan 24 09:45:09 PST 2013


Commit-ID:  75e2b7c282fc3b5c4f5314717f1b224f489b507e
Gitweb:     http://www.syslinux.org/commit/75e2b7c282fc3b5c4f5314717f1b224f489b507e
Author:     Matt Fleming <matt.fleming at intel.com>
AuthorDate: Thu, 24 Jan 2013 16:47:44 +0000
Committer:  Matt Fleming <matt.fleming at intel.com>
CommitDate: Thu, 24 Jan 2013 17:22:45 +0000

ldlinux: Fix serial output and delete eprintf()

Tagging __syslinux_get_serial_info() with __constructor is pretty
useless when the global variables it uses, such as SerialPort, etc,
are assigned *after* the constructor has run. This constructor made
sense when config parsing was done by the core, but parsing is now
performed by ldlinux. We need to explicitly invoke the function to
initialise __syslinux_serial_console_info once we've parsed any config
files.

eprintf.c was introduced in commit 086d698c642f ("ldlinux: Add
eprintf() to print to VGA and serial") because printf() output wasn't
appearing on the serial console. It turns out that the above
__constructor confusion was the real bug.

Signed-off-by: Matt Fleming <matt.fleming at intel.com>

---
 com32/elflink/ldlinux/Makefile     |  2 +-
 com32/elflink/ldlinux/cli.c        | 38 +++++++++++++++++++-------------------
 com32/elflink/ldlinux/config.h     |  2 --
 com32/elflink/ldlinux/eprintf.c    | 36 ------------------------------------
 com32/elflink/ldlinux/ldlinux.c    |  3 +++
 com32/elflink/ldlinux/msg.c        | 18 +++++++++---------
 com32/elflink/ldlinux/readconfig.c | 23 +++++++++--------------
 com32/include/syslinux/config.h    |  2 ++
 com32/lib/syslinux/serial.c        |  2 +-
 core/conio.c                       | 31 +++++++++++++++++++------------
 10 files changed, 63 insertions(+), 94 deletions(-)

diff --git a/com32/elflink/ldlinux/Makefile b/com32/elflink/ldlinux/Makefile
index b2d0cec..556f93a 100644
--- a/com32/elflink/ldlinux/Makefile
+++ b/com32/elflink/ldlinux/Makefile
@@ -23,7 +23,7 @@ all: $(BTARGET) ldlinux_lnx.a
 
 ldlinux.elf : ldlinux.o cli.o readconfig.o refstr.o colors.o getadv.o \
 		adv.o execute.o chainboot.o kernel.o get_key.o \
-		advwrite.o setadv.o eprintf.o loadhigh.o msg.o
+		advwrite.o setadv.o loadhigh.o msg.o
 	$(LD) $(LDFLAGS) -soname $(patsubst %.elf,%.c32,$(@F)) -o $@ $^ $(LIBS)
 
 LNXCFLAGS += -D__export='__attribute__((visibility("default")))'
diff --git a/com32/elflink/ldlinux/cli.c b/com32/elflink/ldlinux/cli.c
index b94c683..b85357b 100644
--- a/com32/elflink/ldlinux/cli.c
+++ b/com32/elflink/ldlinux/cli.c
@@ -71,7 +71,7 @@ static const char * cmd_reverse_search(int *cursor, clock_t *kbd_to,
 
     memset(buf, 0, MAX_CMDLINE_LEN);
 
-    eprintf("\033[1G\033[1;36m(reverse-i-search)`': \033[0m");
+    printf("\033[1G\033[1;36m(reverse-i-search)`': \033[0m");
     while (1) {
 	key = mygetkey_timeout(kbd_to, tto);
 
@@ -105,11 +105,11 @@ static const char * cmd_reverse_search(int *cursor, clock_t *kbd_to,
             *cursor = p - last_good->command;
 	}
 
-	eprintf("\033[?7l\033[?25l");
+	printf("\033[?7l\033[?25l");
 	/* Didn't handle the line wrap case here */
-	eprintf("\033[1G\033[1;36m(reverse-i-search)\033[0m`%s': %s",
+	printf("\033[1G\033[1;36m(reverse-i-search)\033[0m`%s': %s",
 		buf, last_good->command ? : "");
-	eprintf("\033[K\r");
+	printf("\033[K\r");
     }
 
     return last_good ? last_good->command : NULL;
@@ -147,7 +147,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
      * so that it follows whatever text has been written to the screen
      * previously.
      */
-    eprintf("%s ", input);
+    printf("%s ", input);
 
     while (!done) {
 	if (redraw > 1) {
@@ -158,7 +158,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
 	    if (pDraw_Menu)
 		    (*pDraw_Menu) (-1, top, 1);
 	    prev_len = 0;
-	    eprintf("\033[2J\033[H");
+	    printf("\033[2J\033[H");
 	    // printf("\033[0m\033[2J\033[H");
 	}
 
@@ -168,8 +168,8 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
 	    prev_len = max(len, prev_len);
 
 	    /* Redraw the command line */
-	    eprintf("\033[?7l\033[?25l");
-	    eprintf("\033[1G%s ", input);
+	    printf("\033[?7l\033[?25l");
+	    printf("\033[1G%s ", input);
 
 	    x = strlen(input);
 	    y = 0;
@@ -179,23 +179,23 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
 		at++;
 		x++;
 		if (x >= width) {
-		    eprintf("\r\n");
+		    printf("\r\n");
 		    x = 0;
 		    y++;
 		}
 	    }
-	    eprintf("\033[K\r");
+	    printf("\033[K\r");
 
 	    dy = y - (cursor + strlen(input) + 1) / width;
 	    x = (cursor + strlen(input) + 1) % width;
 
 	    if (dy) {
-		eprintf("\033[%dA", dy);
+		printf("\033[%dA", dy);
 		y -= dy;
 	    }
 	    if (x)
-		eprintf("\033[%dC", x);
-	    eprintf("\033[?25h");
+		printf("\033[%dC", x);
+	    printf("\033[?25h");
 	    prev_len = len;
 	    redraw = 0;
 	}
@@ -288,7 +288,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
 		cursor++;
 		x++;
 		if (x >= width) {
-		    eprintf("\r\n");
+		    printf("\r\n");
 		    y++;
 		    x = 0;
 		}
@@ -418,10 +418,10 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
 	    }
 	case KEY_CTRL('V'):
 	    if (BIOSName)
-		eprintf("%s%s%s", syslinux_banner,
-			MK_PTR(0, BIOSName), copyright_str);
+		printf("%s%s%s", syslinux_banner,
+		       (char *)MK_PTR(0, BIOSName), copyright_str);
 	    else
-		eprintf("%s%s", syslinux_banner, copyright_str);
+		printf("%s%s", syslinux_banner, copyright_str);
 
 	    redraw = 1;
 	    break;
@@ -435,7 +435,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
 		    cursor++;
 		    x++;
 		    if (x >= width) {
-			eprintf("\r\n\033[K");
+			printf("\r\n\033[K");
 			y++;
 			x = 0;
 		    }
@@ -452,7 +452,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
 	}
     }
 
-    eprintf("\033[?7h");
+    printf("\033[?7h");
 
     /* Add the command to the history */
     comm_counter = malloc(sizeof(struct cli_command));
diff --git a/com32/elflink/ldlinux/config.h b/com32/elflink/ldlinux/config.h
index c551fb1..242b7dc 100644
--- a/com32/elflink/ldlinux/config.h
+++ b/com32/elflink/ldlinux/config.h
@@ -41,8 +41,6 @@ extern void cat_help_file(int key);
 extern struct menu_entry *find_label(const char *str);
 extern void print_labels(const char *prefix, size_t len);
 
-extern void eprintf(const char *filename, ...);
-
 extern int new_linux_kernel(char *okernel, char *ocmdline);
 
 extern void pm_load_high(com32sys_t *regs);
diff --git a/com32/elflink/ldlinux/eprintf.c b/com32/elflink/ldlinux/eprintf.c
deleted file mode 100644
index f15edc6..0000000
--- a/com32/elflink/ldlinux/eprintf.c
+++ /dev/null
@@ -1,36 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <core.h>
-
-#define BUFFER_SIZE	4096
-
-static void veprintf(const char *format, va_list ap)
-{
-    int rv, _rv;
-    char buffer[BUFFER_SIZE];
-    char *p;
-
-    _rv = rv = vsnprintf(buffer, BUFFER_SIZE, format, ap);
-
-    if (rv < 0)
-	return;
-
-    if (rv > BUFFER_SIZE - 1)
-	rv = BUFFER_SIZE - 1;
-
-    p = buffer;
-    while (rv--)
-	    write_serial(*p++);
-
-    _fwrite(buffer, _rv, stdout);
-}
-
-void eprintf(const char *format, ...)
-{
-    va_list ap;
-
-    va_start(ap, format);
-    veprintf(format, ap);
-    va_end(ap);
-}
diff --git a/com32/elflink/ldlinux/ldlinux.c b/com32/elflink/ldlinux/ldlinux.c
index 6f9f20f..a8b1b38 100644
--- a/com32/elflink/ldlinux/ldlinux.c
+++ b/com32/elflink/ldlinux/ldlinux.c
@@ -12,6 +12,7 @@
 #include "config.h"
 #include "syslinux/adv.h"
 #include "syslinux/boot.h"
+#include "syslinux/config.h"
 
 #include <sys/module.h>
 
@@ -290,6 +291,8 @@ __export int main(int argc __unused, char **argv __unused)
 
 	parse_configs(config_argv);
 
+	__syslinux_set_serial_console_info();
+
 	adv = syslinux_getadv(ADV_BOOTONCE, &count);
 	if (adv && count) {
 		/*
diff --git a/com32/elflink/ldlinux/msg.c b/com32/elflink/ldlinux/msg.c
index 6ce6368..502b58d 100644
--- a/com32/elflink/ldlinux/msg.c
+++ b/com32/elflink/ldlinux/msg.c
@@ -4,7 +4,7 @@
 #include <graphics.h>
 
 static uint8_t TextAttribute;	/* Text attribute for message file */
-static uint8_t DisplayMask;	/* Display modes mask */
+extern uint8_t DisplayMask;	/* Display modes mask */
 
 /* Routine to interpret next print char */
 static void (*NextCharJump)(uint8_t);
@@ -45,6 +45,8 @@ int get_msg_file(char *filename)
 		NextCharJump(ch);	/* Do what shall be done */
 	}
 
+	DisplayMask = 0x07;
+
 	fclose(f);
 	return 0;
 }
@@ -144,16 +146,14 @@ static void msg_normal(uint8_t data)
 	uint8_t bg, fg;
 	uint8_t mask = UsingVGA & 0x1;
 
-	/* Write to serial port */
-	if (DisplayMask & 0x4)
-		write_serial(data);
-
 	/* 0x1 = text mode, 0x2 = graphics mode */
-	if (!(DisplayMask & ++mask))
-		return;		/* Not screen */
+	if (!(DisplayMask & ++mask) || !(DisplayCon & 0x01)) {
+		/* Write to serial port */
+		if (DisplayMask & 0x4)
+			write_serial(data);
 
-	if (!(DisplayCon & 0x01))
-		return;
+		return;		/* Not screen */
+	}
 
 	fg = convert_to_pcdisplay[(TextAttribute & 0x7)];
 	bg = convert_to_pcdisplay[((TextAttribute >> 4) & 0x7)];
diff --git a/com32/elflink/ldlinux/readconfig.c b/com32/elflink/ldlinux/readconfig.c
index f4f599f..a2421e9 100644
--- a/com32/elflink/ldlinux/readconfig.c
+++ b/com32/elflink/ldlinux/readconfig.c
@@ -26,6 +26,7 @@
 #include <syslinux/config.h>
 #include <dprintf.h>
 #include <ctype.h>
+#include <bios.h>
 #include <core.h>
 #include <fs.h>
 
@@ -79,7 +80,6 @@ short allowoptions = 1;		//user-specified options allowed
 short includelevel = 1;		//nesting level
 short defaultlevel = 0;		//the current level of default
 short vkernel = 0;		//have we seen any "label" statements?
-short displaycon = 1;		//conio.inc
 extern short NoHalt;		//idle.c
 
 const char *onerror = NULL;	//"onerror" command line
@@ -442,12 +442,12 @@ void print_labels(const char *prefix, size_t len)
 {
     struct menu_entry *me;
 
-    eprintf("\n");
+    printf("\n");
     for (me = all_entries; me; me = me->next ) {
 	if (!strncmp(prefix, me->label, len))
-	    eprintf(" %s", me->label);
+	    printf(" %s", me->label);
     }
-    eprintf("\n");
+    printf("\n");
 }
 
 struct menu_entry *find_label(const char *str)
@@ -696,7 +696,7 @@ void cat_help_file(int key)
 		return;
 
 	if (cm->fkeyhelp[fkey].textname) {
-		eprintf("\n");
+		printf("\n");
 		get_msg_file((char *)cm->fkeyhelp[fkey].textname);
 	}
 }
@@ -735,12 +735,6 @@ extern void sirq_cleanup_nowipe(void);
 extern void sirq_install(void);
 extern void write_serial_str(char *);
 
-static inline void io_delay(void)
-{
-	outb(0, 0x80);
-	outb(0, 0x80);
-}
-
 extern void loadfont(char *);
 extern void loadkeys(char *);
 
@@ -1180,7 +1174,7 @@ do_include:
 	} else if (looking_at(p, "prompt")) {
 		forceprompt = atoi(skipspace(p + 6));
 	} else if (looking_at(p, "console")) {
-		displaycon = atoi(skipspace(p + 7));
+		DisplayCon = atoi(skipspace(p + 7));
 	} else if (looking_at(p, "allowoptions")) {
 		allowoptions = atoi(skipspace(p + 12));
 	} else if (looking_at(p, "noescape")) {
@@ -1317,8 +1311,9 @@ do_include:
 			write_serial_str(syslinux_banner);
 			write_serial_str(copyright_str);
 		}
+
 	} else if (looking_at(p, "say")) {
-		eprintf("%s\n", p+4);
+		printf("%s\n", p+4);
 	} else if (looking_at(p, "path")) {
 		/* PATH-based lookup */
 		const char *new_path;
@@ -1337,7 +1332,7 @@ do_include:
 			free(PATH);
 			PATH = _p;
 		} else
-			eprintf("Failed to realloc PATH\n");
+			printf("Failed to realloc PATH\n");
 	}
     }
 }
diff --git a/com32/include/syslinux/config.h b/com32/include/syslinux/config.h
index 7bdcdd6..8f4124c 100644
--- a/com32/include/syslinux/config.h
+++ b/com32/include/syslinux/config.h
@@ -156,6 +156,8 @@ struct syslinux_serial_console_info {
     uint16_t flowctl;
 };
 
+extern void __syslinux_set_serial_console_info(void);
+
 extern __nocommon struct syslinux_serial_console_info
     __syslinux_serial_console_info;
 static inline const struct syslinux_serial_console_info
diff --git a/com32/lib/syslinux/serial.c b/com32/lib/syslinux/serial.c
index bb92222..aa5690f 100644
--- a/com32/lib/syslinux/serial.c
+++ b/com32/lib/syslinux/serial.c
@@ -39,7 +39,7 @@
 
 struct syslinux_serial_console_info __syslinux_serial_console_info;
 
-void __constructor __syslinux_get_serial_console_info(void)
+void __syslinux_set_serial_console_info(void)
 {
     uint16_t flowctl;
 
diff --git a/core/conio.c b/core/conio.c
index abfceb8..3b8a103 100644
--- a/core/conio.c
+++ b/core/conio.c
@@ -44,6 +44,8 @@ __export uint8_t FlowIgnore = 0;    /* Ignore input unless these bits set */
 __export uint16_t DisplayCon = 0x01;	/* Display console enabled */
 __export uint8_t FlowOutput = 0;	/* Output to assert for serial flow */
 
+__export uint8_t DisplayMask = 0x07;	/* Display modes mask */
+
 uint8_t ScrollAttribute = 0x07; /* Grey on white (normal text color) */
 
 /*
@@ -74,6 +76,9 @@ __export void write_serial(char data)
 	if (!SerialPort)
 		return;
 
+	if (!(DisplayMask & 0x04))
+		return;
+
 	while (1) {
 		char ch;
 
@@ -156,21 +161,22 @@ __export int pollchar(void)
 		/* Already-queued input? */
 		if (SerialTail == SerialHead) {
 			/* LSR */
-			data = inb(SerialPort + 5) & 1;
-			if (data) {
+			data = !(inb(SerialPort + 5) & 1);
+			if (!data) {
 				/* MSR */
 				data = inb(SerialPort + 6);
 
 				/* Required status bits */
-				if (data) {
-					data &= FlowIgnore;
-					if (data != FlowIgnore)
-						data = 0;
-					else
-						data = 1;
-				}
-			}
-		}
+				data &= FlowIgnore;
+
+				if (data == FlowIgnore)
+					data = 1;
+				else
+					data = 0;
+			} else
+				data = 1;
+		} else
+			data = 1;
 		sti();
 	}
 
@@ -213,7 +219,8 @@ __export char getchar(char *hi)
 				sti(); /* We already know we'll consume data */
 				data = *SerialTail++;
 
-				SerialTail = (char *)((unsigned long)SerialTail & (serial_buf_size - 1));
+				if (SerialTail > SerialHead + serial_buf_size)
+					SerialTail = SerialHead;
 			} else {
 				/* LSR */
 				data = inb(SerialPort + 5) & 1;


More information about the Syslinux-commits mailing list