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 | Summary: Stand-alone memory tester for x86 and x86-64 computers | ||||||
| Name: memtest86+ | Name: memtest86+ | ||||||
| Version: 1.70 | Version: 1.70 | ||||||
| Release: 1%{?dist} | Release: 2%{?dist} | ||||||
| License: GPL | License: GPL | ||||||
| ExclusiveArch: %{ix86} x86_64 | ExclusiveArch: %{ix86} x86_64 | ||||||
| Group: System Environment/Base | 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 | URL: http://www.memtest.org | ||||||
| Source1: new-memtest-pkg | Source1: new-memtest-pkg | ||||||
| Source2: memtest-setup | 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 | Requires(preun): coreutils | ||||||
| # require glibc-devel.i386 via this file: | # require glibc-devel.i386 via this file: | ||||||
| BuildRequires: %{_includedir}/gnu/stubs-32.h | BuildRequires: %{_includedir}/gnu/stubs-32.h | ||||||
| @ -30,6 +34,9 @@ Run 'memtest-setup' to add to your GRUB or lilo boot menu. | |||||||
| 
 | 
 | ||||||
| %prep | %prep | ||||||
| %setup -q | %setup -q | ||||||
|  | %patch0 -p1 | ||||||
|  | %patch1 -p1 | ||||||
|  | %patch2 -p1 | ||||||
| 
 | 
 | ||||||
| %build | %build | ||||||
| # Regular build flags not wanted for this binary | # Regular build flags not wanted for this binary | ||||||
| @ -61,6 +68,9 @@ rm -rf $RPM_BUILD_ROOT | |||||||
| /sbin/new-memtest-pkg --remove %{version} | /sbin/new-memtest-pkg --remove %{version} | ||||||
| 
 | 
 | ||||||
| %changelog | %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 | * Thu Feb 08 2007 Florian La Roche <laroche@redhat.com> - 1.70-1 | ||||||
| - update to 1.70 | - 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