Re: printk

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Aug 03, 2001 at 02:15:54PM -0700, John D. Davis wrote:
> Does anyone know off hand, the earlies point that I can use printk?  I
> added some printk statements to driver/char/console.c and the resulting
> kernel hangs with only the logo showing and no text.  Is prom_printf
> something that I should use instead. I put some printk statements in
> tty_io.c and kernel/printk.c and those compiled kernels work.
> 
> thanks,
> john davis
>

Like other folks from this list have pointed out, you can use
it as early as the first C line.  The output is stored in a memory
buffer and later displayed on your screen when your serial console
is registered.

When porting to a new machine, I often use dev-only patch (i.e.,
not meant to be checked in) to enable seeing printk immediately, *if*
it is a standard UART port.  See the attache patch below.

I don't recommand use or implement prom_printf.

Jun
diff -Nru linux/kernel/printk.c.orig linux/kernel/printk.c
--- linux/kernel/printk.c.orig	Fri Mar  9 12:34:58 2001
+++ linux/kernel/printk.c	Thu Mar 15 14:24:19 2001
@@ -251,6 +251,7 @@
 	return do_syslog(type, buf, len);
 }
 
+extern void debug_out(char * msg, int len);
 asmlinkage int printk(const char *fmt, ...)
 {
 	va_list args;
@@ -296,6 +297,11 @@
 				break;
 			}
 		}
+
+		/* jsun */
+                debug_out(msg,  p - msg + line_feed); 
+
+		/*
 		if (msg_level < console_loglevel && console_drivers) {
 			struct console *c = console_drivers;
 			while(c) {
@@ -304,6 +310,7 @@
 				c = c->next;
 			}
 		}
+		*/
 		if (line_feed)
 			msg_level = -1;
 	}
@@ -494,4 +501,132 @@
 	if (tty && tty->driver.write)
 		tty->driver.write(tty, 0, msg, strlen(msg));
 	return;
+}
+
+
+/* --- CONFIG --- */
+
+/* we need uint32 uint8 */
+/* #include "types.h" */
+typedef         unsigned char uint8;
+typedef         unsigned int  uint32;
+
+/* --- END OF CONFIG --- */
+
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+void Uart16550Init(uint32 baud, uint8 data, uint8 parity, uint8 stop);
+
+/* blocking call */
+uint8 Uart16550GetPoll(void);
+
+void Uart16550Put(uint8 byte);
+
+/* ----------------------------------------------------- */
+
+/* === CONFIG === */
+
+#define         BASE                    0xbfa04200
+#define         MAX_BAUD                115200
+#define		REG_OFFSET		8
+
+/* === END OF CONFIG === */
+
+/* register offset */
+#define         OFS_RCV_BUFFER          (0*REG_OFFSET)
+#define         OFS_TRANS_HOLD          (0*REG_OFFSET)
+#define         OFS_SEND_BUFFER         (0*REG_OFFSET)
+#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
+#define         OFS_INTR_ID             (2*REG_OFFSET)
+#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
+#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
+#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
+#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
+#define         OFS_LINE_STATUS         (5*REG_OFFSET)
+#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
+#define         OFS_RS232_INPUT         (6*REG_OFFSET)
+#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
+
+#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
+#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
+
+
+/* memory-mapped read/write of the port */
+#define         UART16550_READ(y)    (*((volatile uint8*)(BASE + y)))
+#define         UART16550_WRITE(y, z)  ((*((volatile uint8*)(BASE + y))) = z)
+
+#define DEBUG_LED (*(unsigned short*)0xb7ffffc0)
+#define OutputLED(x)  (DEBUG_LED = x)
+
+void Uart16550Init(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+    /* disable interrupts */
+    UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+    /* set up buad rate */
+    { 
+        uint32 divisor;
+       
+        /* set DIAB bit */
+        UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+        
+        /* set divisor */
+        divisor = MAX_BAUD / baud;
+        UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+        UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00)>>8);
+
+        /* clear DIAB bit */
+        UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+    }
+
+    /* set data format */
+    UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+uint8 Uart16550GetPoll(void)
+{
+    while((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+    return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+
+void Uart16550Put(uint8 byte)
+{
+    while ((UART16550_READ(OFS_LINE_STATUS) &0x20) == 0);
+    UART16550_WRITE(OFS_SEND_BUFFER, byte);
+}
+
+/* ---------------------------------------------------------- */
+
+void debug_out(char * msg, int len)
+{
+	int i;
+ 	for (i=0; i< len; i++) {
+		if (msg[i] == '\n') {
+			Uart16550Put('\r');
+			Uart16550Put('\n');
+		} else {
+			Uart16550Put(msg[i]);
+		}
+	}
 }

[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux