Linux系统调用
Posted tommybjia
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux系统调用相关的知识,希望对你有一定的参考价值。
一、 实验目的和要求
1. 学习Linux内核的配置和编译;
2. 深入理解Linux系统调用;
3. 理解ARM和x86的CPU模式(系统模式、用户模式)的不同;
4. 掌握内核模块的编写方法。
二、 实验器材
1. Linux实验板卡一块;
2. 5V/1A电源一个;
3. microUSB线一根
4. MacOS一台
5. USE-TTL串口线一根
6. 以太网线一根
7. 交叉编译软件
三、 实验内容和原理
1.寻找、下载Linux实验板卡所用的Linux内核源码;
2.在内核中加入新的系统调用,具体功能没有要求,能输出调试信息即可;
3.修改内核代码配置,编译内核;
4.将编译好的内核装载到板卡启动;
5.编写C代码,用两种方法做系统调用,测试;
a) 嵌入汇编代码,用r9传参数;
b) 用syscall()函数;
6.编写内核模块,在模块加载和卸载时能通过内核打印函数输出提示信息;
7.通过insmod和lsmod等命令测试内核模块。
四、 实验过程和数据记录
1. 下载Linux内核源码以及修改
可以使用git clone https://github.com/raspberrypi/linux来下载Linux内核源码。由于文件太大,clone较慢,所以直接选择下载zip文件。
2. 在内核中加入新的系统调用
新的系统调用需要在源码系统调用表arch/arm/kernel/call.s中添加,由于223号系统调用在syscall_table中没有使用,所以可以修改为我们的调用。
之后修改MakeFile,使得自定义的系统调用实现链接到内核里去。
3. 修改内核代码配置,编译内核
我们采用交叉编译的方式编译内核,https://github.com/raspberrypi/tools中提供了数套较差编译工具链,我们使用gcc-linaro-arm-linux-gnueabihf-raspbian作为我们编译内核的工具。
在编译前,我们先查看树莓派内核的版本
首先将其添加到PATH,之后设置.config文件,其中的bcm2709_defconfig为raspberry2代3代的默认配置文件,直接使用即可。
make bcm2709_defconfig ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-zlmage modules dtbs |
编译完成后,安装相关文件到树莓派SD卡上,生成内核镜像kernel7.img
sudo make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=mnt/ext4 modules_install sudo scripts/mkknlimg arch/arm/boot/zlmage mnt/fat32/kernel7.img |
安装4.4.11版本的内核后,可以看到其内核已经更新
4. 编写C代码,用两种方式做系统调用
a) 方法一:嵌入汇编代码,用r0传参数
#include <stdio.h> int main() __asm__ __volatile__(“mov r0. #12”); __asm__ __volatile__(“swi 0x900000+223\\n\\t”); return 0; |
通过r0寄存器,传入12为参数
b) 方法二:用syscall()函数调用
#include <sys/syscall.h> #include <unistd.h> int main() int arg=123; syscall(223,arg); return 0; |
传入syscall参数为123。
5. Linux内核模块
Linux内核模块能更方便地调用内核功能,而无需重新编译内核。其中初始化内核模块时会默认调用init_module,从内核中移除时会默认调用cleanup_module,下面编写这两个函数。
#include <linux/module.h> #include <linux/kernel.h>
int init_moduel(void) printk(“Hello! Inserting module\\n”); |
void cleanup_module(void) printk(“Bye! Removing module\\n”);
MODULE_LICENSE(“GPL”); |
编译后,生成后缀为ko的内核模块,使用insmod插入内核模块时,可以看到内核日志中带有初始化的信息提示,通过lsmod可以看到其已经加载到内核中,rmmod后可以看到移除后的内核消息提示。
以上是关于Linux系统调用的主要内容,如果未能解决你的问题,请参考以下文章