5.2.4 内核层:Xenomai系统调用的定义

点击查看系列文章 =》 Interrupt Pipeline系列文章大纲-优快云博客

原创不易,需要大家多多鼓励!您的关注、点赞、收藏就是我的创作动力!

5.2.4 内核层:Xenomai系统调用的定义

为了方便对比ARM64 Linux和Xenomai,以系统调用read为例,分别总结各自的表格如下。

根据《5.1.3 内核层:ARM64 Linux系统调用函数的定义》,总结如下。

ARM64 Linux

位置与定义

系统调用号

include/uapi/asm-generic/unistd.h:

#define __NR_read 63

系统调用函数

fs/read_write.c:

SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)

系统调用表

arch/arm64/kernel/sys.c:

const syscall_fn_t sys_call_table[__NR_syscalls] = {

[0 ... __NR_syscalls - 1] = __arm64_sys_ni_syscall,

#include <asm/unistd.h>

};

系统调用号和系统调用函数插入系统调用表

include/uapi/asm-generic/unistd.h:

__SYSCALL(__NR_read, sys_read)

作为对比,针对Xenomai总结如下。相比Linux多了一个系统调用模式的定义。

ARM64 Xenomai

定义

系统调用号

include/xenomai/cobalt/uapi/syscall.h:

#define sc_cobalt_read              81

系统调用函数

kernel/xenomai/posix/io.c:

COBALT_SYSCALL(read, handover,

           (int fd, void __user *buf, size_t size))

{

    return rtdm_fd_read(fd, buf, size);

}

系统调用表

kernel/xenomai/posix/syscall.c:

#include "syscall_entries.h"

static const cobalt_syshand cobalt_syscalls[] = {

    __COBALT_CALL_NI

    __COBALT_CALL_ENTRIES

#ifdef CONFIG_XENO_ARCH_SYS3264

#include <asm/xenomai/syscall32-table.h>

#endif

};

系统调用号和系统调用函数插入系统调用表

kernel/xenomai/posix/syscall_entries.h:

__COBALT_CALL_ENTRIES

系统调用模式

kernel/xenomai/posix/syscall.c:

static const int cobalt_sysmodes[] = {

    __COBALT_CALL_NFLAGS

    __COBALT_CALL_MODES

};

接下来按照表格逐项展开:

(1)系统调用号

系统调用号定义在include/xenomai/cobalt/uapi/syscall.h,文件比较长,这里分别截取头部和尾部两张图。

第21行,包含头文件cobalt/uapi/asm-generic/syscall.h,此头文件中定义了宏定义__COBALT_SYSCALL_BIT(0x10000000)。在用户层通过x8通用寄存器传递Xenomai系统调用号时,总是与__COBALT_SYSCALL_BIT做逻辑或运算。

第139行,定义了宏__NR_COBALT_SYSCALLS,表示Xenomai包含的系统调用号最大数量为128。从第137行可知,实际只用到了0~114。

(2)系统调用函数

kernel/xenomai/posix/io.c:

COBALT_SYSCALL(read, handover,
           (int fd, void __user *buf, size_t size))
{
    return rtdm_fd_read(fd, buf, size);
}

 在kernel/xenomai/posix/io.c中,通过宏COBALT_SYSCALL来定义read系统调用的实现。

kernel/xenomai/posix/syscall.h:
/* Regular (native) syscall handler implementation. */
#define COBALT_SYSCALL(__name, __mode, __args)  \
    long CoBaLt_ ## __name __args

宏COBALT_SYSCALL展开后,得到函数名为CoBaLt_read。这里的前缀突然用了大小写交替的方式,不知道为什么!

(3)系统调用表

Xenomai系统调用表cobalt_syscalls[]数组的定义,与Linux的系统调用表有异曲同工之妙。

第455行,宏定义__COBALT_CALL_NI的目标,就是把cobalt_syscalls[]数组的所有元素全部初始化,指向CoBaLt_ni函数(直接return -ENOSYS)。相比Linux,系统调用表默认所有元素都指向__arm64_sys_ni_syscall函数。

第456行,宏定义__COBALT_CALL_ENTRIES从字面理解,应该是很多__COBALT_CALL_ENTRY的集合,事实也是如此。__COBALT_CALL_ENTRIES定义在第452包含的头文件syscall_entries.h中。此文件的绝对路径是kernel/xenomai/posix/syscall_entries.h。展开后就是对数组的元素进行赋值,和Linux的套路完全相同。上述宏定义展开的时候,涉及到兼容32位ABI的宏都按空处理。

备注:syscall_entries.h默认是不存在的,是在编译过程中使用脚本gen-syscall-entries.sh处理各个.c文件中的COBALT_SYSCALL宏,生成的一个头文件。

(3)系统调用模式

Xenomai的每个系统调用,都有自己对应的调用模式,定义在数组cobalt_sysmodes[],数组的索引值就是系统调用号。

所以,根据系统调用号,从cobalt_syscalls[]数组可以找到对应的系统调用函数,从cobalt_sysmodes[]数组可以找到系统调用模式。

cobalt_sysmodes[]数组同样定义在kernel/xenomai/posix/syscall.c中。

第462行,宏定义__COBALT_CALL_NFLAGS就是把cobalt_sysmodes[]数组的所有元素全部初始化0。

第463行,宏__COBALT_CALL_MODES定义在第452包含的头文件syscall_entries.h中。此文件的绝对路径是kernel/xenomai/posix/syscall_entries.h。展开后就是对数组的元素进行赋值。宏定义展开的时候,涉及到兼容32位ABI的宏都按空处理。

其中所涉及的__xn_exec_primary、__xn_exec_current等模式的定义,同样定义在kernel/xenomai/posix/syscall.c中。

点击查看系列文章 =》 Interrupt Pipeline系列文章大纲-优快云博客

原创不易,需要大家多多鼓励!您的关注、点赞、收藏就是我的创作动力!

参考

xenomai内核解析--双核系统调用(一)-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值