⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial.c

📁 linux下从网卡远程启动
💻 C
字号:
#ifdef	CONSOLE_SERIAL#include "etherboot.h"#include "linux-asm-io.h"/* * The serial port interface routines implement a simple polled i/o * interface to a standard serial port.  Due to the space restrictions * for the boot blocks, no BIOS support is used (since BIOS requires * expensive real/protected mode switches), instead the rudimentary * BIOS support is duplicated here. * * The base address and speed for the i/o port are passed from the * Makefile in the COMCONSOLE and CONSPEED preprocessor macros.  The * line control parameters are currently hard-coded to 8 bits, no * parity, 1 stop bit (8N1).  This can be changed in serial_init(). */static int found = 0;#define UART_BASE COMCONSOLE#ifndef CONSPEED#define CONSPEED 115200#endif#if ((115200%CONSPEED) != 0)#error Bad ttys0 baud rate#endif#define COMBRD (115200/CONSPEED)/* Line Control Settings */#ifndef	COMPARM/* Set 8bit, 1 stop bit, no parity */#define	COMPARM	0x03#endif#define UART_LCS COMPARM/* Data */#define UART_RBR 0x00#define UART_TBR 0x00/* Control */#define UART_IER 0x01#define UART_IIR 0x02#define UART_FCR 0x02#define UART_LCR 0x03#define UART_MCR 0x04#define UART_DLL 0x00#define UART_DLM 0x01/* Status */#define UART_LSR 0x05#define UART_MSR 0x06#define UART_SCR 0x07/* * void serial_putc(int ch); *	Write character `ch' to port COMCONSOLE. */void serial_putc(int ch){	int i;	int status;	if (!found) {		/* no serial interface */		return;	}	i = 10000; /* timeout */	while(--i > 0) {		status = inb(COMCONSOLE + UART_LSR);		if (status & (1 << 5)) { 			/* TX buffer emtpy */			outb(ch, COMCONSOLE + UART_TBR);			break;		}	}}/* * int serial_getc(void); *	Read a character from port COMCONSOLE. */int serial_getc(void){	int status;	int ch;	do {		status = inb(COMCONSOLE + UART_LSR);	} while((status & 1) == 0);	ch = inb(COMCONSOLE + UART_RBR);	/* fetch (first) character */	ch &= 0x7f;				/* remove any parity bits we get */	if (ch == 0x7f) {			/* Make DEL... look like BS */		ch = 0x08;	}	return ch;}/* * int serial_ischar(void); *       If there is a character in the input buffer of port COMCONSOLE, *       return nonzero; otherwise return 0. */int serial_ischar(void){	int status;	if (!found)		return 0;	status = inb(COMCONSOLE + UART_LSR);	/* line status reg; */	return status & 1;		/* rx char available */}#if	!defined(COMBRD) && defined(CONSPEED)/* Recent GNU as versions with ELF output format define / as a comment * character, because some misguided spec says so.  Do it the easy way and * just check for the usual values.  This is only compiled by gcc, so * #elif can be used (bcc doesn't understand it).  */#if	(CONSPEED == 115200)#define COMBRD 1#elif	(CONSPEED == 57600)#define COMBRD 2#elif	(CONSPEED == 38400)#define COMBRD 3#elif	(CONSPEED == 19200)#define COMBRD 6#elif	(CONSPEED == 9600)#define COMBRD 12#elif	(CONSPEED == 2400)#define COMBRD 48#elif	(CONSPEED == 1200)#define COMBRD 96#elif	(CONSPEED == 300)#define COMBRD 384#else#error Add your unusual baud rate to the table in serial.S!#define	COMBRD	(115200 / CONSPEED)#endif#endif/* * int serial_init(void); *	Initialize port COMCONSOLE to speed CONSPEED, line settings 8N1. */int serial_init(void){	int initialized = 0;	int status;	int divisor, lcs;	divisor = COMBRD;	lcs = UART_LCS;#ifdef COMPRESERVE	lcs = inb(COMCONSOLE + UART_LCR) & 0x7f;	outb(0x80 | lcs, COMCONSOLE + UART_LCR);	divisor = (inb(COMCONSOLE + UART_DLM) << 8) | inb(COMCONSOLE + UART_DLL);	outb(lcs, COMCONSOLE + UART_LCR);#endif	/* Set Baud Rate Divisor to CONSPEED, and test to see if the	 * serial port appears to be present.	 */	outb(0x80 | lcs, COMCONSOLE + UART_LCR);	outb(0xaa, COMCONSOLE + UART_DLL);	if (inb(COMCONSOLE + UART_DLL) != 0xaa) 		goto out;	outb(0x55, COMCONSOLE + UART_DLL);	if (inb(COMCONSOLE + UART_DLL) != 0x55)		goto out;	outb(divisor & 0xff, COMCONSOLE + UART_DLL);	if (inb(COMCONSOLE + UART_DLL) != (divisor & 0xff))		goto out;	outb(0xaa, COMCONSOLE + UART_DLM);	if (inb(COMCONSOLE + UART_DLM) != 0xaa) 		goto out;	outb(0x55, COMCONSOLE + UART_DLM);	if (inb(COMCONSOLE + UART_DLM) != 0x55)		goto out;	outb((divisor >> 8) & 0xff, COMCONSOLE + UART_DLM);	if (inb(COMCONSOLE + UART_DLM) != ((divisor >> 8) & 0xff))		goto out;	outb(lcs, COMCONSOLE + UART_LCR);		/* disable interrupts */	outb(0x0, COMCONSOLE + UART_IER);	/* disable fifo's */	outb(0x00, COMCONSOLE + UART_FCR);	/* Set clear to send, so flow control works... */	outb((1<<1), COMCONSOLE + UART_MCR);	/* Flush the input buffer. */	do {		/* rx buffer reg		 * throw away (unconditionally the first time)		 */		inb(COMCONSOLE + UART_RBR);		/* line status reg */		status = inb(COMCONSOLE + UART_LSR);	} while(status & 1);	initialized = 1; out:	found = initialized;	return initialized;}/* * void serial_fini(void); *	Cleanup our use of the serial port, in particular flush the *	output buffer so we don't accidentially loose characters. */void serial_fini(void){	int i, status;	if (!found) {		/* no serial interface */		return;	}	/* Flush the output buffer to avoid dropping characters,	 * if we are reinitializing the serial port.	 */	i = 10000; /* timeout */	do {		status = inb(COMCONSOLE + UART_LSR);	} while((--i > 0) || (!(status & (1 << 6))));	found = 0;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -