Linux系统调用及测试

1.系统调用
  • 查询syscall用法:man 2 syscall
  • 系统调用:上层应用程序调用的API
    • eg:printf() --> glibc write() --> kernel write()
  • 系统调用和计算机的体系结构相关
  • 系统调用的指令
    • syscall和init
    • syscall是64bit机器的指令,init是32bit机器的指令
  • 系统调用的返回值
    • 返回值:rax、rdx寄存器
  • 系统调用的参数
    • 支持6个参数,分别对应6个寄存器
2.demo程序
/************************************************************************
    > File Name: test_syscall.c
    > Author: CurryCoder
    > Mail: 1217096231@qq.com 
    > Created Time: 2022年09月18日 星期日 09时42分51秒
************************************************************************/

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

int main(){
	int pid = syscall(39); // 39为getpid的系统调用号
	printf("pid=%d\n",pid);
	
	return 0;
}
3.系统调用相关的代码位置
  • 不同体系结构有不同的系统调用
    • arch/x86/entry/syscalls/syscall_64.tbl
  • 系统调用属于内核的一部分,不能作为模块进行编译
    • 对系统调用的修改需要重新编译内核
  • 宏__NR_syscalls
    • 系统调用的个数
    • arch/x86/include/generated/uapi/asm/unistd_64.h
    • 注意:系统调用的编号从0开始的
4.实例:添加系统调用(获取cpu的个数)
  • (1).注册系统调用号
    • arch/x86/entry/syscalls/syscall_64.tbl文件中,eg: 451 common get_cpu_number sys_get_cpu_number
  • (2).声明系统调用函数
    • include/linux/syscalls.h文件中,asmlinkage long sys_get_cpu_number(void)
  • (3).实现系统调用
    • kernel/sys.c文件中
    SYSCALL_DEFINE0(get_cpu_number){
        return num_present_cpus();
    }
    
5.测试系统调用
  • (1).重新编译内核
  • (2).使用busybox制作initramfs
#!/bin/busybox sh

/bin/busybox mkdir -p /proc && /bin/busybox mount -t proc none /proc

/bin/busybox echo "Hello Syscall"

export 'PS1=(kernel) =>'
/bin/busybox sh
  • (3).本地静态编译测试代码gcc -static get_cpu.c -o get_cpu,打包进initramfs
/************************************************************************
    > File Name: get_cpu.c
    > Author: CurryCoder
    > Mail: 1217096231@qq.com 
    > Created Time: 2022年09月18日 星期日 09时42分51秒
************************************************************************/

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

int main(){
	int pid = syscall(39);
	printf("pid=%d\n",pid);

	int cpu_number = syscall(451); // 451为get_cpu_number的系统调用号
	printf("cpus=%d\n",cpu_number);
	
	return 0;
}
  • (4).编写Makefile文件
.PHONY: clean initramfs run

${shell mkdir -p build}

initramfs:
	cd initramfs && find . -print0 | cpio -ov --null -H newc | gzip -9> ../build/initramfs.img

clean:
	rm -rf build

run:
	qemu-system-x86_64 \
		-kernel bzImage \
		-m 256M \
		-smp 4 \
		-nographic \
		-initrd build/initramfs.img \
		-append "init=/init earlyprintk=serial,ttyS0 console=ttyS0"
  • (5).用QEMU模拟,可以调整-smp参数观察效果
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值