lkml.org 
[lkml]   [1997]   [Sep]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patches in this message
/
Date
From
SubjectMagic sysrq over serial & more
Hi!

This code allows you to use Magic SysRq keys even over serial
port. Really nice for machines with no keyboard ;-).

It also adds new features to to magic sysrq keys, some of them
(SysRq-O) pretty dangerous. Make sure you know what you are doing.

Patch is against 2.1.55.
Pavel


--- clean/drivers/char/serial.c Sat Aug 16 18:53:03 1997
+++ linux/drivers/char/serial.c Sat Aug 16 18:48:59 1997
@@ -22,6 +22,9 @@
* 1/97: Extended dumb serial ports are a config option now.
* Saves 4k. Michael A. Griffith <grif@acm.org>
*
+ * 7/97: Console on serial port can now be used to invoke magic
+ * keys. Pavel Machek <pavel@atrey.karlin.mff.cuni.cz>
+ *
* This module exports the following rs232 io functions:
*
* int rs_init(void);
@@ -115,6 +118,13 @@
#endif
#endif

+/* This defines the index into rs_table for the port to use for serial
+ * console
+ */
+#ifndef CONFIG_SERIAL_CONSOLE_PORT
+#define CONFIG_SERIAL_CONSOLE_PORT 0
+#endif
+
/* Set of debugging defines */

#undef SERIAL_DEBUG_INTR
@@ -471,11 +485,23 @@
int ignored = 0;
struct async_icount *icount;

