
### ARM驅動
程序的分種
1.直接運行在硬件上:裸機程序
2.只能運行在對應的操作系統上:應用程序
操作系統
操作系統的定義
- 給應用程序提供運行環境的裸機程序
- 操作系統最底下是linux ,android是中間件,最上層是應用
操作系統的分類
1.任務管理(多任務支持)(最核心的模塊)
2.內存管理(mm)
3.網絡管理(net)
4.文件管理(fs)
5.設備驅動管理(drivers)
6.塊設備(block)
7.對CPU體系的支持(arch)
8.啟動管理(init)
操作系統的分時
1.分時:
2.實時:響應速度
- 單內核:linux(某個代碼出現問題,則操作系統程序就沒法操作)
- 微內核:windows(某個代碼出現問題,并不會影響操作系統)
UNIX
UNIX家族OS的共同特點
1.很簡潔,僅幾百個系統調用
2.所有東西都被當做文件對待
3.C語言編寫內核好喝系統軟件工具,強大的移植力
4.高效地創建進程,獨特的fork()
5.提供一套非常簡單又很穩定的進程間通信元語
6.以文本形式存儲配置數據
內核編程特點
1.無lib,無任何第三方庫,不能包含任何第三方頭文件
2.GNU C而非ANSI C
3.沒有內存保護機制
4.不要輕易在內核中使福浮點數
5.容積小而固定的棧
6.同步和并發
7.可移植性的重要性
- 注意點:異常服務程序不屬于任何一個任務,不是任務所以沒有任何一個狀態.
算法的特征
1.可行性
2.有窮性
設備操作過程
1.設備管理(代碼)
2.任務管理
3.文件管理
4.內存管理
進程與線程
睡眠(任務進行睡眠是為了等待資源的就緒)
- 深度睡眠:只有任務就位才能喚醒
- 淺度睡眠:當信號到來就能喚醒
僵尸進程
- 一個進程fork了一個子進程,父進程結束了,就剩下了子進程,這樣的子進程就是僵尸進程
- 解決僵尸進程:一個進程fork一個子進程,子進程再fork一個孫子進程,將子進程結束,則孫子進程脫離父進程,成獨立的進程.最后,孫子進程也稱為孤兒進程,會被祖宗進程清理掉
內核線程
- pid=0的進程相當于內核,pid=1的進程為祖宗進程
內核空間
1.內核獨立于普通應用程序,它處于系統態
2.擁有受保護的內存空間和訪問硬件設備的所有權限
3.這種處于系統態被保護起來的內存空間,統稱為內核空間
4.如果想要使用,則必須要用接口將內存空間映射到用戶空間下,才能使用,不能直接運用
處理器在任何指定時間點上的活動概況為如下:
1.運用于用戶空間,執行用戶進程(可睡眠)
2.運行于內核空間,處于用戶進程上下文,代表每個特定的進程執行(可睡眠)
3.運行于內核空間,
Linux內核編碼風格
1.接近K&RC風格(K和R這兩個人創建了C語言)
2.縮進
3.switch與case同列
4.空格
(1)空格放在關鍵字周圍
(2)函數名和圓括號之間無空格
(3)函數參數前后無空格
(4)char p,p1;//表示p與p1是char類型的
(5)char* p,p1;//表示p與p1都是char*類型的
5.花括號
(1)函數體采用同列
(2)右花括號可以不單獨占一行,與后續關鍵字同行
6.命名規范
(1)不允許駝峰命名法
7.函數
(1)函數代碼長度不應該超過兩屏
(2)局部變量不應該超過10個
(3)允許使用inline
8.注釋
(1)應該描述代碼要做什么和為什么要做
(2)注釋不應該包含誰寫了哪個函數,
9.Typedef(給已有的數據類型起別名)
(1)內核開發者們強烈反對使用typedef
10.盡量多使用現成的東西,例如:鏈表
11.在源碼中減少代碼量
12.結構體初始化
(1)C99風格初始化
(2)
struct foo my_foo={ .a = INITIAL_A, .b =INITIAL_B
塊設備
1.塊設備:讀數據是按照一塊一塊的讀,一塊是520k
字符設備的編寫
1.進入linux-2.6.32.2/drivers/char
2.mini2440_hello_module.c復制成myhello.c
3.修改Kconfig文件,復制上一段程序,然后組修改
4.修改Makefile文件,復制mini2440_hello_module那一行之后,進行修改
5.然后保存退出
6.編譯:make zImage
7.進入config界面:make menuconfig
- 選擇Device Drivers --->
- 選擇Character devices
- 選擇My module sample,按空格鍵將M改為*號
內核設備的編寫
1.在用戶自己創建的目錄下:創建一個hello.c與Makefile的文件
2.在hello.c中
#include <linux/kernel.h>
#include <linux/module.h>
static int __init mini2440_hello_module_init(void)
{
printk("Hello,Min2440 module is installed !\n");
return 0;
}
static void __exit mini2440_hello_module_cleanup(void)
{
printk("Good_bye,mini2440 module was removed!\n");
}
module_init(mini2440_hello_module_init);
module_exit(mini2440_hello_module_cleanup);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jiang xiu bi");
MODULE_DESCRIPTION("This is example module!!");
MODULE_VERSION("V1.0.0");
- 在Makefile中
ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /home/jxb/1612/1/sq1612/linux-2.6.32.2
PWD :=$(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.symvers *.order
.PHONLY:modules modules_install clean
else
obj-m :=hello.o
#obj-m :=hello2.o
endif
- 運行結果
3.代碼升級,在hello.c中
#include <linux/kernel.h>
#include <linux/module.h>
//#define __init
//#define __exit
static int howmany=1;
static char * name="Jiang xiu bi";
static int __init mini2440_hello_module_init(void)
{
printk("Hello,Min2440 module is installed !\n");
printk("I am %s!\n",name);
printk("I have %d mini2440 board!\n",howmany);
return 0;
}
static void __exit mini2440_hello_module_cleanup(void)
{
printk("Good_bye,mini2440 module was removed!\n");
}
module_init(mini2440_hello_module_init);
module_exit(mini2440_hello_module_cleanup);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jiang xiu bi");
MODULE_DESCRIPTION("This is example module!!");
MODULE_VERSION("V1.0.0");
module_param(howmany,int,S_IRUGO);
module_param(name,charp,S_IRUGO);
EXPORT_SYMBOL(howmany);
EXPORT_SYMBOL(name);
- 在Makefile中
ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /home/jxb/1612/1/sq1612/linux-2.6.32.2
PWD :=$(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.symvers *.order
.PHONLY:modules modules_install clean
else
obj-m :=hello.o
#obj-m :=hello2.o
endif
- 運行結果
- 再升級版,兩個模塊的,在hello.c中
#include <linux/kernel.h>
#include <linux/module.h>
//#define __init
//#define __exit
static int howmany=1;
static char * name="Jiang xiu bi";
static int __init mini2440_hello_module_init(void)
{
printk("Hello,Min2440 module is installed !\n");
printk("I am %s!\n",name);
printk("I have %d mini2440 board!\n",howmany);
return 0;
}
static void __exit mini2440_hello_module_cleanup(void)
{
printk("Good_bye,mini2440 module was removed!\n");
}
module_init(mini2440_hello_module_init);
module_exit(mini2440_hello_module_cleanup);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jiang xiu bi");
MODULE_DESCRIPTION("This is example module!!");
MODULE_VERSION("V1.0.0");
module_param(howmany,int,S_IRUGO);
module_param(name,charp,S_IRUGO);
EXPORT_SYMBOL(howmany);
EXPORT_SYMBOL(name);
- 在hello2.c中
#include <linux/kernel.h>
#include <linux/module.h>
//#define __init
//#define __
extern int howmany;
extern char * name;
static int __init mini2440_hello_module_init(void)
{
printk("Hello,Min2440 module is installed !\n");
printk("I am %s!\n",name);
printk("I have %d mini2440 board!\n",howmany);
return 0;
}
static void __exit mini2440_hello_module_cleanup(void)
{
printk("Good_bye,mini2440 module was removed!\n");
}
module_init(mini2440_hello_module_init);
module_exit(mini2440_hello_module_cleanup);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jiang xiu bi");
MODULE_DESCRIPTION("This is example module!!");
MODULE_VERSION("V1.0.0");
- 在Makefile中
ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /home/jxb/1612/1/sq1612/linux-2.6.32.2
PWD :=$(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.symvers *.order
.PHONLY:modules modules_install clean
else
obj-m :=hello.o
obj-m :=hello2.o
endif
- 運行結果
1.先運行模塊1
2.再運行模塊2
Paste_Image.png