Linux内核(十五)sysrq 详解 II —— 代码框架详解

news/2024/5/18 21:30:23 标签: linux, sysrq, 驱动开发, sysrq模块, 流程图

文章目录


Linux 版本:Linux version 3.18.24

sysrq_5">sysrq模块初始化流程图

sysrq模块源码路径:linux-3.18.24.x/drivers/tty/sysrq.c
编译开启:CONFIG_MAGIC_SYSRQ=y
在这里插入图片描述


sysrq_11">sysrq模块代码详解

1、sysrq模块初始化

static int __init sysrq_init(void)
{
    sysrq_init_procfs();                // 创建sysrq在proc下节点

    if (sysrq_on())                    // 每个linux版本不一样,红帽企业版Linux是需要控制的
        sysrq_register_handler();      // 注册sysrq的处理函数

    return 0;
}
module_init(sysrq_init);

2、创建sysrq在proc下节点:sysrq_init_procfs

static const struct file_operations proc_sysrq_trigger_operations = {
    .write      = write_sysrq_trigger,                // 写回调函数
    .llseek     = noop_llseek,
};

static void sysrq_init_procfs(void)
{
    if (!proc_create("sysrq-trigger", S_IWUSR, NULL,            // 在proc下创建sysrq-trigger节点,并注册文件操作结构体
             &proc_sysrq_trigger_operations))
        pr_err("Failed to register proc interface\n");
}

3、本linux系统内,proc下sysrq事件的回调函数注册始终是打开的:sysrq_on()

static int __read_mostly sysrq_enabled = CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE;   // #define CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE 0x1

static bool sysrq_on(void)
{
    return sysrq_enabled || sysrq_always_enabled;            // sysrq始终都是打开的
}

static int __init sysrq_always_enabled_setup(char *str)
{
    sysrq_always_enabled = true;                            // sysrq_always_enabled始终都是打开的
    pr_info("sysrq always enabled.\n");

    return 1;
}

__setup("sysrq_always_enabled", sysrq_always_enabled_setup);    // 系统启动时自动执行

4、注册sysrq事件的回调函数:sysrq_register_handler

static inline void sysrq_register_handler(void)
{
    unsigned short key;
    int error;
    int i;

    // 首先检查是否实例化了_weak接口。
    for (i = 0; i < ARRAY_SIZE(sysrq_reset_seq); i++) {
        key = platform_sysrq_reset_seq[i];
        if (key == KEY_RESERVED || key > KEY_MAX)
            break;

        sysrq_reset_seq[sysrq_reset_seq_len++] = key;
    }

    // DT构型优先于任何已经通过弱接口定义。
    sysrq_of_get_keyreset_config();

    // 注册input回调
    error = input_register_handler(&sysrq_handler);
    if (error)
        pr_err("Failed to register input handler, error %d", error);
    else
        sysrq_handler_registered = true;
}

sysrqkernel_crash_91">sysrq产生kernel crash事件流程

在串口终端上,能直接将CommandKey写入/proc/sysrq-trigger文件流程
如:echo ‘c’ > sysrq-trigger 产生一个kernel crash
当执行命令之后,会调用proc写回调函数:write_sysrq_trigger

static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
                   size_t count, loff_t *ppos)
{
    if (count) {
        char c;

        if (get_user(c, buf))                // 从用户端获取传入的字符串
            return -EFAULT;
        __handle_sysrq(c, false);            // 调用处理函数
    }

    return count;
}

处理函数__handle_sysrq解析:

void __handle_sysrq(int key, bool check_mask)
{
    struct sysrq_key_op *op_p;
    int orig_log_level;
    int i;

    rcu_sysrq_start();
    rcu_read_lock();
    
    orig_log_level = console_loglevel;            // 使用默认等级#define CONSOLE_LOGLEVEL_DEFAULT 7 /* anything MORE serious than KERN_DEBUG */
    console_loglevel = CONSOLE_LOGLEVEL_DEFAULT;    // 输出到终端
    printk(KERN_INFO "SysRq : ");

        op_p = __sysrq_get_key_op(key);            // 找到sysrq_key_table表中对应结构体
                -> i = sysrq_key_table_key2index(key);    // 通过传入的key值(例中为'c')转为sysrq_key_table表中索引值
                -> op_p = sysrq_key_table[i];       // 获取对应结构体(sysrq_key_table表在下个函数解析)(例中'c'对应为sysrq_crash_op)
        if (op_p) {
        if (!check_mask || sysrq_on_mask(op_p->enable_mask)) {
            printk("%s\n", op_p->action_msg);        
            console_loglevel = orig_log_level;
            op_p->handler(key);            // 执行结构体中的处理函数
        } else {
            printk("This sysrq operation is disabled.\n");
        }
    } else {
        ......
    }
    rcu_read_unlock();
    rcu_sysrq_end();
}

sysrq_key_table表包含36个sysrq_key_op结构体指针(对应传入key值为‘0’ — ‘9’,‘a’ — ‘z’)

struct sysrq_key_op {
        void (*handler)(int);        // 处理函数
        char *help_msg;            // 帮助信息
        char *action_msg;            // 相关动作信息
        int enable_mask;            // 使能掩码
};

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_showstate_blocked_op,    /* w */
    NULL,               /* x */
    NULL,               /* y */
    &sysrq_ftrace_dump_op,      /* z */
};

