分类: LINUX
2017-06-27 19:43:51
It is a 'magical' key combo you can hit which the kernel will respond to regardless of whatever else it is doing, unless it is completely locked up.
在linux系统下,我们有时候会碰到命令卡(hang)住的问题,这时候无法再输入命令,那么对我们调试问题就会造成影响,幸好linux一种后门机制,可以在命令hang住的时候打印一些内核信息,这个机制就是sysrq
具体描述我们可以查看内核文档
root@99-252:~/linux-3.10.70/Documentation# vi sysrq.txt
step1: enable kernel config
Symbol: MAGIC_SYSRQ [=y]
| Type : boolean
| Prompt: Magic SysRq key
| Location:
| (1) -> Kernel hacking
| Defined at lib/Kconfig.debug:55 | Depends on: !UML | Selected by: KGDB_SERIAL_CONSOLE [=y] && KGDB [=y] && TTY [=y]
step2: make sure sysrq open
确认sysrq是否是非0,非0则代表启用,可以通过快捷键触发进入sysrq,如果sysrq=1,则代表允许任何请求,sysrq等于其他值可以选择性开启部分功能. 不同的cpu平台的快捷键也不一样
/proc/sys/kernel # ls -al -rw-r--r-- 1 root 0 0 Mar 23 14:36 sysrq
/proc/sys/kernel # cat sysrq 1 // sysrq写0则关闭此功能 /proc/sys/kernel # echo "0" > sysrq
method1: 使用终端进入sysrq功能
以arm平台为例,可以在终端(like secureCRT)通过键盘组合键ctrl+pause, 5s内输入命令字符执行相应的sysrq功能.
method2: shell
/ # echo "h" >/proc/sysrq-trigger SysRq : HELP : loglevel(0-9) reboot(b) crash(c) terminate-all-tasks(e) memory-full-oom-kill(f) kill-all-tasks(i) thaw-filesystems(j) sak(k) show-backtrace-all-active-cpus(l) show-memory-usage(m) nice-all-RT-tasks(n) poweroff(o) show-registers(p) show-all-timers(q) unraw(r) sync(s) show-task-states(t) unmount(u) show-blocked-tasks(w) / #
键盘上所有的按键都有扫描码和虚拟码,扫描码由键盘硬件发至设备的键盘驱动,键盘驱动会将扫描码转换成统一的虚拟码,屏蔽掉厂家差异。
ctrl + 字母的ASCII码 = 字母的ASCII码 & 0x1f
linux kernel 如何识别sysrq
// 在串口接收字符处理函数中会调用break处理函数 unsigned char serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) { uart_handle_break(port) uart_handle_sysrq_char(port, ch) } // break处理函数的实现,实际上调用了uart_port的break处理 static inline int uart_handle_break(struct uart_port *port) { struct uart_state *state = port->state; if (port->handle_break) port->handle_break(port); #ifdef SUPPORT_SYSRQ if (port->cons && port->cons->index == port->line) { if (!port->sysrq) { port->sysrq = jiffies + HZ*5; return 1; } port->sysrq = 0; } #endif if (port->flags & UPF_SAK) do_SAK(state->port.tty); return 0; } // 处理sysrq的字符,如果超时则不处理 static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) { if (port->sysrq) { if (ch && time_before(jiffies, port->sysrq)) { handle_sysrq(ch); port->sysrq = 0; return 1; } port->sysrq = 0; } return 0; } // sysrq.c 中处理sysrq命令 static struct sysrq_key_op *sysrq_key_table[36] = { &sysrq_loglevel_op, /* 0 */ &sysrq_loglevel_op, /* 1 */ &sysrq_loglevel_op, /* 2 */ &sysrq_loglevel_op, /* 3 */ &sysrq_loglevel_op, /* 4 */ &sysrq_loglevel_op, /* 5 */ &sysrq_loglevel_op, /* 6 */ &sysrq_loglevel_op, /* 7 */ &sysrq_loglevel_op, /* 8 */ &sysrq_loglevel_op, /* 9 */ /* * a: Don't use for system provided sysrqs, it is handled specially on * sparc and will never arrive. */ NULL, /* a */ &sysrq_reboot_op, /* b */ &sysrq_crash_op, /* c & ibm_emac driver debug */ &sysrq_showlocks_op, /* d */ &sysrq_term_op, /* e */ &sysrq_moom_op, /* f */ /* g: May be registered for the kernel debugger */ NULL, /* g */ NULL, /* h - reserved for help */ &sysrq_kill_op, /* i */ #ifdef CONFIG_BLOCK &sysrq_thaw_op, /* j */ #else NULL, /* j */ #endif &sysrq_SAK_op, /* k */ #ifdef CONFIG_SMP &sysrq_showallcpus_op, /* l */ #else NULL, /* l */ #endif &sysrq_showmem_op, /* m */ &sysrq_unrt_op, /* n */ /* o: This will often be registered as 'Off' at init time */ NULL, /* o */ &sysrq_showregs_op, /* p */ &sysrq_show_timers_op, /* q */ &sysrq_unraw_op, /* r */ &sysrq_sync_op, /* s */ &sysrq_showstate_op, /* t */ &sysrq_mountro_op, /* u */ /* v: May be registered for frame buffer console restore */ NULL, /* v */ &sysrq_showstate_blocked_op, /* w */ /* x: May be registered on ppc/powerpc for xmon */ /* x: May be registered on sparc64 for global PMU dump */ NULL, /* x */ /* y: May be registered on sparc64 for global register dump */ NULL, /* y */ &sysrq_ftrace_dump_op, /* z */ };