Linux_kernel编程基础总结

时间:2015/10/9

背景:学习linux内核编程,总结学习中的经验,方便之后查看;

通常我们想弄清楚linux内核是怎么样工作的,如何使用内核接口来编写linux内核代码的第一步都是搭建一个实验环境来做试验的;这里总结一下实验环境的搭建步骤,和我的一些经验;

步骤一、搭建实验环境

这里资源文件总共有两个:hello.c Makefile

Hello.c 是模块的源码;

Makefile  是编译模块的脚本文件;

//hello.c 源码
#include <linux/kernel.h>
#include <linux/module.h>static int __init mini2440_hello_module_init(void)
{printk (KERN_WARNING "hello , mini2440\n");return 0;
}static int __exit mini2440_bye_module_exit(void)
{printk (KERN_WARNING "bye , mini2440\n");return 0;
}module_init(mini2440_hello_module_init);
module_exit(mini2440_bye_module_exit);MODULE_LICENSE("GPL");
#Makefile文件
obj-m := hello.oKERNEL_DIR := /lib/modules/$(shell uname -r)/build
#KERNEL_DIR := /opt/FriendlyARM/mini2440/linux-2.6.32.2  PWD := $(shell pwd)all:  make -C $(KERNEL_DIR) M=$(PWD) modules  clean:  rm *.o *.ko *.mod.c  Module.symvers modules.order

步骤二、编译模块,并执行insmod,rmmod插入卸载模块操作

1、make

2、insmod ./hello.ko
3、dmesg 
4、rmmod hello
5、dmesg -c

分析:从hello.c这个模块源码文件上来看,这个模块的主体是一个很简单的结构,声明了模块在加载的时候执行mini2440_hello_module_init; 模块在卸载的时候执行mini2440_bye_module_exit;分别对应着将不同的字符串打印到串口上;细说一下,在hello.c中前两行的头文件肯定的是指内核的头文件$(kernel)/include/linux而不是在/usr/include的用户空间才使用的头文件路径,而我们所要使用的头文件路径是由Makefile文件中定义好我们要明确使用的是那个内核源码来编译的;

从Makefile进行分析;

Obj-m := hello.o

#表示当前编译想要生成一个动态的模块,这个模块依赖于hello.o来生成;而在makefile中,想要生成hello.o默认的将会执行从hello.c生成;因此Makefile将会自动搜索当前路径下是否有hello.c的文件,如果有则生成hello.o,然后有了hello.o则声称hello.ko;这个是makefile自动匹配的语法;

KERNEL_DIR := /lib/modules/$(shell uname-r)/build

#这句话就是我指定我想编译模块所需要的内核源码路径;可以指定你想指定的任意含有内核源码的路径,编译将会生成对应的内核版本的内核模块;因为linux系统中内核模块有着强烈的版本限制,所以只有对应版本的内核源码编出来的内核模块才能够在对应的内核版本系统中运行;

PWD := $(shell pwd)

#这里使用pwd指令获取当前路径,并将他放在PWD这个变量里面,作为下面make –C makefile的入参;

all:

make -C $(KERNEL_DIR) M=$(PWD) modules

#这里all:就是一个目标,也可以说是一个伪目标,没有实际意义,只是用来表示我要开始执行命令了;

#make –C 表示(change)改变当前makefile的路径,切换到其他makefile中去执行,后面跟的就是想要切换到的路径,这里路径被我定义为/lib/modules/$(shell uname -r)/build

这里ll 这个路径发现,他是一个标准的软连接:指向了

/usr/src/linux-headers-2.6.32-74-generic

之后我们跟踪到/usr/src/linux-headers-2.6.32-74-generic;

Ls -l之后发现这里所有资源指向了上一级的linux-headers.6.32-74

其实我们并不需要关心其他资源,Makefile –C切换过来,需要寻找这个路径下的makefile;我们看看这个文件中的makefile是怎么写的;

在ubuntu 10.04_2.6.32-74内核源码makefile中的69行:这里就强调为什么我们在make –C的时候需要传递一个参数M过去,而不是其他参数;当然这里他是以识别M开头的参数,

如果这里我想挑逗他一下,用一个M1来代替,看看会出什么结果:

将会报错:

Makefile说也可以使用SUBDIRS来代替M;你可以试试:

Make 命令行中最后一个modules表示,这里所要编译的是一个module;

当然你要知道当前所运行的都是在内核源码顶层makefile中运行的,在顶层makefile运行到最后,将会从M中拿到扩展的模块源码进行编译;之后将会生成hello.ko文件;

模块名,源码文件名,KO文件名;

之前一直在困惑,通过Insmod./hello.ko这个文件,最终通过lsmod 查看发现有一个模块名字叫做hello,那么这个模块的命名是由谁决定的;这里面涉及到整个KO编译和插入总共有三个文件名;一个是模块的源码.c文件名;hello.c;另一个是Makefile文件中obj-m:=hello.o编译模块名;最后一个是编译生成的hello.ko文件;之后才清晰的明白其中的转则;

