系統移植
一.服務器的搭建
1. TFTP服務器
1.1 安裝
#sudo apt-get install tftpd-hpa tftp-hpa
1.2配置服務器客戶端在同一網段
服務器 (Ubuntu)$ sudo ifconfig eth0(網卡) 192.168.~.~ netmask 255.255.255.0
上面的命令,將ip地址和子網掩碼設置到內核;
當網卡斷開時,內核會丟掉ip地址;
當網卡連接時,內核會從配置文件(從網絡自動獲取)讀取ip地址和子網掩碼
客戶端 (開發板)# setenv ipaddr 192.168.~.~ 將ip地址設置到ipaddr環境變量
# setenv netmask 255.255.255.0 設置子網掩碼
# saveenv 保存所有的環境變量到emmc
網卡:將虛擬機設置為橋接模式
1.3修改配置文件
# sudo vi /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftpboot" #****指定tftp服務器的根目錄,就是下載文件的位置
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-c -s -l" #這里是選項,-c是可以上傳文件的參數,-s是指定tftpd-hpa服務目錄,上面已經指定 -l 監聽模式
創建tftpboot目錄,重啟啟動 tftp-server
#sudo mkdir /tftpboot
#sudo chmod 777 /tftpboot
#sudo service tftpd-hpa restart
2.通過TFTP服務器移植系統
通過網線將(Ubuntu)中tftp文件夾下的系統配置文件燒寫到開發板中
2.1燒寫kernel(uImage)
1. 拷貝uImage到虛擬機的/tftpboot
2. 下載uImage到開發板內存(0x41000000)
# tftp 41000000(內存地址) uImage
2.2 燒寫設備樹(exynos4412-fs4412.dtb)
1. 拷貝exynos4412-fs4412.dtb到虛擬機的/tftpboot
2. 下載exynos4412-fs4412.dtb到開發板內存(0x41000000)
# tftp 0x41000000(內存地址) exynos4412-fs4412.dtb
3. 燒寫exynos4412-fs4412.dtb到emmc
# movi write dtbs(分區名) 0x41000000(內存,放了exynos4412-fs4412.dtb)
2.3燒寫文件系統rootfs(ramdisk.img)
1. 拷貝ramdisk.img到虛擬機的/tftpboot
2. 下載ramdisk.img到開發板內存(0x41000000)
# tftp 0x41000000(內存地址) ramdisk.img
3. 燒寫ramdisk.img到emmc
# movi write rootfs(分區名) 0x41000000(內存,放了ramdisk.img) 0x300000(分區大小)
2.4手動啟動
1. 設置內核的啟動參數
# setenv bootargs init=/linuxrc(告訴內核第一個應用程序的位置) console=ttySAC2,115200(告訴內核哪個終端是它的輸入/輸出終端)
# saveenv
2. 讀取kernel到內存(運行時以下三個文件要并存,地址要偏移下,不要覆蓋)
# movi read kernel 0x41000000
3. 讀取設備樹到內存
# movi read dtbs 0x42000000
4. 讀取rootfs(ramdisk.img)到內存
# movi read rootfs 0x43000000(放在內存的位置) 0x300000(大小)
5. 啟動內核
#bootm 0x41000000(內核) 0x43000000(根文件系統) 0x42000000(設備樹的位置)
2.5自動啟動
1. 原理
u-boot啟動后,如果倒計時到0, 它會自動運行bootcmd環境變量中的命令
2. 設置bootcmd環境變量
# setenv bootcmd movi read kernel 0x41000000\;movi read dtbs 0x42000000\;movi read rootfs 0x43000000 0x300000\;bootm 0x41000000 0x43000000 0x42000000
# saveenv
3. 重啟開發板
注:當出現下載不動,終端一直打印T時,檢查服務器配置,端口設置,重啟服務器
3.通過NFS服務器掛載網絡文件系統
3.1原理
將開發板上的文件系統掛載到服務器(Ubuntu)上,實現服務器和開發板可以同時對改文件系統進行操作。
3.2 安裝
#sudo apt-get install nfs-kernel-server nfs-common
3.3修改配置文件系統
sudo vi /etc/exports
在注視下添加一行:
/source/rootfs *(rw,sync,no_root_squash,no_subtree_check)
/source/rootfs”是存放nfs文件系統的路徑;“*”表示在所有的網段都可以共享;“rw”表示nfs文件系統允許讀寫;
“sync”表示修改都會同步到nfs服務端,否則只是會暫存在本地內存;
新建配置文件指定的對應的nfs服務器根目錄
sudo mkdir -p /source/rootfs
重啟nfs服務程序,使配置生效
sudo service nfs-kernel-server restart
3.4就該開發板Uboot的內核啟動參數
//根文件系統通過nfs協議去掛載 網絡文件系統存放的位置
#setenv bootargs root=/dev/nfs rw nfsroot=192.168.1.250:/source/rootfs ip=192.168.1.4(內核用到的ip地址,因為內核要和nfs服務器進行網絡通訊) console=ttySAC2,115200 init=/linuxrc
(3) 設置自動運行命令
#setenv bootcmd tftp 41000000 uImage\;tftp 42000000 exynos4412-fs4412.dtb\;bootm 41000000 - 42000000 ("-"表示不指定根文件系統地址)
#saveenv
3. boot或重啟開發板
二.U-boot
1.BootLoader.
1.1簡介:
屬于嵌入式系統的軟件層次,固話在固件中的boot程序,類似于(BOIS),grub,它是在操作系統運行前執行的一小段程序,主要是用于引導操作系統。
1.2基本功能
a.初始化硬件 b.把BootLoader自搬到內存中 c.執行用戶命令(訪問環境變量,網絡,串口通訊,讀寫ram/flash) d.設置Linux啟動參數
1.3 執行過程
不同的處理器上電或復位后執行的第一條指令地址并不相同,對于 ARM 處理器來說,該地址為 0x00000000。
對于一般的嵌入式系統,通常把 Flash 等非易失性存儲器映射到這個地址處,而 Bootloader就位于該存儲器的最前端,
所以系統上電或復位后執行的第一段程序便是Bootloader。而因為存儲 Bootloader的存儲器不同,Bootloader的執行過程也并不相同,
嵌入式系統中廣泛采用的非易失性存儲器通常是 Flash,而 Flash 又分為 Nor Flash 和Nand Flash 兩種。
它們之間的不同在于:Nor Flash 支持芯片內執行(XIP, eXecute In Place),這樣代碼可以在Flash上直接執行而不必拷貝到RAM中去執行。
而Nand Flash并不支持XIP,所以要想執行 Nand Flash 上的代碼,必須先將其拷貝到 RAM中去,然后跳到 RAM 中去執行
2.uboot分析
2.1 uboot特點
代碼結構清晰,易于一直,支持多種CUP,可以支持多種操作系統,支持許多開發板,支持多種協議文件系統。
2.2uboot常用命令
setenv var value 設置環境變量
setenv var 刪除var變量
saveenv <==>save
printenv <==> pri
特殊變量 bootcmd uboot在自啟動模式下會自動執行。
bootcmd 在uboot啟動的時候,當倒計時到0的時候,uboot會去找到bootcmd環境變量,取得它的值。
bootcmd的值都是一些uboot可執行的命令,uboot會去自動執行這些命令。
bootargs linux內核啟動參數,uboot會將此環境變量的值存到啟動參數區,內核在啟動的時候,首先會去啟動參數區
獲取相關參數,解析處理,做相應的處理。參數格式,名稱不能隨意,固定的。
2.3uboot啟動流程
第一階段:匯編
1>初始化硬件(CPU內部的寄存器)
2>初始化RAM,為第二階段程序準備空間
3>拷貝第二階段的程序到內存空間
4>跳轉到第二階段C入口
第二階段:C語言
1>初始化硬件(板級硬件設備)
2>將內核和根文件系統鏡像加載到內存中
3>執行內核
3.U-BOOT移植
3.1基本步驟
1.找到相近的代碼,并拷貝一份作為自己修改的源碼
2.先修改源碼,使能核心部件(uart clock ram..),能串口輸出信息。
3.移植修改其他非核心源碼
三.Linux內核
1 Linux內核的基本組成
a.MM內存管理
b.PM進程管理
c.FS文件系統
d.DC驅動架構
e.NET網絡
f.驅動代碼(占很大部分代碼)
Linux內核是一個有文件系統,多任務管理,硬件抽象層2等功能的系統軟件。內核不是一個完整的操作系統
linux系統 = Linux kernel + lib + apps + GUI(圖形界面 qt window gome)
2.Linux內核的特征
2.1特點
1.可裁剪,可擴展,可定制。
2.可移植性強,支持多種體系結構。
3.穩定性強,網絡功能強。
4.支持多任務多用戶,資源耗費少。
2.2內核源碼目錄
git分布式 svn托管 代碼管理系統
*arch 體系結構相關代碼,各體系結構cpu
arch/arm/板子 arm體系結構 目錄都是開發板
mach-開發板名稱
開發板相關代碼,以前有各個板子硬件信息。
后面device tree技術出來之后,硬件信息提取出來。
boot/compressed 下面是壓縮解壓代碼(image<->zImage --mkimage--> uImage)
arch/arm/kernel/head.S是第一個被執行文件
boot/dts 設備樹源碼文件
.dtsi 設備樹頭文件 .h
.dts 設備樹源碼 .c
.dtb 被編譯過的產物
*Documentation 文檔
init 內核啟動初始化代碼 不可裁剪
lib 通用庫實現
sound 音頻驅動
block 塊設備
*drivers 設備驅動
ipc 進程間通訊
fs 文件系統
include 通用頭文件
kernel 核心代碼不可裁剪 pm
scripts 配置編譯腳本 這些腳本用于系統源碼的配置和編譯
mm 內存管理
3.配置編譯
1.修改源碼目錄下頂層的Makefile
ARCH ?= arm
CROSS_COMPILE ?= arm-none-linux-gnueabi-
2.找一個與開發板類似的缺省配置,參考導入默認參考配置
make exynos_defconfig(只用執行一次,生成一個默認的.config)
3.執行配置命令
make menuconfig 字符界面配置菜單,需要ncureses庫
sudo apt-get install ncurses-dev
4.內核啟動流程
上電--->CPU跳到中斷向量處執行--->加載并執行bootloader代碼--->加載內核--->
執行內核---->掛載根文件系統--》運行第一個用戶空間程序 bootargs init=/linuxrc