1. 程式人生 > >Linux 第n次驅動入門(一) ---- helloWorld

Linux 第n次驅動入門(一) ---- helloWorld

Linux驅動 helloWorld

根據下面的helloWorld.c驅動來了解總結核心中的printk,__init,__exit

helloWorld.c


#include <linux/init.h>
#include <linux/module.h>

static char* name = "the man like wind ";
module_param(name, charp, S_IRUGO);

static int age = 18;
module_param(age, int, 0644);


static int __init helloWorld_init(void
){ int ret = 0; printk(KERN_INFO "------------------>see you again , world :-)\n"); printk(KERN_INFO "- name : %s\n",name); printk(KERN_INFO "- age : %d\n",age); return ret; } static void __exit helloWorld_exit(void){ printk(KERN_INFO"------------------>bye %s , good world :(\n"
,name); } int add_integer(int a,int b){ return a+b; } EXPORT_SYMBOL(add_integer); int sub_integer(int a,int b){ return a-b; } EXPORT_SYMBOL(sub_integer); module_init(helloWorld_init); module_exit(helloWorld_exit); MODULE_AUTHOR("Qian <[email protected]>"); MODULE_LICENSE("GPL v2"
); MODULE_VERSION("V9.9"); MODULE_ALIAS("a simple helloWorld driver");

1.__exit 和 __init

__init,__initdata,__exit,__exitdata的定義全部在<Linux/init.h>,這些巨集定義的作用就是告訴編譯器把這些函式或者資料放在相應的selection中,其中__init修飾函式。__initdata修飾變數。

靜態載入(直接編入核心)

__init函式在區段.initcall.init中還儲存了一份函式指標,在初始化時核心會通過這些函式指標呼叫這些__init函式指標,並在整個初始化完成後,釋放整個init區段,當模組直接編進核心時,在linux啟動到最後可以看到類似下面的提示,靜態載入時__exit將沒有作用也不會編入核心,因為內建了就不能解除安裝
PHY: 0:01 - Link is Up - 100/Full
VFS: Mounted root (nfs filesystem) on device 0:14.
devtmpfs: mounted
Freeing init memory: 196K
INIT: version 2.86 booting

動態載入(insmod modprobe)

__init進行初始化工作,在模組裝載之後,模組裝載就會將初始化函式扔掉,這樣可以將該函式佔用的記憶體釋放出來。__exit進行清理工作

2.printk列印函式

日誌級別一共有8個級別,printk的日誌級別定義如下(在include/Linux/kernel.h中):  
#define KERN_EMERG 0/*緊急事件訊息,系統崩潰之前提示,表示系統不可用*/  
#define KERN_ALERT 1/*報告訊息,表示必須立即採取措施*/  
#define KERN_CRIT 2/*臨界條件,通常涉及嚴重的硬體或軟體操作失敗*/  
#define KERN_ERR 3/*錯誤條件,驅動程式常用KERN_ERR來報告硬體的錯誤*/ 
#define KERN_WARNING 4/*警告條件,對可能出現問題的情況進行警告*/  
#define KERN_NOTICE 5/*正常但又重要的條件,用於提醒*/  
#define KERN_INFO 6/*提示資訊,如驅動程式啟動時,列印硬體資訊*/  
#define KERN_DEBUG 7/*除錯級別的訊息*/

檢視修改列印級別

#檢視Ubuntu列印級別
study@ubuntu:~$ cat /proc/sys/kernel/printk
4   4   1   7

#####################################################################
#打印出來4個數字的意義                                              
#控制檯日誌級別:優先順序高於該值的訊息將被列印至控制檯             
#預設的訊息日誌級別:將用該優先順序來列印沒有優先順序的訊息
#最低的控制檯日誌級別:控制檯日誌級別可被設定的最小值(最高優先順序)
#預設的控制檯日誌級別:控制檯日誌級別的預設值
#####################################################################

#發現在Ubuntu下無法修改列印級別,本著好學的態度,在一塊開發板上,這樣當我們在驅動中為了除錯,應該把列印級別調到最低就是7
~ # cat /proc/sys/kernel/printk
7       4       1       7
~ # echo 6 4 1 7 > /proc/sys/kernel/printk 
~ # cat /proc/sys/kernel/printk
6       4       1       7

3.幾個驅動使用的命令

