Lab 6:Linux系统调用
来源:互联网 发布:平定四方巾 知乎 编辑:程序博客网 时间:2024/05/22 07:59
一、连接和器材
器材列表:
RaspberryPi(树莓派)一块、USB-TTL串口线一根(PL2303芯片)、以太网线一根、8G容量SD卡一张、带windows7操作系统的PC一台。
连接示意图:
二、实验步骤
a.寻找、下载Linux实验板卡所用的Linux内核源码
在ubuntu14.04下直接使用命令git clone --depth=1 https://github.com/raspberrypi/linux获取最新版本的树莓派源码。源码放在~/test1/linux下
另外,由于网速问题,我直接从https://github.com/raspberrypi/下载了对应的firmware和tools的zip压缩包并且解压后依次命名为~/RpiFirmware和~/RpiTools。
然后修改~/.bashrc加上环境变量:
b.在内核中加入新的系统调用
在linux/arch/arm/kernel文件夹下新建mysyscall.c文件,内容如下:
然后打开linux/arch/arm/kernel/calls.S添加系统调用号223为mysyscall:
最后修改linux/arch/arm/kernel/Makefile文件,在obj –y结尾加上mysyscall.o
至此,添加新的系统调用准备工作完成。
c.修改内核代码配置,编译内核
编译过程主要参考自树莓派官方文档
https://www.raspberrypi.org/documentation/linux/kernel/building.md
直接采用了默认内核配置,所以没有修改内核代码配置。
在linux目录下输入如下的操作命令:
cd linux
KERNEL
=kernel
make ARCH
=arm CROSS_COMPILE
=arm
-linux
-gnueabihf
-bcmrpi_defconfig
make ARCH
=arm CROSS_COMPILE
=arm
-linux
-gnueabihf
-zImage modules dtbs
随后看到内核开始编译,完成后在linux/arch/arm/boot下找到了zImage文件:
此后进入输入命令
sudo ~/linux/scripts
/mkknlimg arch
/arm
/boot
/zImage ~
/kernel.img
可以在home目录下看到kernel.img文件:
编译完内核后,还要编译lib。
使用如下命令:
sudo make ARCH
=arm CROSS_COMPILE
=arm
-linux
-gnueabihf
-INSTALL_MOD_PATH
=~/modules2 modules_install
d.将编译好的内核装载到板卡启动
将树莓派连接上局域网,随后使用scp命令将内核kernel.img拷贝到/boot/kernel.img,
在编译好的modules2文件夹内找到lib文件夹,里面有firmware和modules两个文件夹,分别拷贝覆盖树莓派的/lib/firmware和/lib/modules文件夹。
最后还要使用如下命令覆盖掉一些文件:
sudo scp arch
/arm
/boot
/dts
/*.dtb pi@
/192.168.137.71:/boot/
sudo scp arch
/arm
/boot
/dts
/overlays
/*.dtb
*pi@
/192.168.137.71:/boot/overlays
/
sudo scp arch
/arm
/boot
/dts
/overlays
/README pi@
/192.168.137.71:/boot/overlays
/
(所有被覆盖的文件都已经提前备份)
完成上述操作后,在树莓派内输入reboot命令,即可重启。
重启后的输出信息表明,内核已经更新为4.4.11+,如下所示:
e.编写C代码,用两种方法做系统调用,测试:
1、嵌入汇编代码,用r0传参数;
2、用syscall()函数。
在树莓派的home目录下,创建syscall_test.c文件内容如下:
(嵌入汇编代码调用syscall)
编译执行后,输入dmesg | tail可以看到系统调用成功,下图中最后一句This is mysyscall即为系统调用输出信息:
随后在home目录下再新建一个syscall_test2.c函数:
(通过syscall函数调用syscall)
编译运行后同样能成功调用mysyscall如下:
(上图中最后两句”This is mysyscall”分别是运行syscall_test和syscall_test2时输出的)
由此可见,两种系统调用方法均成功了。
f.编写内核模块,在模块加载和卸载时能通过内核打印函数输出提示信息并且通过insmod和lsmod等命令测试内核模块
首先在ubuntu环境下写好需要的show.c函数和Makefile文件。
其中show.c的作用是遍历进程,输出系统中:每个进程的名字、进程pid、进程的状态、父进程的名字;统计系统中进程个数,统计系统中TASK_RUNNING、TASK_INTERRUPTIBLE、TASK_UNINTERRUPTIBLE、TASK_ZOMBIE、TASK_STOPPED等(还有其他状态)状态进程的个数。这个程序是我在操作系统实验课上写的。
两文件内容分别如下:
show.c:
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/init.h>
#include<linux/sched.h>
#include<linux/list.h>
static__init int print_pid(void)
{
struct task_struct *task,*p;
struct list_head *pos;
intrunning=0,interruptible=0,uninterruptible=0,zombie=0,stopped=0,dead=0,traced=0,unknown=0;
printk("Begin\n");
task=&init_task;
list_for_each(pos,&task->tasks)
{
p=list_entry(pos,structtask_struct,tasks);
printk("%s---%d---%ld---%s\n",p->comm,p->pid,p->state,p->parent->comm);
switch(p->state){
caseEXIT_ZOMBIE:zombie++;break;
case EXIT_DEAD:dead++;break;
caseTASK_RUNNING:running++;break;
caseTASK_INTERRUPTIBLE:interruptible++;break;
caseTASK_UNINTERRUPTIBLE:uninterruptible++;break;
caseTASK_STOPPED:stopped++;break;
caseTASK_TRACED:traced++;break;
default:unknown++;break;
}
}
printk("TASK_RUNNING:%d\n",running);
printk("TASK_INTERRUPTIBLE:%d\n",interruptible);
printk("TASK_UNINTERRUPTIBLE:%d\n",uninterruptible);
printk("TASK_STOPPED:%d\n",stopped);
printk("TASK_TRACED:%d\n",traced);
printk("EXIT_ZOMBIE:%d\n",zombie);
printk("EXIT_DEAD: %d\n",dead);
printk("End\n");
return 0;
}
static __exitvoid print_exit(void)
{
printk("<0>end!\n");
}
module_init(print_pid);
module_exit(print_exit);
Makefile:
TARGET =show
KVER ?=$(shell uname -r)
KDIR =/home/xuanzhuanecy/modules/lib/modules/4.4.11+/build/
PWD =$(shell pwd)
obj-m +=$(TARGET).o
default:
make -C $(KDIR) M=$(PWD) modules
随后在ubuntu环境下交叉编译树莓派的内核模块show.ko如下所示:
makeARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make –C/home/xuanzhuanecy/modules/lib/modules/4.4.11+/build/ M=/home/xuanzhuanecymodules
然后通过scp命令拷贝这个show.ko到树莓派的home目录下。
运行sudo insmod show.ko命令后再输入sudo lsmod,可以看到show模块成功载入:
然后输入cat /var/log/kern.log命令,最后显示的几行内容如下:
可见show模块被载入成功,并且打印输出了当前系统中的各种状态的进程的数量的信息到/var/log/kern.log。
- Lab 6:Linux系统调用
- LAB : Linux系统修复(转载自百度文库)
- 嵌入式LAB 6:Linux内核编译
- LAB 6
- 汇编语言调用Linux系统调用
- 如何调用linux系统调用
- Linux系统调用列表
- Linux 系统调用
- Linux系统调用列表
- Linux系统调用列表
- Linux系统调用列表
- Linux系统调用列表
- linux的系统调用
- Linux系统调用列表
- Linux系统调用列表
- Linux系统调用列表
- Linux系统调用讲义
- Linux系统调用列表
- Oracle创建、重建和删除索引
- Xshell无法连接Ubuntu,但能够ping通虚拟机
- 《计算机系统要素》学习笔记: 逻辑门 构建 思路
- 用Java的加密机制来保护你的数据
- iOS应用架构谈 本地持久化方案及动态部署
- Lab 6:Linux系统调用
- font-awesome 原理分析
- safari中overflow:hidden对CSS模糊滤镜溢出隐藏无效解决办法
- 变量的多态性
- Java程序的加密和反加密
- iOS应用架构谈 组件化方案
- 项目管理工具-redmine安装
- JAVA加密解密---自定义类加载器应用
- 蘑菇街 App 的组件化之路