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系统调用的主要内容,如果未能解决你的问题,请参考以下文章

linux 系统调用列表

哪条命令查看思科业务板卡信息状态

使用QEMU实现vexpress-ca9板卡的linux启动

思科设备登陆到独立的板卡采用啥命令

Linux操作系统下如何调用动态分配显存?

板卡AIubuntu系统显卡驱动cudacudnn安装教程