AIX内核扩展编程2

31 篇文章 1 订阅
4 篇文章 0 订阅

复杂度3/5
机密度4/5

最后更新2021/05/18

下面我们要研究被加载程序本身,这和普通c程序没什么太大区别,当然,区别还是有一些的,例如没有main。普通C程序本身,省缺会需要main函数,作为程序入口,而内核扩展程序是通过链接时定义,决定哪个函数是主入口的。甚至可能完全没有入口,只等待其它内核程序调用自己提供的扩展函数。我们先考虑最普通的内核扩展,也就是需要一个入口,需要进行初始化的内核扩展程序。下面的程序看起来与普通的C没什么不同是吧?其中几个主要区别我们说一下:

  1. 没有main,这个说过了,内核扩展本身没有main;
  2. 所有log输出,要走bsdlog,因为作为内核扩展,是没有stdout/stderr这种东西的,linux使用printk在内核里分几k的空间实现,aix没有这种机制(可以自己做一个),一般用bsdlog把信息打印出来,示范程序中将打印DEBUG和KERN两种信息;
  3. 当前kernel extension本身不需要pincode,所谓pincode是把代码“固定”在内存里,而不会交换出内存到磁盘。如果kernel extension的操作与磁盘交换有关而又没有pin在内存,就可能会出现因data store interrupt重入而死掉;当然,对于与磁盘交换完全无关的kernel extension(例如本例:其实啥都没干。。。),pincode不是必要的操作,而且如果使用了pincode,那么所有的退出出口前,必须记得unpin释放内存;
  4. 从这个例子里可以看到,对应的入口命令CFG_INIT和CFG_TERM是自己解释的,也就是由加载程序和被加载程序二者之间协商一致,通过内核sysconfig系统调用直接传送过来,并不进行额外解读,因此可以自己自由定义。同时还有入口的输入结构uio和长度,其实也是如此,但在本例中未涉及到更复杂的结构数据传送,再后续继续深入分析。
/* myExtension.c */
#include <strings.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/syslog.h>
#include <sys/device.h>
#include <sys/pin.h>
#include <sys/thread.h>
#include <sys/signal.h>
#include <unistd.h>

int myEntry(int const cmd, struct uio* const uio_buf)
{
    int rc = 0;
    bsdlog(LOG_DEBUG|LOG_KERN,"Enter myEntry: command = 0x%d   \n",cmd);
    if( cmd == CFG_INIT )
    {
        bsdlog(LOG_DEBUG|LOG_KERN,"Initializing my Kernal Extension \n");
        rc = pincode( (int (*)())myEntry);
        if( rc )
        {
           bsdlog(LOG_DEBUG|LOG_KERN,"pincode failed with rc=%d\n",rc);
           return rc;
        }
    }
    else if( cmd == CFG_TERM )
    {
        bsdlog(LOG_DEBUG|LOG_KERN,"Terminating my Kernal Extension \n");
        rc = unpincode(myEntry);
        if( rc )
        {
bsdlog(LOG_DEBUG|LOG_KERN,"Failed to unpin the code. rc = %d\n", rc );
        }
    }
    return 0;
}
/*最后这个函数是demo,作为新支持的系统调用提供 */
int test_syscall( int arg )
{
 bsdlog(LOG_DEBUG|LOG_KERN,"In test_syscall: recevied arg %d.....\n",arg);
 return 0;
}

关于bsdlog的使用:

  1. 先生成一个“种子”log文件
# touch /tmp/testbsd.log
  1. 通过在syslog中定义使用此log文件
#cat /etc/syslog.conf
...
    kern.debug /tmp/testbsd.log rotate size 100K files 4
...

以上信息告诉syslog将kern和debug类型的bsdlog写入到/tmp/testbsd.log文件,此文件最多4个,循环使用,每个大小为100k,记录内核的DEBUG信息,这与示范程序中LOG_KERN | LOG_DEBUG对应。

  1. 刷新syslog使对syslog.conf的修改生效
#refresh -s syslogd

注意,bsdlog不是同步的,最后写入文件会有一定(几秒)延时,特别在多线程情况下,不能保证时间前后一致,但对于单一线程,还是能确保前后一致的,只是可能整体滞后几秒。由于调试kernel经常出现死机情况,log仅作为执行参考,而死机还是需要通过dump分析去判定具体位置和原因。

下面继续介绍内核扩展编译makefile和相关问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ensighine

如需特定专题,踢我

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值