把29th_app_system_callkernel里的文件复制到内核目录syscallsh==>includelinuxread_writec==>fscallsS==>arch
把29th_app_system_call\kernel里的文件复制到内核目录
syscalls.h ==> include/linux
read_write.c ==> fs/
calls.S ==> arch/arm/kernel
解析:当应用程序调用open、read、write函数时会履行swi val指令,然后引发一个反常,就像中止相同,就会进入内核的反常处理函数里边,依据不同的val值来调用sys_open、sys_read、sys_write(虚拟文件体系VFS),并依据操作不同的文件特点(C:字符型设备,主设备号)在chrdev数组中找到file_operations类型的结构体指针,经过file_operations结构体指针找到对应的open、read、write(first_drv_open,first_drv_write)驱动函数。能够使用驱动程序检查应用程序傍边全局变量、局部变量的信息,并打印出来。
故首先在calls.S 中:
// 350
CALL(sys_timerfd)
CALL(sys_eventfd)
CALL(sys_hello) //添加sys_hello的注册
再在read_write.c 中完成sys_hello函数体:
asmlinkage void sys_hello(const char __user * buf, int count)
{
char ker_buf[100];
if (buf)
{
copy_from_user(ker_buf, buf, (count < 100) ? count : 100);
ker_buf[99] = \0;
printk(“sys_hello: %s\n”, ker_buf);
}
}
在syscalls.h中声明:
asmlinkage void sys_hello(const char __user * buf, int count);
再模仿glib.c中open、read等仿写hello函数:
void hello(char *buf, int count)
{
// swi //
asm (“mov r0, %0\n” // save the argment in r0 //
“mov r1, %1\n” // save the argment in r0 //
“swi %2\n” // do the system call //
:
: “r”(buf), “r”(count), “i” (__NR_SYSCALL_BASE + 352)
: “r0”, “r1”);
}
再在应用程序中调用hello函数:
int main(int argc, char **argv)
{
printf(“in app, call hello\n”);
hello(“www.100ask.net”, 15);
return 0;
}
以上只是在应用程序调用hello函数时发生SWI中止后使用驱动程序sys_hello打印传入的字符串,也能够修正应用程序编译后发生可履行文件中的机器码,替换成swi指令,使用swi指令进入sys_hello,在sys_hello中打印调查应用程序傍边的变量信息,再履行被替换的指令后回来,如下:
asmlinkage void sys_hello(const char __user * buf, int count)
{
int val;
struct pt_regs *regs;
// 1. 输出一些调试信息 //
// 应用程序test_sc的反汇编里: 0001078c : //
// 应用程序test_sc_sleep的反汇编里: 000107c8 : //
//copy_from_user(&val, (const void __user *)0x0001078c, 4);
copy_from_user(&val, (const void __user *)0x000107c8, 4);
printk(“sys_hello: cnt = %d\n”, val);
// 2. 履行被替换的指令: add r3, r3, #2 ; 0x2 //
// 搜 pt_regs , 在它的成果里再搜 current //
regs = task_pt_regs(current);
regs->ARM_r3 += 2;
// 打印局部变量i //
copy_from_user(&val, (const void __user *)(regs->ARM_fp – 16), 4);
printk(“sys_hello: i = %d\n”, val);
// 3. 回来 //
return;
}
被用于测验的应用程序如下:
while (1)
{
printf(“Hello, cnt = %d, i = %d\n”, cnt, i);
cnt++;
i = i + 2;
sleep(5);
}
修正了可履行文件的i = i + 2; 替换为swi指令进入sys_hello,再回来。
声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ziliao/zhudong/263414.html