例子中,用户层传入‘c’ 对应的结构体是sysrq_crash_op

// 触发一个系统crash的处理函数
static void sysrq_handle_crash(int key)
{
    char *killer = NULL;

    panic_on_oops = 1;      /* force panic */
    wmb();
    *killer = 1;
}
static struct sysrq_key_op sysrq_crash_op = {
    .handler    = sysrq_handle_crash,
    .help_msg   = "crash(c)",
    .action_msg = "Trigger a crash",
    .enable_mask    = SYSRQ_ENABLE_DUMP,
};

sysrq__204">sysrq 整体框架图

在这里插入图片描述


sysrq__209">sysrq 框架中添加自定义实例

diff --git a/linux-3.18.24.x/drivers/tty/sysrq.c b/linux-3.18.24.x/drivers/tty/sysrq.c
index 42bad18c6..a156551d3 100755
--- a/linux-3.18.24.x/drivers/tty/sysrq.c
+++ b/linux-3.18.24.x/drivers/tty/sysrq.c
@@ -408,6 +408,18 @@ static struct sysrq_key_op sysrq_unrt_op = {
        .enable_mask    = SYSRQ_ENABLE_RTNICE,
 };

+static void sysrq_handle_dwb(int key)
+{
+       console_loglevel = CONSOLE_LOGLEVEL_DEFAULT;
+       printk("sysrq_handle_dwb test ok. \n");
+}
+static struct sysrq_key_op sysrq_dwb_op = {
+       .handler        = sysrq_handle_dwb,
+       .help_msg       = "dwb test",
+       .action_msg     = "dwb",
+       .enable_mask    = SYSRQ_ENABLE_DUMP,
+};
+
 /* Key Operations table and lock */
 static DEFINE_SPINLOCK(sysrq_key_table_lock);

@@ -451,7 +463,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
        &sysrq_showmem_op,              /* m */
        &sysrq_unrt_op,                 /* n */
        /* o: This will often be registered as 'Off' at init time */
-       NULL,                           /* o */
+       &sysrq_dwb_op,                          /* o */
        &sysrq_showregs_op,             /* p */
        &sysrq_show_timers_op,          /* q */
        &sysrq_unraw_op,                /* r */


http://www.niftyadmin.cn/n/334612.html

相关文章

内网渗透之权限维持-黄金白银票据隐藏账户远控-RustDeskGotoHTTP

0x01权限维持-隐藏用户 CreateHiddenAccount工具 CreateHiddenAccount -u test -p Psswrd用户管理能查看到&#xff0c;命令查看看不到&#xff0c;单机版无法删除(不在任何组)&#xff0c;域环境(在administrator组中)可以删除 0x02权限维持-黄金白银票据 ⻩⾦票据⽣成攻…

Python学习29:存款买房(B)

描述‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬ 你刚刚大学毕业&#xff0c;…

MySQL入门第六课:单表无条件/有条件和多表无条件/有条件查询(难点)

查找单列数据 select 字段名 from 表名 查找并更改字段名输出(不在原表里更改) select 字段名1中文名1&#xff0c;字段名2中文名2...... from 表名 删除重复值并输出 select distinct 重复的字段名 from 表名 order by 字段名排序 desc降序 不填就是升序 limit 索引(如果…

网络安全实验——信息收集与主机发现

目录 实验目的 实验原理 实验内容 1.信息搜集 1.ping探测 2. Nmap扫描 3. 探测总结 2.主机发现程序开发 3.主机发现 实验总结 实验目的 1.了解信息搜集的一般步骤。 2.学会熟练使用ping命令。 3.学会利用Nmap等工具进行信息搜集。 4.了解IP助手函数。 5.掌握Sen…

GPT大语言模型Vicuna本地化部署实践(效果秒杀Alpaca) | 京东云技术团队

​ 背景 上一篇文章《[GPT大语言模型Alpaca-lora本地化部署实践]》介绍了斯坦福大学的Alpaca-lora模型的本地化部署&#xff0c;并验证了实际的推理效果。 总体感觉其实并不是特别理想&#xff0c;原始Alpaca-lora模型对中文支持并不好&#xff0c;用52k的中文指令集对模型进…

Bitcoin的Segwit地址

Segwit地址又称隔离见证地址。在Bitcoin Blockchain上,经常可以看到类似bc1qmy63mjadtw8nhzl69ukdepwzsyvv4yex5qlmkd这样的以bc开头的地址,这种地址就是隔离见证地址。 Segwit地址有好几种,一种是以3开头的隔离见证兼容地址(Nested Segwit Address),从该地址上无法区分…

David Silver Lecture 8: Integrating Learning and Planning

1 Introduction 1.1 Model based Reinforcement Learning 1.2 model based and model free RL 2 Model-Based Reinforcement Learning 2.1 outline 2.2 Learning a model 2.2.1 what is a model model主要是指&#xff0c;state transitions和相应的reward。 2.2.2 Model…

JCJC句子改写在线工具上线-202305

JCJC句子改写在线工具上线-202305 字根科技发布了新版JCJC在线句子改写功能。 使用网址&#xff1a; JCJC在线句子改写 新版的在线中文句子改写一共分为三种模式&#xff1a; 严谨模式普通模式休闲模式 上述三种改写模式适用于不同的改写需求&#xff0c;界面展示如下&…