rpms/memtest86+/devel additional-lib-functions.diff, NONE, 1.1 console-boot-parameter.diff, NONE, 1.1 use-strtoul-in-getval.diff, NONE, 1.1 memtest86+.spec, 1.27, 1.28

Warren Togami (wtogami) fedora-extras-commits at redhat.com
Wed Oct 17 17:58:35 UTC 2007


Author: wtogami

Update of /cvs/pkgs/rpms/memtest86+/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv10469

Modified Files:
	memtest86+.spec 
Added Files:
	additional-lib-functions.diff console-boot-parameter.diff 
	use-strtoul-in-getval.diff 
Log Message:
mschmidt's boot time configuration of serial console (#319631)


additional-lib-functions.diff:

--- NEW FILE additional-lib-functions.diff ---
This adds several standard C functions to lib.c:
strncmp, toupper, isdigit, isxdigit

simple_strtoul is a limited implementation of strtoul, taken from Linux.

They will be needed for command line parsing.

Index: memtest86+-1.70/lib.c
===================================================================
--- memtest86+-1.70.orig/lib.c
+++ memtest86+-1.70/lib.c
@@ -69,6 +69,21 @@ int memcmp(const void *s1, const void *s
 	return 0;
 }
 
+int strncmp(const char *s1, const char *s2, ulong n)
+{
+	signed char res = 0;
+	while (n) {
+		res = *s1 - *s2;
+		if (res != 0)
+			return res;
+		if (*s1 == '\0')
+			return 0;
+		++s1, ++s2;
+		--n;
+	}
+	return res;
+}
+
 void *memmove(void *dest, const void *src, ulong n)
 {
 	long i;
@@ -87,6 +102,53 @@ void *memmove(void *dest, const void *sr
 	}
 	return dest;
 }