insmod  #載入驅動,會執行module_init()修飾的函式
rmmod   #解除安裝驅動,執行module_exit()修飾的函式
lsmod   #列出目前載入的驅動 等同於cat /proc/modules
tree /sys/module/  #insmod後會在/sys/moudle生成驅動名的一個目錄
modprobe #在載入時會同時載入依賴的模組 依賴關係在/lib/modules/<kerel_version>/modules.dep,格式很簡單,下面是copy過來的一個
    kernel/lib/cpu-notifier-error-inject.ko: kernel/lib/notifier-error-inject.ko
modinfo #檢視模組資訊

4驅動程式結構

  • 模組載入函式 ,insmod時會被核心執行,完成初始化工作
  • 模組解除安裝函式 ,rmmod時會被核心執行,完成清理工作
  • 模組許可宣告 ,MODULE_LICENSE(“GPL v2”),不宣告會在載入時提示汙染核心
  • 模組引數(可選),外界可以傳給驅動變數的一個數值
  • 匯出符號(可選),可以匯出一個函式給其他驅動使用
  • 作者別名等其他描述資訊(可選) , 使用MODULE_xx()宣告

4.1模組引數

在/sys/module/驅動名字/parameters所以該驅動匯出模組引數的檔案,可以cat檢視引數值

#可以傳入的引數型別有byte short ushort int uint long ulong charp boo等
static char* name = "the man like wind ";
module_param(name, charp, S_IRUGO);
static int age = 18;
module_param(age, int, 0644);
#這樣在使用時可以insmod *.ko name="leo" age=23
#如果是靜態載入進入核心可以在uboot的bootargs裡設定“模組名.引數名=值”

4.2匯出符號

使用下面巨集匯出符號到核心符號表中
EXPORT_SYMBOL()
EXPORT_SYMBOL_GPL()

#可以通過/proc/kallsyms查詢匯出符號相關資訊
int add_integer(int a,int b){
    return a+b;
}
EXPORT_SYMBOL(add_integer);

int sub_integer(int a,int b){
    return a-b;
}
EXPORT_SYMBOL(sub_integer);

相關推薦

Linux n驅動入門 ---- helloWorld

Linux驅動 helloWorld 根據下面的helloWorld.c驅動來了解總結核心中的printk,__init,__exit helloWorld.c #include <linux/init.h> #include

Linux I2C設備驅動編寫

ive AC ner 解決 args nali smb man lin http://blog.csdn.net/airk000/article/details/21345457 在Linux驅動中I2C系統中主要包含以下幾個成員: I2C adapter 即I2C適配

2個人作業

第2次個人作業(一) 1、 程式碼倉庫:https://gitee.com/ytning/software_operation   2、 PSP表格   Personal software process stages 預估耗時(分鐘)

linux核心SPI匯流排驅動分析

下面有兩個大的模組: 一個是SPI匯流排驅動的分析            (研究了具體實現的過程) 另一個是SPI匯流排驅動的編寫(不用研究具體的實現過程) SPI匯流排驅動分析 1 SPI概述      SPI是英語Serial Peripheral inte

SpringBoot2.x入門[HelloWorld程式]

雲盤地址(版本為17版本) 連結:https://pan.baidu.com/s/1dOxiPSaJGnlLoY73FhXZvw  提取碼:m3mm  使用idea:file-->new-->project 選擇:spring Assistant

Linux設備驅動程序設備驅動程序簡介

包括 收集 字符設備 調度器 計算機 啟動 驅動程序 str 單個 機制or策略: 驅動提供機制(what),而不是提供策略(how); 內核功能劃分: 根據內核完成任務的不同,可分為如下幾個部分: 1. 進程管理 負責進程的的創建和銷毀,並

Linux入門root密碼設置和用戶切換

root 三種方式 變量 blog log div ubun 普通 終端 從這學期開始,本人將會親自開一個Linux 專題學習包括Linux 常用命令,常見問題的一些解決方法,以及Linux系統下C和C++一些學習經驗 下面這張圖片是首次安裝Ubuntu後第一次設置root

java程式設計師菜鳥進階十三linux基礎入門vmvare下安裝linux RedHat圖解超詳細篇

對於linux,我從大二就想學習一下,但一直苦於無從下手,所以一直拖到現在,鑑於筆者瞭解很多人在linux入門的困難在何處,所以我認為本套入門基礎文章還是挺適合想學習linux的朋友,本系列文章大約十篇文章左右,近期會不斷更新下來,沒有linux基礎但又想學習linux的朋友可以關注一下本系列

