gpt4 book ai didi

linux-kernel - 在实时 Debian Wheezy 上实现系统调用

转载 作者:行者123 更新时间:2023-12-04 04:35:18 27 4
gpt4 key购买 nike

出于教育目的,我想在 Debian Wheezy 中实现一个系统调用。我希望在 linux-image-3.2.0--rt-amd64 包中的内核上实现它。以下是我尝试过的概述:
获取内核源代码:

apt-get source linux-image-3.2.0-4-rt-amd64
从那里,我得到了我在其中执行的目录的以下文件/目录:
linux_3.2.41.orig.tar.xz
linux_3.2.41-2+deb7u2.dsc
linux_3.2.41-2+deb7u2.debian.tar.xz
也:
linux_3.2.41
其中包含内核的源代码。
然后,为了添加系统调用进行必要的更改,我基本上遵循了这个页面:
How to write system calls on debian/ubuntu
以下是其中给出的说明的精简版本,已修改以反射(reflect)我所做的更改。
+文件1:linux-x.x.x/vpart_syscalls/vpart_syscalls.c
#include <linux/linkage.h>
#include <linux/kernel.h>

asmlinkage long insert_partition(char*dest, const char* src)
{
printk("<--- the syscall has been called!");
return 0;
}
  • 文件 2:linux-x.x.x/vpart_syscalls/Makefile。在您上面创建的同一测试目录中创建一个 Makefile 并将此行放入其中:obj-y := vpart_syscalls.o
  • 文件 3:linux-x.x.x/arch/x86/kernel/syscall_table_32.S。现在,您必须将系统调用添加到系统调用表中。将以下行追加到文件中:.long insert_partition
  • 文件4:linux-x.x.x/arch/x86/include/asm/unistd_32.h

  • 在此文件中,所有系统调用的名称将与一个唯一编号相关联。在最后一个系统调用号码对之后,添加一行
    #define __NR_insert_partition 349
    然后替换 NR_syscalls 值,用(现有数字增加 1)说明系统调用的总数,即在这种情况下,NR_syscalls 应该是 338,新值是 339。
    #define NR_syscalls 350
  • 文件5:linux-x.x.x/include/linux/syscalls.h

  • 将我们函数的原型(prototype)附加到文件中。
    asmlinkage long insert_partition(int lenTicks, int vpid);
    就在文件中的#endif 行之前。
  • 文件 6:源目录根目录下的 Makefile。

  • 打开 Makefile 并找到定义 core-y 的行并将目录 test 添加到该行的末尾。
    core-y += kernel/ mm/ fs/ test/ vpart_syscalls/
    然后我开始以不同于那里描述的方式构建内核:
    make localmodconfig
    make menuconfig (making no changes)


    make-kpkg clean
    fakeroot make-kpkg --initrd --append-to-version=+tm kernel_image kernel_headers
    cd ..
    dpkg -i linux-image-3.8.*
    dpkg -i linux-headers-3.8.*
    安装的内核可以正常启动。我制作了以下 c 程序来测试系统调用:
    #include <stdio.h>
    #include <linux/unistd.h>
    #include <sys/syscall.h>

    int main(){
    printk("Calling the new syscall!\n");
    int ret = 100;
    ret = syscall(349, 1, 2);
    printf("call return value: %i\n", ret);
    return 0;

    }
    当我编译并运行这个程序时,我得到一个返回值 -1。我使用 dmesg 检查消息,没有证据表明我的 printk 被调用..
    如果有人知道我的问题出在哪里,我会非常高兴!我应该说我在更改和构建内核方面没有太多经验,但我学到了很多。我在网上阅读了 Robert Loves 的书 - linux 内核开发和一些指南。

    最佳答案

    我认为,对于 64 位内核,步骤 3 和 4 可能不正确:

    File 3: linux-x.x.x/arch/x86/kernel/syscall_table_32.S. 
    File 4: linux-x.x.x/arch/x86/include/asm/unistd_32.h

    这里有两个文件: http://lxr.linux.no/linux+v3.2.41/arch/x86/kernel/
    syscall_64.c    668 2008-12-24 14:26:58 -0800   
    syscall_table_32.S 8659 2012-01-04 14:55:50 -0800

    第一个使用 C 文件定义 64 位模式的系统调用表内容,并使用 unistd_64.h 进行宏作弊。
    #define __SYSCALL(nr, sym) [nr] = sym,

    const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = {
    ....
    #include <asm/unistd_64.h>
    };

    在哪里 asm/unistd_64.h
     #define __NR_read                               0
    __SYSCALL(__NR_read, sys_read)

    等等。

    第二个,您更改了 - 用于 32 位模式,并使用 asm 文件和标签 ( .long sys_call_name ) 编写。

    因此,您为 32 位模式定义了系统调用,并且您正在使用 linux-image-3.2.0-4-rt-amd64这基本上适用于“64位PC”。

    我认为您将测试程序编译为 gcc test.c ,默认为 64 位模式。你可以试试 -m32 gcc 选项: gcc -m32 test.c获取 32 位应用程序(这仅在您有正确的 32 位构建跨环境时才有效)或在某些 32 位 linux 上编译此测试。

    或者另一种选择是进行步骤“4a”:编辑 arch/x86/include/asm/unistd_64.h添加两行:
     #define __NR_insert_partition                               YOUR_NUMBER
    __SYSCALL(__NR_insert_partition, insert_partition)

    我不确定 64 位的 NR_syscalls 是在哪里以及如何定义的。它可能在构建期间生成。

    关于linux-kernel - 在实时 Debian Wheezy 上实现系统调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16725069/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com