当前位置: 首页 > news >正文

南乐网站建设价格石家庄住房和城乡建设厅网站

南乐网站建设价格,石家庄住房和城乡建设厅网站,饿了吗网站有问题怎么办,哪个网站ppt模板免费下载说明 基于riscv64 soc linux_5.10.4平台#xff0c;通过新增一个系统调用深入了解下系统调用实现原理。 简介 Linux 软件运行环境分为用户空间和内核空间#xff0c;默认情况下#xff0c;用户进程无法访问内核#xff0c;既不能访问内核所在的内存空间#xff0c;也不…说明 基于riscv64 soc linux_5.10.4平台通过新增一个系统调用深入了解下系统调用实现原理。 简介 Linux 软件运行环境分为用户空间和内核空间默认情况下用户进程无法访问内核既不能访问内核所在的内存空间也不能调用内核中的函数。为了给应用层提供系统支持Linux提供了一组系统调用接口用户可以通过调用它们访问linux内核的数据和函数。Linux系统调用实现原理是固定不同平台arm64riscv只是切换至内核态的汇编指令不同大致原理如下 程序将系统调用参数填充到对应的平台通用寄存器。调用平台特定的汇编指令触发同步异常切换至内核态运行。内核初始化时已设置异常向量表应用层触发同步异常后CPU会跳到异常向量表对应的异常处理执行通常是一段平台相关的汇编代码。异常处理代码会检查系统调用号是否超出未超出再根据定义的系统调用表(sys_call_table)找到相应的系统调用函数入口地址执行后再通过汇编指令返回应用层。 新增系统调用实现步骤如下 修改系统调用表syscall_table新增一项。系统调用声明。系统调用实现。 修改系统调用表 系统调用表syscall_table定义如下 // file: arch/riscv/kernel/syscall_table.c #undef __SYSCALL #define __SYSCALL(nr, call) [nr] (call),const void *sys_call_table[__NR_syscalls] {[0 ... __NR_syscalls - 1] sys_ni_syscall, #include asm/unistd.h //通过unistd.h导入实际定义 };asm/unistd.h最终定义如下 //file: include/uapi/asm-generic/unistd.h ... #define __NR_openat2 437 //系统调用openat2 编号 __SYSCALL(__NR_openat2, sys_openat2) //系统调用openat2 syscall_table项定义 #define __NR_pidfd_getfd 438 __SYSCALL(__NR_pidfd_getfd, sys_pidfd_getfd) #define __NR_faccessat2 439 __SYSCALL(__NR_faccessat2, sys_faccessat2) #define __NR_process_madvise 440 __SYSCALL(__NR_process_madvise, sys_process_madvise)#undef __NR_syscalls #define __NR_syscalls 441 //系统调用表 项个数 ...新增一项系统调用(mytest) diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index 15279e8d8..7df066dc5 100644 --- a/include/uapi/asm-generic/unistd.hb/include/uapi/asm-generic/unistd.h-860,8 860,11 __SYSCALL(__NR_faccessat2, sys_faccessat2)#define __NR_process_madvise 440__SYSCALL(__NR_process_madvise, sys_process_madvise)#define __NR_mytest 441 __SYSCALL(__NR_mytest, sys_mytest) #undef __NR_syscalls -#define __NR_syscalls 441 #define __NR_syscalls 442系统调用声明 新增系统调用需要先声明否则内核编译时会报错找不到新增系统调用声明。 //file: include/linux/syscalls.h .... asmlinkage long sys_madvise(unsigned long start, size_t len, int behavior); asmlinkage long sys_process_madvise(int pidfd, const struct iovec __user *vec,size_t vlen, int behavior, unsigned int flags); .... asmlinkage long sys_mytest(int id); //新增系统调用声明系统调用实现 实现系统调用时不能像实现普通函数一样需要使用SYSCALL_DEFINE宏如系统调用madvise,定义时使用SYSCALL_DEFINE3宏宏展开后就是sys_madvise。 //file: mm/madvise.c SYSCALL_DEFINE3(madvise, unsigned long, start, size_t, len_in, int, behavior) { return do_madvise(current-mm, start, len_in, behavior); }int do_madvise(struct mm_struct *mm, unsigned long start, size_t len_in, int behavior) { ....//实际功能实现.... }SYSCALL_DEFINE 宏定义 //file: include/linux/syscalls.h #ifndef SYSCALL_DEFINE0 #define SYSCALL_DEFINE0(sname) \SYSCALL_METADATA(_##sname, 0); \asmlinkage long sys_##sname(void); \ALLOW_ERROR_INJECTION(sys_##sname, ERRNO); \asmlinkage long sys_##sname(void) #endif /* SYSCALL_DEFINE0 */#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) #define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__) #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__) #define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__) #define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__) #define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)#define SYSCALL_DEFINE_MAXARGS 6#define SYSCALL_DEFINEx(x, sname, ...) \SYSCALL_METADATA(sname, x, __VA_ARGS__) \__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)#define __PROTECT(...) asmlinkage_protect(__VA_ARGS__)系统调用最多支持6个参数1个参数使用SYSCALL_DEFINE12个参数使用SYSCALL_DEFINE2以此类推。 新系统调用 // file: mm/madvise.c ,随便找了一个文件保存代码 SYSCALL_DEFINE1(mytest, int, id) {return id; //测试将id返回 }应用层测试 编译并运行新内核后可运行应用层程序验证。 int main(void) {int id 0;id syscall(441, 100);printf(result : %d\n, id);return 0; }~# ./mytest result : 100标准C库 程序中调用的syscall来自标准C库根据源码可知应用层系统调用接口是封装的syscall。当前使用的标准C库muslsyscall源码如下 //file: musl-1.2.1/arch/riscv64/syscall_arch.h ... #define __asm_syscall(...) \__asm__ __volatile__ (ecall\n\t \: r(a0) : __VA_ARGS__ : memory); \return a0; \static inline long __syscall0(long n) {register long a7 __asm__(a7) n;register long a0 __asm__(a0);__asm_syscall(r(a7)) } ... static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f) {register long a7 __asm__(a7) n;register long a0 __asm__(a0) a;register long a1 __asm__(a1) b;register long a2 __asm__(a2) c;register long a3 __asm__(a3) d;register long a4 __asm__(a4) e;register long a5 __asm__(a5) f;__asm_syscall(r(a7), 0(a0), r(a1), r(a2), r(a3), r(a4), r(a5)) }可知 riscv64最终使用汇编指令ecall,触发同步异常切换至内核态执行。使用通用寄存器a7 存储系统调用编号和内核定义一致syscall支持0 ~ 6个参数__syscall0 ~ __syscall6 使用寄存器a0 ~ a5传递参数。 ARM64实现原理也是一样不同的只是触发异常的指令svc以及通用寄存器的使用如下 #define __asm_syscall(...) do { \__asm__ __volatile__ ( svc 0 \: r(x0) : __VA_ARGS__ : memory, cc); \return x0; \} while (0)static inline long __syscall0(long n) {register long x8 __asm__(x8) n;register long x0 __asm__(x0);__asm_syscall(r(x8)); } ... static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f) {register long x8 __asm__(x8) n;register long x0 __asm__(x0) a;register long x1 __asm__(x1) b;register long x2 __asm__(x2) c;register long x3 __asm__(x3) d;register long x4 __asm__(x4) e;register long x5 __asm__(x5) f;__asm_syscall(r(x8), 0(x0), r(x1), r(x2), r(x3), r(x4), r(x5)); }总结 系统调用是安全的执行时应用层没有访问内核空间。系统调用执行时应用层暂停切换至内核空间执行。系统调用执行时是通过平台相关的特定汇编指令触发同步异常riscv64是使用ecallaarch64是使用svc 0Intel CPU由中断0x80实现。 CPU会跳转到对应的异常处理源码如下 //file: arch/riscv/kernel/entry.S .... ENTRY(handle_exception) //对应的异常处理.... check_syscall_nr:/* Check to make sure we dont jump to a bogus syscall number. */li t0, __NR_syscallsla s0, sys_ni_syscall/** Syscall number held in a7.* If syscall number is above allowed value, redirect to ni_syscall.*/bgeu a7, t0, 3f #ifdef CONFIG_COMPATREG_L s0, PT_STATUS(sp)srli s0, s0, SR_UXL_SHIFTandi s0, s0, (SR_UXL SR_UXL_SHIFT)li t0, (SR_UXL_32 SR_UXL_SHIFT)sub t0, s0, t0bnez t0, 1f/* Call compat_syscall */la s0, compat_sys_call_tablej 2f 1: #endif/* Call syscall */la s0, sys_call_table 2:slli t0, a7, RISCV_LGPTRadd s0, s0, t0REG_L s0, 0(s0) 3:jalr s0ret_from_syscall: ....内核态调用对应的系统调用函数执行完后会退出内核态切换至用户态如上 ret_from_syscall。 此过程 aarch64平台是由eret汇编指令实现和arm trustzone机制 bl31切换至非安全worldREE以及切换至安全worldbl32实现流程是一样的riscv64 平台具体指令暂不明。
http://www.hkea.cn/news/14420662/