java+selenium的入門 案例 selenium包 谷歌驅動包 火狐驅動包 IE驅動

目錄 前言 selenium是什麼? Selenium的下載使用 Selenium下載 Selenium下載地址 Selenium之谷歌驅動包 chromedriver包下載地址 Selenium使用 前言 在學習selenium之前,要了解selen

Linux USB 驅動開發—— USB裝置基礎概念

Linux USB 驅動開發(一)—— USB裝置基礎概念           在終端使用者看來,USB裝置為主機提供了多種多樣的附加功能,如檔案傳輸,聲音播放等,但對USB主機來說,它與所有USB裝置的介面都是一致的。一個USB裝置由3個功

Linux 字元裝置驅動結構—— cdev 結構體、裝置號相關知識解析

一、字元裝置基礎知識 1、裝置驅動分類       linux系統將裝置分為3類:字元裝置、塊裝置、網路裝置。使用驅動程式: 字元裝置:是指只能一個位元組一個位元組讀寫的裝置,不能隨機讀取裝置記憶體中的某一資料,讀取資料需要按照先後資料。

SQL入門經典(5版)學習筆記

1.縮寫“SQL”的含義是什麼?stuctured query language 結構化查詢語言 2.SQL命令的6個主要類別是什麼?事務控制命令 commit 資料定義語言 create table 資料操作語言 update 資料查詢語言 select 資料管理命令(進行審計分析 start audit

SmartBear SoapUI Pro入門教程--第一功能測試

SoapUI Pro擁有許多其他web服務測試工具所不具備的高階技術和功能。對於REST、SOAP以及其他流行的API和物聯網協議,SoapUI Pro提供了業界最全面的功能測試功能。通過易用的圖形介面和企業級功能,SoapUI Pro允許你快速建立和執行自動功能測試。在單一環境下,SoapUI P

Linux I2C裝置驅動編寫

在Linux驅動中I2C系統中主要包含以下幾個成員: I2C adapter 即I2C介面卡 I2C driver 某個I2C裝置的裝置驅動,可以以driver理解。 I2C client 某個I2C裝置的裝置宣告,可以以device理解。 I2C adapter 是

Swift快速入門一個Swift程式

1. 本系列說明 本系列只是一個Swift快速入門的教程,並沒有詳盡的介紹Swift,Swift也並不是一個簡單的程式語言,所以要想詳盡的系統的學習Swift,本系列並不適合你,此係列只是讓開發者可以快速的用Swift來進行開發。另外學習本系列並不需要obj-

Linux平臺下Python 指令碼程式設計入門

眾所周知,系統管理員需要精通一門指令碼語言,而且招聘機構列出的職位需求上也會這麼寫。大多數人會認為 Bash (或者其他的 shell 語言)用起來很方便,但一些強大的語言(比如 Python)會給你帶來一些其它的好處。 在 Linux 中學習 Python 指令碼程式設計 首先,我們會使用 Py

MySQL快速入門—Java進階學習十五天

文件版本 開發工具 測試平臺 工程名字 日期 作者 備註 V1.0 2016.05.09 lutianfei none

Linux 下wifi 驅動開發—— WiFi基礎知識解析

 一、WiFi相關基礎概念 1、什麼是wifi        我們看一下百度百科是如何定義的:       Wi-Fi是一種可以將個人電腦、手持裝置(如pad、手機)等終端以無線方式互相連線的技術,事實上它是一個高頻無線電訊號。[1]  無線保真是一個無線網路通訊技術的品牌

Kali Linux 網路掃描祕籍 三章 埠掃描

第三章 埠掃描(一) 作者:Justin Hutchens 譯者:飛龍 3.1 UDP埠掃描 由於 TCP 是更加常用的傳輸層協議,使用 UDP 的服務常常被人遺忘。雖然 UDP 服務本質上擁有被忽視的趨勢,這些服務可以列舉,

Linux下I2C驅動分析

        最近在做一個基於全志A33晶片的android移植時發現嵌入式裝置很多都用到了I2C匯流排通訊,比如說攝像頭,G-sensor,觸控式螢幕等,為此我覺得很好的理解I2C裝置驅動在今後的嵌入式開發中是非常有好處的,而目前我也是處於學習階段,便將這些學習的過程給