+
+char toupper(char c)
+{
+	if (c >= 'a' && c <= 'z')
+		return c + 'A' -'a';
+	else
+		return c;
+}
+
+int isdigit(char c)
+{
+	return c >= '0' && c <= '9';
+}
+
+int isxdigit(char c)
+{
+	return isdigit(c) || (toupper(c) >= 'A' && toupper(c) <= 'F');
+}
+
+unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
+{
+	unsigned long result = 0, value;
+
+	if (!base) {
+		base = 10;
+		if (*cp == '0') {
+			base = 8;
+			cp++;
+			if (toupper(*cp) == 'X' && isxdigit(cp[1])) {
+				cp++;
+				base = 16;
+			}
+		}
+	} else if (base == 16) {
+		if (cp[0] == '0' && toupper(cp[1]) == 'X')
+			cp += 2;
+	}
+	while (isxdigit(*cp) &&
+		(value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
+		result = result*base + value;
+		cp++;
+	}
+	if (endp)
+		*endp = (char *)cp;
+	return result;
+}
+
 /*
  * Scroll the error message area of the screen as needed
  * Starts at line LINE_SCROLL and ends at line 23
Index: memtest86+-1.70/test.h
===================================================================
--- memtest86+-1.70.orig/test.h
+++ memtest86+-1.70/test.h
@@ -95,6 +95,7 @@ typedef unsigned long ulong;
 #define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); })
 int memcmp(const void *s1, const void *s2, ulong count);
 void *memmove(void *dest, const void *src, ulong n);
+int strncmp(const char *s1, const char *s2, ulong n);
 int query_linuxbios(void);
 int query_pcbios(void);
 int insertaddress(ulong);

-- 

console-boot-parameter.diff:

--- NEW FILE console-boot-parameter.diff ---
Make the serial console port and its baudrate configurable on the bootloader
(e.g GRUB) command line.

The parameter format is similar to Linux's. Examples:
console=ttyS0        # to enable serial console on the first serial port
console=ttyS1        # second serial port
console=ttyS0,38400  # with the given baudrate

Selectable parity, bits, flow control not implemented yet.

Index: memtest86+-1.70/config.h
===================================================================
--- memtest86+-1.70.orig/config.h
+++ memtest86+-1.70/config.h
@@ -15,6 +15,9 @@
 /*	to enable. */
 #define SERIAL_CONSOLE_DEFAULT 0
 
+/* SERIAL_TTY - The default serial port to use. 0=ttyS0, 1=ttyS1 */
+#define SERIAL_TTY 0
+
 /* SERIAL_BAUD_RATE - Baud rate for the serial console */
 #define SERIAL_BAUD_RATE 9600
 
Index: memtest86+-1.70/lib.c
===================================================================
--- memtest86+-1.70.orig/lib.c
+++ memtest86+-1.70/lib.c
@@ -11,6 +11,18 @@
 
 int slock = 0, lsr = 0;
 short serial_cons = SERIAL_CONSOLE_DEFAULT;
+
+#if SERIAL_TTY != 0 && SERIAL_TTY != 1
+#error Bad SERIAL_TTY. Only ttyS0 and ttyS1 are supported.
+#endif
+short serial_tty = SERIAL_TTY;
+const short serial_base_ports[] = {0x3f8, 0x2f8};
+
+#if ((115200%SERIAL_BAUD_RATE) != 0)
+#error Bad default baud rate
+#endif
+int serial_baud_rate = SERIAL_BAUD_RATE;
+
 char buf[18];
 
 struct ascii_map_str {
@@ -721,19 +733,9 @@ void ttyprint(int y, int x, const char *
 	serial_echo_print(p);
 }
 
-#if defined(SERIAL_BAUD_RATE)
-
-#if ((115200%SERIAL_BAUD_RATE) != 0)
-#error Bad ttys0 baud rate
-#endif
-
-#define SERIAL_DIV     (115200/SERIAL_BAUD_RATE)
-
-#endif /* SERIAL_BAUD_RATE */
-
 void serial_echo_init(void)
 {
-	int comstat, hi, lo;
+	int comstat, hi, lo, serial_div;
 
 	/* read the Divisor Latch */
 	comstat = serial_echo_inb(UART_LCR);
@@ -744,12 +746,11 @@ void serial_echo_init(void)
 
 	/* now do hardwired init */
 	serial_echo_outb(0x03, UART_LCR); /* No parity, 8 data bits, 1 stop */
-#if defined(SERIAL_BAUD_RATE)
+	serial_div = 115200 / serial_baud_rate;
 	serial_echo_outb(0x83, UART_LCR); /* Access divisor latch */
-	serial_echo_outb(SERIAL_DIV & 0xff, UART_DLL);  /* baud rate divisor */
-	serial_echo_outb((SERIAL_DIV>> 8) & 0xff, UART_DLM);
+	serial_echo_outb(serial_div & 0xff, UART_DLL);  /* baud rate divisor */
+	serial_echo_outb((serial_div >> 8) & 0xff, UART_DLM);
 	serial_echo_outb(0x03, UART_LCR); /* Done with divisor */
-#endif
 
 	/* Prior to disabling interrupts, read the LSR and RBR
 	 * registers */
@@ -974,6 +975,59 @@ void wait_keyup( void ) {
 		}
 	}
 }
+
+/*
+ * Handles "console=<param>" command line option
+ *
+ * Examples of accepted params:
+ *   ttyS0
+ *   ttyS1
+ *   ttyS0,115200
+ */
+void serial_console_setup(char *param)
+{
+	char *option, *end;
+	unsigned long tty;
+	unsigned long baud_rate;
+
+	if (strncmp(param, "ttyS", 4))
+		return;   /* not a serial port */
+
+	param += 4;
+
+	tty = simple_strtoul(param, &option, 10);
+
+	if (option == param)
+		return;   /* there were no digits */
+
+	if (tty > 1)
+		return;   /* only ttyS0 and ttyS1 supported */
+
+	if (*option == '\0')
+		goto save_tty; /* no options given, just ttyS? */
+
+	if (*option != ',')
+		return;  /* missing the comma separator */
+
+	/* baud rate must follow */
+	option++;
+	baud_rate = simple_strtoul(option, &end, 10);
+
+	if (end == option)
+		return;  /* no baudrate after comma */
+
+	if (baud_rate == 0 || (115200 % baud_rate) != 0)
+		return;  /* wrong baud rate */
+
+	if (*end != '\0')
+		return;  /* garbage at the end */
+
+	serial_baud_rate = (int) baud_rate;
+save_tty:
+	serial_tty = (short) tty;
+	serial_cons = 1;
+}
+
 #ifdef LP
 #define DATA            0x00
 #define STATUS          0x01
Index: memtest86+-1.70/main.c
===================================================================
--- memtest86+-1.70.orig/main.c
+++ memtest86+-1.70/main.c
@@ -31,6 +31,7 @@ const struct tseq tseq[] = {
 };
 
 char firsttime = 0;
+char cmdline_parsed = 0;
 
 struct vars variables = {};
 struct vars * const v = &variables;
@@ -135,12 +136,53 @@ static void run_at(unsigned long addr)
 	__run_at(run_at_addr);
 }
 
