自己写一个linux的系统调用

知识背景:
一.SWI:软中断指令, 可以从用户空间切换到系统空间。
 以用户空间的read函数操做流程分析:
 1.用户空间的read调用会对应一个内核空间的read调用。
 2.从用户空间切换到内核空间需要用到一个指令SWI。
 3.切换到内核空间之后会取相对应的系统调用的编号,这个编号是随SWI指令传进来的。
 4.在内核里面会维护一张系统调用表,表中的每个系统调用对应一个系统编号。
二.ENTRY(vector_swi)在entry_common.S文件中。
三.用户空间总是将系统编号放进R7当中,然后内核会通过调用SWI指令将系统切换到内核态,然后将R7中的系统编号取出放入scno中,
   然后内核会根据scno的值从系统调用表中取出相对应的系统调用。


实验步骤:
  一.比如写类似printk函数功能的函数。在kernel文件夹里面的printk.c里面写
    例如: void sys_pk()
{
printk("this is a new sys_call!\n");
}      

  二.然后修改calls.s(/arch/arm/kernel)在最后面修改
  三.然后在Unistd.h(/arch/arm/include/asm)做和在calls.s一样的修改。
  
代码分析:
在entry_common.S中会有一行代码ENTRY(vector_swi),这部分代码是内核专门用来响应SWI指令,如下:
#elif defined(CONFIG_ARM_THUMB)


/* Legacy ABI only, possibly thumb mode. */
tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs
addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in
ldreq scno, [lr, #-4]


#else
/* Legacy ABI only. */
ldr scno, [lr, #-4] @ get SWI instruction
  A710( and ip, scno, #0x0f000000 @ check for SWI )
  A710( teq ip, #0x0f000000 )
  A710( bne .Larm710bug )
#endif

在这部分代码中是从R7中取出系统编号,放入在scno,然后从系统调用表中调出相关的系统调用
代码实现为 ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine


实验结果:自己写系统调用不成功。原因分析:不明??

你可能感兴趣的:(linux,linux,linux,kernel)