如何使用Linux内核中没有被导出的变量或函数?

Linux 内核为了减少命名空间的污染,并做到正确的信息隐藏,内核提供了管理内核符号可见性的方法,没有被 EXPORT_SYMBOL 相关的宏导出的变量或函数是不能直接使用的,为了说明并解决这个问题,我们不妨先看如下一段内核模块,功能为打印超级块 super_block 结构中一些域的值。

我们知道vfs(虚拟文件系统)是用 super_block (超级块)来描述整个文件系统的信息,内核在对一个文件系统进行初始化和注册时,就为其分配了一个 super_block,该文件系统卸载时,其对应的 super_block 也会被自动删除。super_block 结构中有一个 list_head 类型的字段 s_list 用来把系统中的 super_block 组成一个双向循环链表,并使用一个叫做 super_ blocks 的全局变量来指向该双向循环链表中的第一个元素。super_block 中还有一个叫做 s_inodes 的字段,指向链接该超级块中所有的 inode 的链表 i_sb_list。我们也使用了自旋锁 spin_lock 对链表的相关操作进行了加锁,保护共享变量,现在看内核模块:

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/kdev_t.h>
#include <linux/kallsyms.h>  //方法二

/*
 *方法二,使用kallsyms_lookup_name()查找函数或变量的虚拟地址
 *使用时,需要注释其它方法的代码,取消此处及下面方法二的注释
  spinlock_t * sb_lock_address;
  struct list_head * super_blocks_address;
 */

/*
 *方法三,内核模块中直接使用内核函数的虚拟地址
 *使用时,需要注释其他方法的代码,取消此处及下面方法三的注释
  #define SUPER_BLOCKS_ADDRESS 0xffffffff91d2efe0
  #define SB_LOCK_ADDRESS 0xffffffff922f35d4
 */

static int __init my_init(void)
{  
    struct super_block *sb;  
    struct list_head *pos;
    struct list_head *linode;
    struct inode *pinode;
    unsigned long long count = 0;
	
    printk("\nPrint some fields of super_blocks:\n");

/*
    *方法二
    sb_lock_address = (spinlock_t *)kallsyms_lookup_name("sb_lock");
    super_blocks_address = (struct list_head *)kallsyms_lookup_name("super_blocks");
    spin_lock(sb_lock_address);
    list_for_each(pos, super_blocks_address) {
    */
    
    /*
     *方法三
     spin_lock((spinlock_t *)SB_LOCK_ADDRESS);
     list_for_each(pos, (struct list_head *)SUPER_BLOCKS_ADDRESS) {
     */
      
/*此处使用了未导出变量,若使用方法二或方法三时需要注释以下两行*/
    spin_lock(&sb_lock);  //加锁,此处使用了未导出的变量
	list_for_each(pos, &super_blocks) {
	
        sb = list_entry(pos, struct super_block, s_list);  
        printk("dev_t:%d:%d", MAJOR(sb->s_dev),MINOR(sb->s_dev));
        //打印文件系统所在设备的主设备号和次设备号
        printk("file_type name:%s\n", sb->s_type->name);
        //打印文件系统名

        list_for_each(linode, &sb->s_inodes) {
	        pinode=list_entry(linode, struct inode, i_sb_list);
	        count++;
	        printk("%lu\t", pi
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值