+/* command line passing using the 'old' boot protocol */
+#define MK_PTR(seg,off) ((void*)(((unsigned long)(seg) << 4) + (off)))
+#define OLD_CL_MAGIC_ADDR ((unsigned short*) MK_PTR(INITSEG,0x20))
+#define OLD_CL_MAGIC 0xA33F
+#define OLD_CL_OFFSET_ADDR ((unsigned short*) MK_PTR(INITSEG,0x22))
+
+static void parse_command_line(void)
+{
+	char *cmdline;
+
+	if (cmdline_parsed)
+		return;
+
+	if (*OLD_CL_MAGIC_ADDR != OLD_CL_MAGIC)
+		return;
+
+	unsigned short offset = *OLD_CL_OFFSET_ADDR;
+	cmdline = MK_PTR(INITSEG, offset);
+
+	/* skip leading spaces */
+	while (*cmdline == ' ')
+		cmdline++;
+
+	while (*cmdline) {
+		if (!strncmp(cmdline, "console=", 8)) {
+			cmdline += 8;
+			serial_console_setup(cmdline);
+		}
+
+		/* go to the next parameter */
+		while (*cmdline && *cmdline != ' ')
+			cmdline++;
+		while (*cmdline == ' ')
+			cmdline++;
+	}
+
+	cmdline_parsed = 1;
+}
+
 void do_test(void)
 {
 	int i = 0;
 	unsigned long chunks;
 	unsigned long lo, hi;
 
+	parse_command_line();
+
 	/* If we have a partial relocation finish it */
 	if (run_at_addr == (unsigned long)&_start) {
 		run_at_addr = 0xffffffff;
Index: memtest86+-1.70/serial.h
===================================================================
--- memtest86+-1.70.orig/serial.h
+++ memtest86+-1.70/serial.h
@@ -136,8 +136,8 @@
  */
 
 #include "io.h"
-#define serial_echo_outb(v,a) outb((v),(a)+0x3f8)
-#define serial_echo_inb(a)    inb((a)+0x3f8)
+#define serial_echo_outb(v,a) outb((v),(a)+serial_base_ports[serial_tty])
+#define serial_echo_inb(a)    inb((a)+serial_base_ports[serial_tty])
 #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
 /* Wait for transmitter & holding register to empty */
 #define WAIT_FOR_XMITR \
Index: memtest86+-1.70/test.h
===================================================================
--- memtest86+-1.70.orig/test.h
+++ memtest86+-1.70/test.h
@@ -103,6 +103,7 @@ void printpatn(void);
 void printpatn(void);
 void itoa(char s[], int n);
 void reverse(char *p);
+void serial_console_setup(char *param);
 void serial_echo_init(void);
 void serial_echo_print(const char *s);
 void ttyprint(int y, int x, const char *s);

-- 

use-strtoul-in-getval.diff:

--- NEW FILE use-strtoul-in-getval.diff ---
Now that we have simple_strtoul() we can use it in getval().

Index: memtest86+-1.70/lib.c
===================================================================
--- memtest86+-1.70.orig/lib.c
+++ memtest86+-1.70/lib.c
@@ -683,21 +683,7 @@ ulong getval(int x, int y, int result_sh
 	shift -= result_shift;
 
 	/* Compute our current value */
-	val = 0;
-	for(i = (base == 16)? 2: 0; i < n; i++) {
-		unsigned long digit = 0;
-		if ((buf[i] >= '0') && (buf[i] <= '9')) {
-			digit = buf[i] - '0';
-		}
-		else if ((buf[i] >= 'a') && (buf[i] <= 'f')) {
-			digit = buf[i] - 'a' + 10;
-		}
-		else {
-				/* It must be a suffix byte */
-			break;
-		}
-		val = (val * base) + digit;
-	}
+	val = simple_strtoul(buf, NULL, base);
 	if (shift > 0) {
 		if (shift >= 32) {
 			val = 0xffffffff;

-- 


Index: memtest86+.spec
===================================================================
RCS file: /cvs/pkgs/rpms/memtest86+/devel/memtest86+.spec,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- memtest86+.spec	8 Feb 2007 09:10:28 -0000	1.27
+++ memtest86+.spec	17 Oct 2007 17:58:03 -0000	1.28
@@ -6,7 +6,7 @@
 Summary: Stand-alone memory tester for x86 and x86-64 computers
 Name: memtest86+
 Version: 1.70
-Release: 1%{?dist}
+Release: 2%{?dist}
 License: GPL
 ExclusiveArch: %{ix86} x86_64
 Group: System Environment/Base
@@ -14,6 +14,10 @@
 URL: http://www.memtest.org
 Source1: new-memtest-pkg
 Source2: memtest-setup
+# patches from mschmidt at redhat.com to implement boot-time configurable serial console
+Patch0: additional-lib-functions.diff
+Patch1: console-boot-parameter.diff
+Patch2: use-strtoul-in-getval.diff
 Requires(preun): coreutils
 # require glibc-devel.i386 via this file:
 BuildRequires: %{_includedir}/gnu/stubs-32.h
@@ -30,6 +34,9 @@
 
 %prep
 %setup -q
+%patch0 -p1
+%patch1 -p1
+%patch2 -p1
 
 %build
 # Regular build flags not wanted for this binary
@@ -61,6 +68,9 @@
 /sbin/new-memtest-pkg --remove %{version}
 
 %changelog
+* Wed Oct 17 2007 Warren Togami <wtogami at redhat.com> - 1.70-2
+- mschmidt's boot time configuration of serial console (#319631)
+
 * Thu Feb 08 2007 Florian La Roche <laroche at redhat.com> - 1.70-1
 - update to 1.70
 




More information about the scm-commits mailing list