1.系统调用
- 查询syscall用法:man 2 syscall
- 系统调用:上层应用程序调用的API
- eg:printf() --> glibc write() --> kernel write()
- 系统调用和计算机的体系结构相关
- 系统调用的指令
- syscall和init
- syscall是64bit机器的指令,init是32bit机器的指令
- 系统调用的返回值
- 系统调用的参数
2.demo程序
#include
#include
#include
int main(){
int pid = syscall(39);
printf("pid=%d\n",pid);
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
3.系统调用相关的代码位置
- 不同体系结构有不同的系统调用
- arch/x86/entry/syscalls/syscall_64.tbl
- 系统调用属于内核的一部分,不能作为模块进行编译
- 宏__NR_syscalls
- 系统调用的个数
- arch/x86/include/generated/uapi/asm/unistd_64.h
- 注意:系统调用的编号从0开始的
4.实例:添加系统调用(获取cpu的个数)
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
#include
#include
#include
int main(){
int pid = syscall(39);
printf("pid=%d\n",pid);
int cpu_number = syscall(451);
printf("cpus=%d\n",cpu_number);
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
.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"
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- (5).用QEMU模拟,可以调整-smp参数观察效果