【问题标题】:Extending the Rasbian Kernel (Linux Kernel 3.10.28) for Arm / Raspberry PI - How to correctly add own system calls?为 Arm / Raspberry PI 扩展 Rasbian Kernel (Linux Kernel 3.10.28) - 如何正确添加自己的系统调用?
【发布时间】:2016-10-03 22:23:45
【问题描述】:

我需要向 Raspbian Linux 内核添加一个自己的系统调用。现在我在搜索了大约 2 天以找到解决方案后被卡住了。

要添加系统调用,我基本上是按照大致的大纲 (http://elinux.org/RPi_Kernel_Compilation) 使用来自以下 git repo 的内核源代码:

git://github.com/raspberrypi/tools.git

我已经使用 crosstool-ng (http://www.kitware.com/blog/home/post/426) 安装了交叉编译环境。

以上所有这些都有效。我能够编译和部署一个新内核。我还能够为 Raspbian 进行交叉编译。

我正在尝试添加一个“hello world”系统调用。该函数位于其自己的实现文件(kernel/helloworld.?)中,并实现为:

helloworld.c:

#include <linux/linkage.h>
#include <linux/kernel.h>
#include <linux/random.h>
#include "helloworld.h"

asmlinkage long sys_helloworld(){
  printk (KERN_EMERG "hello world!");
  return get_random_int()*4;
}

helloworld.h:

#ifndef HELLO_WORLD_H
#define HELLO_WORLD_H
asmlinkage long sys_helloworld(void);
#endif

Makefile 被相应地扩展。

我现在卡在错误消息中

AS      arch/arm/kernel/entry-common.o
arch/arm/kernel/entry-common.S: Assembler messages:
arch/arm/kernel/entry-common.S:104: Error: __NR_syscalls is not equal to the size of the syscall table
make[1]: *** [arch/arm/kernel/entry-common.o] Error 1

按照Writing a new system call 中的建议,我添加了以下内容:

  • arch/arm/kernel/calls.S

    CALL(sys_helloworld)
    
  • arch/arm/include/uapi/asm/unistd.h

    #define __NR_helloworld                 (__NR_SYSCALL_BASE+380)
    
  • 包括/uapi/asm-generic/unistd.h

    #define __NR_helloworld 274
    __SYSCALL(__NR_helloworld, sys_helloworld)
    
    #define __NR_syscalls 275
    
  • arch/x86/syscalls/syscall_32.tbl

    351     i386    helloworld              sys_helloworld
    

我现在一直在解决错误。

当删除calls.S中的行时,内核编译正常;虽然我不能调用系统调用。添加上述行时,出现上述错误。

供参考:测试系统调用的客户端代码为:

#include <linux/unistd.h>
#include <stdio.h>
#include <sys/syscall.h>

int main (int argc, char* argv[])
{
    int i=atoi(argv[1]);
    int j=-1;
    printf("invocing kernel function %i\n", i);
    j=syscall(i); /* 350 is our system calls offset number */
    printf("invoked. Return is %i. Bye.\n", j);

    return 0;
}

所有其他系统调用(例如,1 == sys_exit)工作正常。

任何想法我错过了什么?例如,我不完全了解如何实施 rasens 答案。

【问题讨论】:

  • 98% 的情况下,添加新的系统调用是解决任何问题的错误方法,除非是出于学习目的。
  • 我即将通过与系统总线/专有硬件交互来直接控制硬件设备 - 我不会说我的方式完全错误... :-/
  • 不,这绝对是错误的。通常,如果您需要从用户空间控制设备,您编写一个实现字符设备文件 + ioctl 调用的内核驱动程序。如果是为了控制设备属性,则使用 sysfs 框架。编辑:此外,当您使用字符设备文件时,您可以从内核免费锁定,因此任何时候只有一个进程可以控制您的设备。
  • 好的...然后让我等到所有要求都设置好...谢谢现在和提示!

标签: linux kernel arm raspberry-pi system-calls


【解决方案1】:

_NR_syscallsarch/arm/include/asm/unistd.h 文件中定义,此值将始终为__NR_last_syscall+1。因此,在您的情况下,_NR_syscalls 应修改为 381,但由于系统调用表中的填充,此更改也会产生相同的错误。因此将其定义为 384。这解决了编译错误。以下更改不是必需的:

include/uapi/asm-generic/unistd.h

#define __NR_helloworld 274
__SYSCALL(__NR_helloworld, sys_helloworld)

#define __NR_syscalls 275

arch/x86/syscalls/syscall_32.tbl

351     i386    helloworld              sys_helloworld

【讨论】:

  • 我们应该如何找到填充的数量?在新版本中有 387 个系统调用。
猜你喜欢
  • 2014-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-02
  • 1970-01-01
  • 2019-08-05
  • 2010-12-13
  • 2021-08-01
相关资源
最近更新 更多