colored-kernel-message-output.diff 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
  2. index 01d1c18..2a02d82 100644
  3. --- a/arch/x86/kernel/early_printk.c
  4. +++ b/arch/x86/kernel/early_printk.c
  5. @@ -26,7 +26,8 @@
  6. static int max_ypos = 25, max_xpos = 80;
  7. static int current_ypos = 25, current_xpos;
  8. -static void early_vga_write(struct console *con, const char *str, unsigned n)
  9. +static void early_vga_write(struct console *con, const char *str, unsigned n,
  10. + unsigned int loglevel)
  11. {
  12. char c;
  13. int i, k, j;
  14. @@ -104,7 +105,8 @@ static int early_serial_putc(unsigned char ch)
  15. return timeout ? 0 : -1;
  16. }
  17. -static void early_serial_write(struct console *con, const char *s, unsigned n)
  18. +static void early_serial_write(struct console *con, const char *s, unsigned n,
  19. + unsigned int loglevel)
  20. {
  21. while (*s && n-- > 0) {
  22. if (*s == '\n')
  23. diff --git a/drivers/accessibility/braille/braille_console.c b/drivers/accessibility/braille/braille_console.c
  24. index dc34a5b..020118b 100644
  25. --- a/drivers/accessibility/braille/braille_console.c
  26. +++ b/drivers/accessibility/braille/braille_console.c
  27. @@ -116,7 +116,7 @@ static void braille_write(u16 *buf)
  28. *c++ = csum;
  29. *c++ = ETX;
  30. - braille_co->write(braille_co, data, c - data);
  31. + braille_co->write(braille_co, data, c - data, 0);
  32. }
  33. /* Follow the VC cursor*/
  34. diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
  35. index ba2f5e7..b649820 100644
  36. --- a/drivers/net/netconsole.c
  37. +++ b/drivers/net/netconsole.c
  38. @@ -728,7 +728,8 @@ static int netconsole_netdev_event(struct notifier_block *this,
  39. .notifier_call = netconsole_netdev_event,
  40. };
  41. -static void write_msg(struct console *con, const char *msg, unsigned int len)
  42. +static void write_msg(struct console *con, const char *msg, unsigned int len,
  43. + unsigned int loglevel)
  44. {
  45. int frag, left;
  46. unsigned long flags;
  47. diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig
  48. index 978db34..63e7160 100644
  49. --- a/drivers/tty/Kconfig
  50. +++ b/drivers/tty/Kconfig
  51. @@ -75,6 +75,111 @@ config VT_CONSOLE_SLEEP
  52. def_bool y
  53. depends on VT_CONSOLE && PM_SLEEP
  54. +menuconfig VT_CKO
  55. + bool "Colored kernel message output"
  56. + depends on VT_CONSOLE
  57. + ---help---
  58. + This option enables kernel messages to be emitted in
  59. + colors other than the default.
  60. +
  61. + The color value you need to enter is composed (OR-ed)
  62. + of a foreground and a background color.
  63. +
  64. + Foreground:
  65. + 0x00 = black, 0x08 = dark gray,
  66. + 0x01 = red, 0x09 = light red,
  67. + 0x02 = green, 0x0A = light green,
  68. + 0x03 = brown, 0x0B = yellow,
  69. + 0x04 = blue, 0x0C = light blue,
  70. + 0x05 = magenta, 0x0D = light magenta,
  71. + 0x06 = cyan, 0x0E = light cyan,
  72. + 0x07 = gray, 0x0F = white,
  73. +
  74. + (Foreground colors 0x08 to 0x0F do not work when a VGA
  75. + console font with 512 glyphs is used.)
  76. +
  77. + Background:
  78. + 0x00 = black, 0x40 = blue,
  79. + 0x10 = red, 0x50 = magenta,
  80. + 0x20 = green, 0x60 = cyan,
  81. + 0x30 = brown, 0x70 = gray,
  82. +
  83. + For example, 0x1F would yield white on red.
  84. +
  85. + If unsure, say N.
  86. +
  87. +config VT_PRINTK_EMERG_COLOR
  88. + hex "Emergency messages color"
  89. + range 0x00 0xFF
  90. + depends on VT_CKO
  91. + default 0x07
  92. + ---help---
  93. + This option defines with which color kernel emergency messages will
  94. + be printed to the console.
  95. +
  96. +config VT_PRINTK_ALERT_COLOR
  97. + hex "Alert messages color"
  98. + range 0x00 0xFF
  99. + depends on VT_CKO
  100. + default 0x07
  101. + ---help---
  102. + This option defines with which color kernel alert messages will
  103. + be printed to the console.
  104. +
  105. +config VT_PRINTK_CRIT_COLOR
  106. + hex "Critical messages color"
  107. + range 0x00 0xFF
  108. + depends on VT_CKO
  109. + default 0x07
  110. + ---help---
  111. + This option defines with which color kernel critical messages will
  112. + be printed to the console.
  113. +
  114. +config VT_PRINTK_ERR_COLOR
  115. + hex "Error messages color"
  116. + range 0x00 0xFF
  117. + depends on VT_CKO
  118. + default 0x07
  119. + ---help---
  120. + This option defines with which color kernel error messages will
  121. + be printed to the console.
  122. +
  123. +config VT_PRINTK_WARNING_COLOR
  124. + hex "Warning messages color"
  125. + range 0x00 0xFF
  126. + depends on VT_CKO
  127. + default 0x07
  128. + ---help---
  129. + This option defines with which color kernel warning messages will
  130. + be printed to the console.
  131. +
  132. +config VT_PRINTK_NOTICE_COLOR
  133. + hex "Notice messages color"
  134. + range 0x00 0xFF
  135. + depends on VT_CKO
  136. + default 0x07
  137. + ---help---
  138. + This option defines with which color kernel notice messages will
  139. + be printed to the console.
  140. +
  141. +config VT_PRINTK_INFO_COLOR
  142. + hex "Information messages color"
  143. + range 0x00 0xFF
  144. + depends on VT_CKO
  145. + default 0x07
  146. + ---help---
  147. + This option defines with which color kernel information messages will
  148. + be printed to the console.
  149. +
  150. +config VT_PRINTK_DEBUG_COLOR
  151. + hex "Debug messages color"
  152. + range 0x00 0xFF
  153. + depends on VT_CKO
  154. + default 0x07
  155. + ---help---
  156. + This option defines with which color kernel debug messages will
  157. + be printed to the console.
  158. +
  159. config HW_CONSOLE
  160. bool
  161. depends on VT && !UML
  162. diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
  163. index e33d38cb..d73fdfb 100644
  164. --- a/drivers/tty/serial/8250/8250_core.c
  165. +++ b/drivers/tty/serial/8250/8250_core.c
  166. @@ -2850,7 +2850,8 @@ static void serial8250_console_putchar(struct uart_port *port, int ch)
  167. * The console_lock must be held when we get here.
  168. */
  169. static void
  170. -serial8250_console_write(struct console *co, const char *s, unsigned int count)
  171. +serial8250_console_write(struct console *co, const char *s, unsigned int count,
  172. + unsigned int loglevel)
  173. {
  174. struct uart_8250_port *up = &serial8250_ports[co->index];
  175. struct uart_port *port = &up->port;
  176. diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c
  177. index c100d63..bb28b49 100644
  178. --- a/drivers/tty/serial/8250/8250_early.c
  179. +++ b/drivers/tty/serial/8250/8250_early.c
  180. @@ -98,7 +98,7 @@ static void __init serial_putc(struct uart_port *port, int c)
  181. }
  182. static void __init early_serial8250_write(struct console *console,
  183. - const char *s, unsigned int count)
  184. + const char *s, unsigned int count, unsigned int loglevel)
  185. {
  186. struct uart_port *port = &early_device.port;
  187. unsigned int ier;
  188. diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
  189. index 61b1137..f1fa906 100644
  190. --- a/drivers/tty/vt/vt.c
  191. +++ b/drivers/tty/vt/vt.c
  192. @@ -71,6 +71,7 @@
  193. */
  194. #include <linux/module.h>
  195. +#include <linux/moduleparam.h>
  196. #include <linux/types.h>
  197. #include <linux/sched.h>
  198. #include <linux/tty.h>
  199. @@ -2430,16 +2431,44 @@ int vt_kmsg_redirect(int new)
  200. return kmsg_con;
  201. }
  202. +#ifdef CONFIG_VT_CKO
  203. +static unsigned int printk_color[8] __read_mostly = {
  204. + CONFIG_VT_PRINTK_EMERG_COLOR, /* KERN_EMERG */
  205. + CONFIG_VT_PRINTK_ALERT_COLOR, /* KERN_ALERT */
  206. + CONFIG_VT_PRINTK_CRIT_COLOR, /* KERN_CRIT */
  207. + CONFIG_VT_PRINTK_ERR_COLOR, /* KERN_ERR */
  208. + CONFIG_VT_PRINTK_WARNING_COLOR, /* KERN_WARNING */
  209. + CONFIG_VT_PRINTK_NOTICE_COLOR, /* KERN_NOTICE */
  210. + CONFIG_VT_PRINTK_INFO_COLOR, /* KERN_INFO */
  211. + CONFIG_VT_PRINTK_DEBUG_COLOR, /* KERN_DEBUG */
  212. +};
  213. +module_param_array(printk_color, uint, NULL, S_IRUGO | S_IWUSR);
  214. +
  215. +static inline void vc_set_color(struct vc_data *vc, unsigned char color)
  216. +{
  217. + vc->vc_color = color_table[color & 0xF] |
  218. + (color_table[(color >> 4) & 0x7] << 4) |
  219. + (color & 0x80);
  220. + update_attr(vc);
  221. +}
  222. +#else
  223. +static unsigned int printk_color[8];
  224. +static inline void vc_set_color(const struct vc_data *vc, unsigned char c)
  225. +{
  226. +}
  227. +#endif
  228. +
  229. /*
  230. * Console on virtual terminal
  231. *
  232. * The console must be locked when we get here.
  233. */
  234. -static void vt_console_print(struct console *co, const char *b, unsigned count)
  235. +static void vt_console_print(struct console *co, const char *b, unsigned count,
  236. + unsigned int loglevel)
  237. {
  238. struct vc_data *vc = vc_cons[fg_console].d;
  239. - unsigned char c;
  240. + unsigned char current_color, c;
  241. static DEFINE_SPINLOCK(printing_lock);
  242. const ushort *start;
  243. ushort cnt = 0;
  244. @@ -2475,11 +2504,20 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
  245. start = (ushort *)vc->vc_pos;
  246. + /*
  247. + * We always get a valid loglevel - <8> and "no level" is transformed
  248. + * to <4> in the typical kernel.
  249. + */
  250. + current_color = printk_color[loglevel];
  251. + vc_set_color(vc, current_color);
  252. +
  253. +
  254. /* Contrived structure to try to emulate original need_wrap behaviour
  255. * Problems caused when we have need_wrap set on '\n' character */
  256. while (count--) {
  257. c = *b++;
  258. if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) {
  259. + vc_set_color(vc, vc->vc_def_color);
  260. if (cnt > 0) {
  261. if (CON_IS_VISIBLE(vc))
  262. vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
  263. @@ -2492,6 +2530,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
  264. bs(vc);
  265. start = (ushort *)vc->vc_pos;
  266. myx = vc->vc_x;
  267. + vc_set_color(vc, current_color);
  268. continue;
  269. }
  270. if (c != 13)
  271. @@ -2499,6 +2538,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
  272. cr(vc);
  273. start = (ushort *)vc->vc_pos;
  274. myx = vc->vc_x;
  275. + vc_set_color(vc, current_color);
  276. if (c == 10 || c == 13)
  277. continue;
  278. }
  279. @@ -2521,6 +2561,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
  280. vc->vc_need_wrap = 1;
  281. }
  282. }
  283. + vc_set_color(vc, vc->vc_def_color);
  284. set_cursor(vc);
  285. notify_update(vc);
  286. diff --git a/include/linux/console.h b/include/linux/console.h
  287. index 7571a16..af01c35 100644
  288. --- a/include/linux/console.h
  289. +++ b/include/linux/console.h
  290. @@ -118,7 +118,7 @@ static inline int con_debug_leave(void)
  291. struct console {
  292. char name[16];
  293. - void (*write)(struct console *, const char *, unsigned);
  294. + void (*write)(struct console *, const char *, unsigned, unsigned int);
  295. int (*read)(struct console *, char *, unsigned);
  296. struct tty_driver *(*device)(struct console *, int *);
  297. void (*unblank)(void);
  298. diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
  299. index be7c86b..8517cbe 100644
  300. --- a/kernel/printk/printk.c
  301. +++ b/kernel/printk/printk.c
  302. @@ -1282,7 +1282,7 @@ static void call_console_drivers(int level, const char *text, size_t len)
  303. if (!cpu_online(smp_processor_id()) &&
  304. !(con->flags & CON_ANYTIME))
  305. continue;
  306. - con->write(con, text, len);
  307. + con->write(con, text, len, level);
  308. }
  309. }
  310. @@ -1732,7 +1732,7 @@ void early_vprintk(const char *fmt, va_list ap)
  311. char buf[512];
  312. int n = vscnprintf(buf, sizeof(buf), fmt, ap);
  313. - early_console->write(early_console, buf, n);
  314. + early_console->write(early_console, buf, n, 0);
  315. }
  316. }