mschmidt's boot time configuration of serial console (#319631)
This commit is contained in:
		
							parent
							
								
									e9d378a849
								
							
						
					
					
						commit
						018b917ac8
					
				
							
								
								
									
										101
									
								
								additional-lib-functions.diff
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								additional-lib-functions.diff
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,101 @@ | ||||
| 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); | ||||
| 
 | ||||
| -- 
 | ||||
							
								
								
									
										239
									
								
								console-boot-parameter.diff
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										239
									
								
								console-boot-parameter.diff
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,239 @@ | ||||
| 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); | ||||
| 
 | ||||
| -- 
 | ||||
| @ -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 @@ Source0: http://www.memtest.org/download/1.20/memtest86+-%{version}.tar.gz | ||||
| URL: http://www.memtest.org | ||||
| Source1: new-memtest-pkg | ||||
| Source2: memtest-setup | ||||
| # patches from mschmidt@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 @@ Run 'memtest-setup' to add to your GRUB or lilo boot menu. | ||||
| 
 | ||||
| %prep | ||||
| %setup -q | ||||
| %patch0 -p1 | ||||
| %patch1 -p1 | ||||
| %patch2 -p1 | ||||
| 
 | ||||
| %build | ||||
| # Regular build flags not wanted for this binary | ||||
| @ -61,6 +68,9 @@ rm -rf $RPM_BUILD_ROOT | ||||
| /sbin/new-memtest-pkg --remove %{version} | ||||
| 
 | ||||
| %changelog | ||||
| * Wed Oct 17 2007 Warren Togami <wtogami@redhat.com> - 1.70-2 | ||||
| - mschmidt's boot time configuration of serial console (#319631) | ||||
| 
 | ||||
| * Thu Feb 08 2007 Florian La Roche <laroche@redhat.com> - 1.70-1 | ||||
| - update to 1.70 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										31
									
								
								use-strtoul-in-getval.diff
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								use-strtoul-in-getval.diff
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| 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; | ||||
| 
 | ||||
| -- 
 | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user