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后可以看到移除后的内核消息提示。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值