1、  不修改资源文件,默认编译并生成了hello.ko文件;修改hello.ko文件名为hello_back.ko然后插入这个KO文件,之后通过lsmod查看,发现模块名依旧是hello,所以说模块名与KO文件名无关;

2、  模块名取决于obj-m后面跟的是什么,这里obj-m跟的是hello.o所以kernel默认将会生成hello模块;因为Obj-m依赖于hello.o,而makefile语法中想要生成hello.o将要在路径下寻找同名的.c文件(hello.c),也就是这里的第一个名字:源码的.c文件名,就是这么用的;

linux kernel内核编程基础总结相关推荐

  1. Windows驱动开发学习笔记(二)—— 驱动调试内核编程基础

    Windows驱动开发学习笔记(二)-- 驱动调试&内核编程基础 基础知识 驱动调试 PDB(Program Debug Database) WinDbg 加载 PDB 实验:调试 .sys ...

  2. Linux下libxml2编程基础

    Linux下libxml2编程基础 一.libxml2的简介 xml是一个实现读.创建.以及操作xml数据功能的C语言库.并且支持XPATH查询,以及部分的支持XSLT转换等的功能. libxml2的 ...

  3. [linux kernel] 内核下ksz8081驱动调试

    系统版本:Ubuntu18.04-64 编译器版本:gcc version 7.4.0 (Ubuntu/Linaro 7.4.0-1ubuntu1~18.04.1) uboot版本:2018.07 - ...

  4. Linux Shell脚本编程基础

    2 Linux Shell脚本编程基础 发表于: Linux, Shell, UNIX, 资源分享 | 作者: 谋万世全局者 标签: Linux,Shell,编程基础,脚本 本文作者:Leal 授权许 ...

  5. Linux内核学习(七):linux kernel内核启动(一):概述篇

    Linux内核学习(七):linux kernel内核启动(一):概述篇 这一篇让我们来大致的了解一下Linux内核的启动过程 这篇文章不涉及源码,重在让你知道这个linux内核的启动过程,源码详细的 ...

  6. Linux 中断学习之小试牛刀篇---Linux中断内核编程

    原址 前言 在前面分析了中断的基本原理后,就可以写一个内核中断程序来体验以下,也可以借此程序继续深入来了解内核中断的执行过程 一.内核中断程序: 我们还是来看一看成程序: 在看程序之前,要熟悉如何进行 ...

  7. Linux C网络编程基础

    目录 Linux套接字结构定义 Linux C的网络基础操作函数 字节顺序转换函数族 IP地址转换函数族 域名转换函数 Linux网络套接字操作函数 创建套接字描述符函数 绑定套接字函数 建立连接函数 ...

  8. Linux kernel内核编译配置选项详解

    转载于:http://lamp.linux.gov.cn/Linux/kernel_options.html 作者:金步国 Code maturity level options 代码成熟度选项 Pr ...

  9. 正式推出Linux Kernel内核5.19

    导读 近日消息,Linus Torvalds 今天发布了 Linux Kernel 版本 5.19,带来了更多新功能.改进的硬件支持以及大量错误 Bug 和安全修复.这里最有趣的部分是,Linus T ...

最新文章

  1. Wpf使用Winform控件后Wpf元素被Winform控件遮盖问题的解决
  2. Linux 操作系统原理 — 内存 — mmap 进程虚拟内存映射
  3. [luoguP1640] [SCOI2010]连续攻击游戏(二分图最大匹配)
  4. vs在linux下的环境搭建,linux下vscode环境配置
  5. 零基础转行web前端,如何高效的去学习web前端?
  6. 腾讯PHP工程师面试题两份
  7. yum的更多用法和源码编译安装apache
  8. PAIP。AHK IDE及相关DOC
  9. IM消息重试机制Java实现_消息的重试机制的设计思路
  10. 图论入门及基础概念(图篇)
  11. java打印特殊符号_Java Poi 在Excel中输出特殊符号的实现方法
  12. 北京大学计算机801考试大纲,2019年中国科学院大学801高等代数考研初试大纲
  13. Firefox,IE5,IE6,IE5.5等浏览器兼容性解决方法
  14. 姐妹素数java_Java之姐妹素数
  15. Android如何关闭硬件加速
  16. ABAQUS软件实训(一):ABAQUS介绍
  17. 英特尔cpu天梯图排名(附台式机CPU天梯图2022年3月份最新版精简图)
  18. 《Flutter入门疑难杂症》ios deactivate没反应的解决方案
  19. oracle数据库中批量把一张表里面的数据插入到不同的表中的方法
  20. 志高显示df什么意思_志高空调故障代码df是什么意思?

热门文章

  1. JavaWeb课程设计——名片管理系统
  2. 手把手教你实战开发黑白棋实时对战游戏
  3. JavaScript 中字符串截取 (+实现)
  4. 神奇的口袋--刚好装满背包的方法总数
  5. python列表过滤的方法
  6. 自己搭建FRP服务器,速度不错!
  7. Android SDK Windows 安装及环境配置教程
  8. 语音识别原理与应用学习笔记
  9. 【5G系列】MICO学习总结(1)
  10. ITIL 4 讲解:事态、事件、灾难流程如何界定?