sysrq

要使用sysrq,需要定义SUPPORT_SYSRQ
如下所示:
438 #ifdef SUPPORT_SYSRQ
439 static inline int
440 uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
441 {
442         if (port->sysrq) {
443                 if (ch && time_before(jiffies, port->sysrq)) {
444                         handle_sysrq(ch);
445                         port->sysrq = 0;
446                         return 1;
447                 }
448                 port->sysrq = 0;
449         }
450         return 0;
451 }
452 #else
453 #define uart_handle_sysrq_char(port,ch) ({ (void)port; 0; })
454 #endif
这个函数一般在uart rx的中断函数中调用uart_handle_sysrq_char 最好的是第二个参数ch表示用户当前按下key的ascll码
uart_handle_sysrq_char 继续调用handle_sysrq出来按下的key
source/drivers/tty/sysrq.c
577 void handle_sysrq(int key)
578 {
579         if (sysrq_on())
580                 __handle_sysrq(key, true);
581 }
继续调用__handle_sysrq
524 void __handle_sysrq(int key, bool check_mask)
525 {
526         struct sysrq_key_op *op_p;
527         int orig_log_level;
528         int i;
529 
530         rcu_sysrq_start();
531         rcu_read_lock();
532         /*
533          * Raise the apparent loglevel to maximum so that the sysrq header
534          * is shown to provide the user with positive feedback.  We do not
535          * simply emit this at KERN_EMERG as that would change message
536          * routing in the consumers of /proc/kmsg.
537          */
538         orig_log_level = console_loglevel;
539         console_loglevel = CONSOLE_LOGLEVEL_DEFAULT;
540         pr_info("SysRq : ");
541 
542         op_p = __sysrq_get_key_op(key);
543         if (op_p) {
544                 /*
545                  * Should we check for enabled operations (/proc/sysrq-trigger
546                  * should not) and is the invoked operation enabled?
547                  */
548                 if (!check_mask || sysrq_on_mask(op_p->enable_mask)) {
549                         pr_cont("%s\n", op_p->action_msg);
550                         console_loglevel = orig_log_level;
551                         op_p->handler(key);
552                 } else {
553                         pr_cont("This sysrq operation is disabled.\n");
554                 }
555         } else {
556                 pr_cont("HELP : ");
557                 /* Only print the help msg once per handler */
558                 for (i = 0; i < ARRAY_SIZE(sysrq_key_table); i++) {
559                         if (sysrq_key_table[i]) {
560                                 int j;
561 
562                                 for (j = 0; sysrq_key_table[i] !=
563                                                 sysrq_key_table[j]; j++)
564                                         ;
565                                 if (j != i)
566                                         continue;
567                                 pr_cont("%s ", sysrq_key_table[i]->help_msg);
568                         }
569                 }
570                 pr_cont("\n");
571                 console_loglevel = orig_log_level;
572         }
573         rcu_read_unlock();
574         rcu_sysrq_end();
575 }
这个函数的542行拿到对应key的函数,例如按下0~9 来改变log lever.对应的hanler为sysrq_handle_loglever
然后在551行调用这个handle.
我们看看最重要的__sysrq_get_key_op实现.
504 struct sysrq_key_op *__sysrq_get_key_op(int key)
505 {
506         struct sysrq_key_op *op_p = NULL;
507         int i;
508 
509         i = sysrq_key_table_key2index(key);
510         if (i != -1)
511                 op_p = sysrq_key_table[i];
512 
513         return op_p;
514 }
其中sysrq_key_table_key2index将key转成index,很简单
488 static int sysrq_key_table_key2index(int key)
489 {
490         int retval;
491 
492         if ((key >= '') && (key <= '9'))
493                 retval = key - '';
494         else if ((key >= 'a') && (key <= 'z'))
495                 retval = key + 10 - 'a';
496         else
497                 retval = -1;
498         return retval;
499 }
得到这个index后就查询sysrq_key_table 数组得到对应key的handle。
 static struct sysrq_key_op *sysrq_key_table[36] = {
429         &sysrq_loglevel_op,             /* 0 */
430         &sysrq_loglevel_op,             /* 1 */
431         &sysrq_loglevel_op,             /* 2 */
例如1对应的op是sysrq_loglevel_op
 93 static struct sysrq_key_op sysrq_loglevel_op = {
 94         .handler        = sysrq_handle_loglevel,
 95         .help_msg       = "loglevel(0-9)",
 96         .action_msg     = "Changing Loglevel",
 97         .enable_mask    = SYSRQ_ENABLE_LOG,
 98 };
可以看到handler是sysrq_handle_loglevel,
我们再来看看sysrq_handle_loglevel具体是怎么改变log level的
 84 static void sysrq_handle_loglevel(int key)
 85 {
 86         int i;
 87 
 88         i = key - '';
 89         console_loglevel = CONSOLE_LOGLEVEL_DEFAULT;
 90         pr_info("Loglevel set to %d\n", i);
 91         console_loglevel = i;
 92 }
可以看到是通过console_loglevel 来改变kernel log level的.
如果想要定制key对应的handler,就需要来修改sysrq_key_table。改法很简单的。只要替换对应key的handle就行了
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值