相关文章:

  • 网站建设对客户的影响软件开发如何定价
  • 网站建设软件有哪些自适应网站做百度推广
  • 自适应网站功能免费微信点餐小程序
  • 北京网站开发团队知名seo电话
  • 国外优秀摄影作品网站天猫网页版
  • 摄影婚纱官网2017织梦网站怎么做seo
  • 建网站备案好麻烦做宣传图片用什么网站
  • 东莞网站建设公司注册网易企业邮箱手机登录
  • 如何修改上线网站wordpress去掉购物车
  • 做竞价网站服务器多少钱线上平面设计课程
  • 唐山网站建设模板公司网站建设团队
  • 手机网站制作套餐wordpress函数调用函数
  • 英文网站域名注册郑州安卓app开发
  • 大学生作业做网站绍兴网站制作
  • wordpress建站 云打印肇庆网站推广排名
  • 做网站一定要有空间吗网站建设kpi考核
  • 企业建设网站应该一般多少钱东营在建项目
  • 制作网站river小程序代理商有哪些
  • 教学信息化大赛网站建设作品WordPress添加工单功能
  • 自己做的砍价网站设计的比较好的网站
  • 北京做网站s那个软件可以做网站
  • 网站备案后需要年检吗电子商务网站建设讯息
  • 网站建设为什么要全款wordpress 评论内容
    标签 显示html
    
  • 黄冈网站推广软件自己的网站怎么样推广优化
  • 网站建站的步骤临沂网站公众号建设
  • 基于lamp网站建设实例做网站推广的一般都是什么公司
  • 找做网站公司wordpress导航特效
  • 响应式相册网站软件外包项目网站
  • 网站建设与管理课程设计wordpress调用分类目录代码
  • html网站发布大型网站架设需要考虑哪些问题