aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-01-24 16:47:44 +0000
committerMatt Fleming <matt.fleming@intel.com>2013-01-24 17:22:45 +0000
commit75e2b7c282fc3b5c4f5314717f1b224f489b507e (patch)
tree5f428f170ced2ae70395ce0eedba510b24e23a63
parent40a6839c9ed17518e5984f4ea3e5530cbcfeb4c3 (diff)
downloadsyslinux-75e2b7c282fc3b5c4f5314717f1b224f489b507e.tar.gz
syslinux-75e2b7c282fc3b5c4f5314717f1b224f489b507e.tar.xz
syslinux-75e2b7c282fc3b5c4f5314717f1b224f489b507e.zip
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@intel.com>
-rw-r--r--com32/elflink/ldlinux/Makefile2
-rw-r--r--com32/elflink/ldlinux/cli.c38
-rw-r--r--com32/elflink/ldlinux/config.h2
-rw-r--r--com32/elflink/ldlinux/eprintf.c36
-rw-r--r--com32/elflink/ldlinux/ldlinux.c3
-rw-r--r--com32/elflink/ldlinux/msg.c18
-rw-r--r--com32/elflink/ldlinux/readconfig.c23
-rw-r--r--com32/include/syslinux/config.h2
-rw-r--r--com32/lib/syslinux/serial.c2
-rw-r--r--core/conio.c31
10 files changed, 63 insertions, 94 deletions
diff --git a/com32/elflink/ldlinux/Makefile b/com32/elflink/ldlinux/Makefile
index b2d0cecb..556f93a5 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 b94c6835..b85357b2 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 c551fb19..242b7dc5 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 f15edc6e..00000000
--- 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 6f9f20fa..a8b1b386 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 6ce63685..502b58de 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 f4f599f4..a2421e95 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 7bdcdd6b..8f4124ce 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 bb92222f..aa5690fa 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 abfceb88..3b8a103b 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;