Messages in this thread Patches in this message | | | Date | Sat, 13 Sep 1997 21:07:24 +0200 | From | Pavel Machek <> | Subject | Magic 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;
| |