嵌入式技术
(1).源码下载链接
(2).查看本机配置参数命令:screenfetch;
(3).三种编译方式进行内核编译配置
make menuconfig
make xconfig
make gconfig(需要安装GTK Package)
(4).查看内核配置文件: ll -a | grep config;
(5).清除上一次构建生成的config文件:make mrproper;
(6).编译内核:make -jn 可以加快内核编译,n为线程数,编译时间与电脑配置有关;
(7).清除上一次内核编译过程生成的文件:make clean;
(8).编译结果内核镜像文件生成路径:linux-5.19.4/arch/x86/boot/bzImage;
内核编译
内核镜像文件
(1).busyBox源码下载链接
(2).解压源码后,进行make menuconfig配置编译选项。开启静态编译Build Static;binary(no shared libs)选项;
(3).编译busyBox源码:make -j4;
(4).编译完成后进行安装:make install;
(5).命令行工具安装在路径:busybox-1.35.0/_install/bin/;
(6).在命令行工具安装路径下执行可执行程序./busybox --help可以查询当前所有可用的命令;
(7).在命令行工具安装路径下执行可执行程序./busybox sh可以进入shell环境;
busybox编译
(1).在home目录下创建initramfs/bin文件夹;
(2).从已经编译并安装好的busybox目录busybox-1.35.0/_install/bin/下将可执行程序busybox拷贝到initramfs/bin目录下;
(3).在initramfs目录下创建文件init, 并修改其权限为可执行chmod +x init ;
(4).切换到目录initramfs下,执行find . -print0 | cpio -ov --null --format=newc | gzip -9 > initramfs.img命令将该目录下的所有文件使用cpio命令归档并使用gzip进行压缩,生成initramfs.img文件;
#!/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
(1).查询syscall用法:man 2 syscall
(2).系统调用:上层应用程序调用的API
举例:C库中的printf() --> glibc 库中的write() --> kernel中的write()
(3).系统调用和计算机的体系结构相关
(4).系统调用的指令
syscall和init
syscall是64bit机器的指令,init是32bit机器的指令
(5).系统调用的返回值
返回值存储在rax、rdx寄存器中
(6).系统调用的参数
支持6个参数,分别对应6个寄存器
5.系统调用相关的代码位置
(1).不同体系结构有不同的系统调用
arch/x86/entry/syscalls/syscall_64.tbl
(2).系统调用属于内核的一部分,不能作为模块进行编译
对系统调用的修改需要重新编译内核
(3).宏__NR_syscalls
系统调用的个数
arch/x86/include/generated/uapi/asm/unistd_64.h
注意:系统调用的编号从0开始的
6.实例:添加新的系统调用(获取cpu的个数)
(1).注册系统调用号
arch/x86/entry/syscalls/syscall_64.tbl文件中,例如 :添加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();
}
7.使用QEMU测试新的系统调用
(1).重新编译内核,具体见第1小节;
(2).使用busybox制作initramfs,具体见第3小节;
(3).本地静态编译测试代码gcc -static get_cpu.c -o get_cpu,将编译生成的可执行文件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=%dn",pid);
int cpu_number = syscall(451); // 451为get_cpu_number的系统调用号
printf("cpus=%dn",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参数观察效果
启动QEMU
测试结果
全部0条评论
快来发表一下你的评论吧 !