Linux驅動開發環境搭建--exynos4412
Linux驅動開發環境搭建
1,ubuntu中配置編譯環境
設置交叉工具鏈:
tar -xvf gcc-4.6.4.tar.xz -C ~/Linux_4412/toolchain
設置環境變量:
vim ~/.bashrc 最後面添加
export PATH=$PATH:/home/george/Linux_4412/toolchain/gcc-4.6.4/bin
更新腳本:
source ~/.bashrc
arm-none-linux-gnueabi-gcc -v
Using built-in specs.
COLLECT_GCC=arm-none-linux-gnueabi-gcc
COLLECT_LTO_WRAPPER=/home/george/Linux_4412/toolchain/gcc-4.6.4/bin/
../libexec/gcc/arm-arm1176jzfssf-linux-gnueabi/4.6.4/lto-wrapper
2,運行開發
a,通過tftp去啓動內核
1,將uImage和dtb文件放入到ubuntu中/tftpboot
2,在開發板中設置uboot參數,使其能夠去加載內核
set ipaddr 192.168.7.22
set serverip 192.168.7.21
set bootcmd tftp 0x41000000 uImage \; tftp 0x42000000 exynos4412-fs4412.dtb \; bootm 0x41000000 - 0x42000000
save
b,通過nfs去掛載rootfs
1,需要一個跟文件系統目錄--rootfs.tar.xz,需要解壓到ubuntu
sudo tar -xvf rootfs.tar.xz -C /opt/4412/
2, 配置nfs服務器(需要安裝),讓/opt/4412/rootfs可以被掛載
sudo vim /etc/exports
/opt/4412/rootfs *(subtree_check,rw,no_root_squash,async)
sudo service nfs-kernel-server restart //重啓nfs服務器
測試:
sudo mount -t nfs localhost:/opt/4412/rootfs /mnt
3,在開發中去指定內核要掛載/opt/4412/rootfs--切換到開發操作
set bootargs console=ttySAC2,115200 init=/linuxrc root=/dev/nfs rw nfsroot=192.168.7.21:/opt/4412/rootfs ip=192.168.7.22
save
解釋:
bootargs 是uboot傳遞給內核到啓動參數,是一個字符串
console=xxx: 告訴內核啓動時候到調試信息是從哪個設備輸出
init=xxx: 告訴內核linux到第一個用戶進程是什麼
root=xxx : 告訴內核根文件系統在哪裏
root=/dev/nfs 表示根文件系統在網路遠端
nfsroot=ip:path
ip=xxx :告訴內核開機的時候內核的ip地址是多少(靜態分配ip)
3,可以開始去編寫代碼--開發驅動
a, 編譯內核
tar -xvf linux-3.14.tar.xz
步驟:
1,設置交叉工具鏈--uImage也運行arm開發板
vim Makefile
ARCH = arm
CROSS_COMPILE = arm-none-linux-gnueabi-
2, 選擇一個soc ,可以支持很多到soc,所以必須挑出針對我們到平臺到代碼
make exynos_defconfig
// cp -raf arch/arm/configs/exynos_defconfig .config
3,make menuconfig 內核裁剪,產生一個圖像界面
System Type --->
(2) S3C UART to use for low-level messages
4,make uImage : 編譯內核
//如果編譯報錯:缺mkimage
sudo cp -raf mkimage /usr/bin/
sudo chmod 777 /usr/bin/
重新在make uImage
5,編譯設備樹文件--描述設備信息--最終要編譯成dtb
以一個默認到dts爲參考,變成我們自己想要的dts
arch/arm/boot/dts$ cp exynos4412-origen.dts exynos4412-fs4412.dts
arch/arm/boot/dts$ vim Makefile
70行 exynos4412-fs4412.dtb \
回到內核源碼頂層目錄:
george@ubuntu:~/Linux_4412/kernel/linux-3.14$ make dtbs
DTC arch/arm/boot/dts/exynos4210-origen.dtb
DTC arch/arm/boot/dts/exynos4210-smdkv310.dtb
DTC arch/arm/boot/dts/exynos4210-trats.dtb
DTC arch/arm/boot/dts/exynos4210-universal_c210.dtb
DTC arch/arm/boot/dts/exynos4412-odroidx.dtb
DTC arch/arm/boot/dts/exynos4412-origen.dtb
DTC arch/arm/boot/dts/exynos4412-fs4412.dtb
DTC arch/arm/boot/dts/exynos4412-smdk4412.dtb
DTC arch/arm/boot/dts/exynos4412-tiny4412.dtb
DTC arch/arm/boot/dts/exynos4412-trats2.dtb
DTC arch/arm/boot/dts/exynos5250-arndale.dtb
DTC arch/arm/boot/dts/exynos5250-smdk5250.dtb
DTC arch/arm/boot/dts/exynos5250-snow.dtb
DTC arch/arm/boot/dts/exynos5420-arndale-octa.dtb
DTC arch/arm/boot/dts/exynos5420-smdk5420.dtb
DTC arch/arm/boot/dts/exynos5440-sd5v1.dtb
DTC arch/arm/boot/dts/exynos5440-ssdk5440.dtb
使用uImag和dtb文件
cp -raf arch/arm/boot/uImage /tftpboot
cp -raf arch/arm/boot/dts/exynos4412-fs4412.dtb /tftpboot
==============================================
移植dm9000
實際是設備樹文件修改
vim arch/arm/boot/dts/exynos4412-fs4412.dts
添加如下內容:
srom-cs1@5000000 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
reg = <0x5000000 0x1000000>;
ranges;
ethernet@5000000 {
compatible = "davicom,dm9000";
reg = <0x5000000 0x2 0x5000004 0x2>;
interrupt-parent = <&gpx0>;
interrupts = <6 4>;
davicom,no-eeprom;
mac-address = [00 0a 2d a6 55 a2];
};
};
保存退出後,需要再次編譯dts文件
make dtbs
配置內核:
make menuconfig
[*] Networking support --->
Networking options --->
<*> Packet socket
<*> Unix domain sockets
[*] TCP/IP networking
[*] IP: kernel level autoconfiguration
[*] IP: BOOTP support
Device Drivers --->
[*] Network device support --->
[*] Ethernet driver support (NEW) --->
<*> DM9000 support
File systems --->
[*] Network File Systems (NEW) --->
<*> NFS client support
[*] NFS client support for NFS version 2
[*] NFS client support for NFS version 3
[*] NFS client support for the NFSv3 ACL protocol extension
[*] Root file system on NFS
退出到時候要保存:
再次編譯內核:
make uImage -j2
cp -raf arch/arm/boot/uImage /tftpboot
cp -raf arch/arm/boot/dts/exynos4412-fs4412.dtb /tftpboot
在開發板中到uboot設置中,添加一個參數 clk_ignore_unused
set bootargs clk_ignore_unused console=ttySAC2,115200 init=/linuxrc root=/dev/nfs rw nfsroot=192.168.7.21:/opt/4412/rootfs ip=192.168.7.22
重新啓動開發板
b, 編寫驅動代碼
1,用什麼工具去寫---source insight(看代碼的工具)
環境搭建\燒錄鏡像和工具\si_linux3.14-ori.tgz
解壓到內核源碼的頂層目錄:
tar -xvf si_linux3.14-ori.tgz
2,怎麼寫
在souceinsght去寫
驅動代碼需要有四個部分
1,頭文件
#include <linux/init.h>
#include <linux/module.h>
2,驅動模塊裝載和卸載函數入口到聲明
module_init(hello_drv_init);
module_exit(hello_drv_exit);
3,實現模塊裝載和卸載函數入口
static int __init hello_drv_init(void)
{
return 0;
}
static void __exit hello_drv_exit(void)
{
}
4,GPL聲明
MODULE_LICENSE("GPL");
c,編譯驅動代碼--Makefile(被讀取兩次: make 2,內核源碼中Makefile)
ROOTFS_DIR = /opt/4412/rootfs
ifeq ($(KERNELRELEASE), )
#內核源碼到路徑,不同環境會不一樣,內核源碼一定要先編譯
KERNEL_DIR = /home/george/Linux_4412/kernel/linux-3.14
CUR_DIR = $(shell pwd)
all :
make -C $(KERNEL_DIR) M=$(CUR_DIR) modules
clean :
make -C $(KERNEL_DIR) M=$(CUR_DIR) clean
install:
cp -raf *.ko $(ROOTFS_DIR)/drv_module
else
#用於指定到底編譯哪個代碼--hello.c
obj-m += hello.o
endif
d,加載ko
[root@farsight drv_module]# insmod hello.ko
[ 2789.700000] -------hello_drv_init-------------
[root@farsight drv_module]# lsmod
hello 805 0 - Live 0xbf000000 (O)
[root@farsight drv_module]# rmmod hello
rmmod: can't change directory to '/lib/modules': No such file or directory
[root@farsight drv_module]# mkdir /lib/modules
[root@farsight drv_module]# rmmod hello
rmmod: can't change directory to '3.14.0': No such file or directory
[root@farsight drv_module]# mkidr /lib/modules/3.14.0
[root@farsight drv_module]# rmmod hello
[ 2903.230000] -------hello_drv_exit-------------