+
icount = &info->state->icount;
do {
ch = serial_inp(info, UART_RX);
if (tty->flip.count >= TTY_FLIPBUF_SIZE)
break;
+
+#ifdef CONFIG_SERIAL_CONSOLE
+#ifdef CONFIG_MAGIC_SYSRQ
+ if (info->flags & ASYNC_WASBREAK) {
+ info->flags &= ~ASYNC_WASBREAK;
+ handle_sysrq( ch, NULL, NULL, tty );
+ goto ignore_char;
+ }
+#endif
+#endif
+
*tty->flip.char_buf_ptr = ch;
icount->rx++;

@@ -498,6 +524,16 @@
if (*status & UART_LSR_OE)
icount->overrun++;

+#ifdef CONFIG_SERIAL_CONSOLE
+#ifdef CONFIG_MAGIC_SYSRQ
+ /* Check for magic on serial */
+ if (((rs_table + CONFIG_SERIAL_CONSOLE_PORT)->info == info)
+ && (*status & (UART_LSR_BI))) {
+ info->flags |= ASYNC_WASBREAK;
+ }
+#endif
+#endif
+
/*
* Now check to see if character should be
* ignored, and mask off conditions which
@@ -3480,13 +3516,6 @@
#ifdef CONFIG_SERIAL_CONSOLE

#include <linux/console.h>
-
-/*
- * this defines the index into rs_table for the port to use
- */
-#ifndef CONFIG_SERIAL_CONSOLE_PORT
-#define CONFIG_SERIAL_CONSOLE_PORT 0
-#endif

#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)

--- clean/include/linux/serial.h Thu Jul 17 05:16:34 1997
+++ linux/include/linux/serial.h Thu Aug 21 15:12:48 1997
@@ -89,7 +89,7 @@
#define ASYNC_USR_MASK 0x1430 /* Legal flags that non-privileged
* users can set or reset */

-/* Internal flags used only by kernel/chr_drv/serial.c */
+/* Internal flags used only by drivers/char/serial.c */
#define ASYNC_INITIALIZED 0x80000000 /* Serial port was initialized */
#define ASYNC_CALLOUT_ACTIVE 0x40000000 /* Call out device is active */
#define ASYNC_NORMAL_ACTIVE 0x20000000 /* Normal device is active */
@@ -98,8 +98,10 @@
#define ASYNC_CTS_FLOW 0x04000000 /* Do CTS flow control */
#define ASYNC_CHECK_CD 0x02000000 /* i.e., CLOCAL */
#define ASYNC_SHARE_IRQ 0x01000000 /* for multifunction cards */
+#define ASYNC_CONSOLE 0x00800000 /* Is this port configured as console? */
+#define ASYNC_WASBREAK 0x00400000 /* Did we notice break before this char? */

-#define ASYNC_INTERNAL_FLAGS 0xFF000000 /* Internal flags */
+#define ASYNC_INTERNAL_FLAGS 0xFFC00000 /* Internal flags */

/*
* Multiport serial configuration structure --- external structure
@@ -216,7 +218,8 @@
/*
* The size of the serial xmit buffer is 1 page, or 4096 bytes
*/
-#define SERIAL_XMIT_SIZE 4096
+#define SERIAL_XMIT_SIZE 1024
+//4096

/*
* Events are used to schedule things to happen at timer-interrupt
--- clean/drivers/char/sysrq.c Thu Aug 7 00:51:57 1997
+++ linux/drivers/char/sysrq.c Mon Aug 25 22:07:46 1997
@@ -19,6 +19,9 @@
#include <linux/reboot.h>
#include <linux/sysrq.h>
#include <linux/kbd_kern.h>
+#include <linux/tty.h>
+#include <linux/delay.h>
+
#include <asm/ptrace.h>
#include <asm/smp_lock.h>

@@ -55,6 +58,8 @@
* and any other keycode arrives.
*/

+void **eaten_memory;
+
void handle_sysrq(int key, struct pt_regs *pt_regs,
struct kbd_struct *kbd, struct tty_struct *tty)
{
@@ -63,17 +68,71 @@
console_loglevel = 7;
printk(KERN_INFO "SysRq: ");
switch (key) {
- case 'r': /* R -- Reset raw mode */
- if (kbd) {
- kbd->kbdmode = VC_XLATE;
- printk("Keyboard mode set to XLATE\n");
+ case 'w': /* W -- eat physical memory */
+ {
+ int i = 0;
+ void **c= eaten_memory, *m;
+ printk( "Eating pages " );
+ while ((m = kmalloc( 3500, GFP_ATOMIC )))
+ {
+ eaten_memory = m;
+ printk( "." );
+ *eaten_memory = c;
+ c = eaten_memory;
+ i++;
+ }
+ printk( "(%dK)\n", i*4 );
+ }
+ break;
+ case 'q': /* Q -- return physical memory */
+ {
+ int i = 0;
+ void **c = eaten_memory, *f;
+ printk( "Freeing pages " );
+ while (c)
+ {
+ printk( "." );
+ f = *c;
+ c = *c;
+ if (f) { kfree( f ); i++; }
+ }
+ printk( "(%dK)\n", i*4 );
+ eaten_memory = NULL;
+ }
+ break;
+ case 'j': /* J -- Set jiffies to -10 sec */
+ printk( "Setting Jiffies\n" );
+ jiffies = 0xFFFFFFFF - 10*HZ;
+ break;
+ case 'c': /* C -- Cli & sleep for 10 sec */
+ {
+ unsigned long flags;
+ int i;
+ printk( "Halting in cli:" );
+ save_flags( flags ); cli();
+ for (i=0; i<10; i++) { printk( "." ); cli(); udelay( 1000000 ); }
+ restore_flags( flags );
+ printk( "ok?\n" );
}
break;
+ case 'f': /* F -- freeze computer totally */
+ printk("Freezing...");
+ cli();
+ while(1);
+ printk("failed?!\n");
+#ifdef CONFIG_VT
+ case 'r': /* R -- Reset raw mode */
+ if (kbd) { kbd->kbdmode = VC_XLATE; printk("Keyboard mode set to XLATE\n"); }
+ break;
+#endif
case 'a': /* A -- SAK */
- printk("SAK\n");
- if (tty)
- do_SAK(tty);
- reset_vc(fg_console);
+ if (tty) {
+ printk("SAK\n");
+ do_SAK(tty);
+#ifdef CONFIG_VT
+ reset_vc(fg_console);
+#endif
+ }
break;
case 'b': /* B -- boot immediately */
printk("Resetting\n");
@@ -115,8 +174,9 @@
show_mem();
break;
case '0' ... '9': /* 0-9 -- set console logging level */
- orig_log_level = key - '0';
- printk("Log level set to %d\n", orig_log_level);
+ key -= '0';
+ orig_log_level = key;
+ printk("Log level set to %d\n", key);
break;
case 'e': /* E -- terminate all user processes */
printk("Terminate All Tasks\n");
@@ -128,20 +188,29 @@
send_sig_all(SIGKILL, 0);
orig_log_level = 8;
break;
- case 'l': /* L -- kill all processes including init */
+ case 'l': /* L -- kill processes (incl. init) */
printk("Kill ALL Tasks (even init)\n");
send_sig_all(SIGKILL, 1);
orig_log_level = 8;
break;
+ case 'o':
+ printk("Oops-ing\n"); /* O -- induce an Oops */
+ die_if_kernel( "Oops requested by user", pt_regs, 0 );
+ break;
default: /* Unknown: help */
- printk("unRaw sAk Boot "
+ printk(
+#ifdef CONFIG_VT
+ "unRaw "
+#endif
+ "sAk Boot "
#ifdef __sparc__
"Halt "
#endif
#ifdef CONFIG_APM
"Off "
#endif
- "Sync Unmount showPc showTasks showMem loglevel0-8 tErm Kill killalL\n");
+ "W:eat Q:return Jiffies Cli&10sec Freeze "
+ "Sync Unmount showPc showTasks showMem loglevel0-8 tErm Kill killalL Oops\n");
}

console_loglevel = orig_log_level;
\
 
 \ /
  Last update: 2005-03-22 13:40    [W:0.413 / U:0.128 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site