標籤:
本文將介紹如何移植linux-3.4.2核心到JZ2440開發板上的全過程,使用的交叉編譯工具版本為 arm-linux-gcc-4.3.2.tar.bz2
下面來一步一步介紹如何移植。
由於kernel的啟動參數是由Uboot傳遞的,關鍵的參數有 R0=0 R1=Mach-Type R2=Tag參數地址
其中,Mach-Type為核心支援板子的硬體型號,tag參數為Uboot存放傳遞給Kernel參數的記憶體位址。
核心啟動時,根據傳入的Mach-Type參數選擇對應的板級初始化函數來初始化,然後解析tag參數,設定相應系統狀態值,裝載驅動程式,最後掛載根檔案系統。
1. 編譯核心
修改根目錄下面的Makefile,該ARCH ?= arm ,CROSS_COMPILE ?= arm-linux-
針對arm架構的板級設定檔,位於 arch/arm/configs/mini2440_defconfig 和 s3c2410_defconfig 這兩個有參考意義的設定檔。
配置核心 make s3c2410_defconfig
編譯核心 make uImage //最終產生的uImage位於 arch/arm/boot/uImage
測試新核心 開機進入boot命令列,tftp 0x32000000 uImage ; bootm 0x32000000;
問題解決:新核心啟動後,有可能串口列印出亂碼,原因可能是 Uboot沒有傳遞 console 的正確參數,也有可能是核心對於串口時鐘頻率沒有初始化成功。
Uboot啟動時傳遞的Mach-Type,如果有命令列指定的,則使用指定的,否則就使用環境變數中的machid值。
對於核心來說,每種硬體設定的板子都對於一個固定的Mach-Type ID,Uboot傳遞的Mach-Typ必須與其一致,這樣,核心才能正確識別。
最少的核心啟動命令列: set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 ; set machid MACH_ID
核心支援的板級列表檔案為: include/generated/mach-types.h
這裡,我們使用的是smdk2440配置:
1: //arch/arm/mach-s3c24xx/mach-smdk2440.c
2: static void __init smdk2440_map_io(void)
3: {
4: s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
5: s3c24xx_init_clocks(12000000); //將原來的16934400 改為 12000000
6: s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
7: }
然後,重新編譯,測試就可以。
2. 修改核心預設分區
預設核心啟動,對nand flash的分區如下:
這樣的分區,不是我們想要的,通過在核心代碼中搜尋 “S2C2410 flash partitions 1”可以找到位於 common-smdk.c中smdk_default_nand_part分區數組。
我們期望的分區為:
,經過修改後的分區數組如下:
1: // arch/arm/mach-s3c24xx/common-smdk.c
2: static struct mtd_partition smdk_default_nand_part[] = {
3: [0] = {
4: .name = "Bootloader",
5: .size = SZ_256K,
6: .offset = 0,
7: },
8: [1] = {
9: .name = "params",
10: .offset = MTDPART_OFS_APPEND,
11: .size = SZ_128K,
12: },
13: [2] = {
14: .name = "kernel",
15: .offset = MTDPART_OFS_APPEND,
16: .size = SZ_2M,
17: },
18: [3] = {
19: .name = "rootfs",
20: .offset = MTDPART_OFS_APPEND,
21: .size = MTDPART_SIZ_FULL,
22: }
23: };
3. 修改核心支援yaffs2檔案系統
3.4.2核心版本 預設支援 jaffs2 檔案系統,而且在掛載根檔案系統的過程中,嘗試能夠支援的檔案系統類型(ext2,3,cramfs,vfat,msdos romfs等)
如果檔案系統類型為 jffs2類型,需要重新設定bootargs,
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2
如果是yaffs2類型,不需要重新設定
編譯根檔案系統的編譯器最好和編譯核心的編譯器保持一致。 先配置好交叉編譯工具鏈,然後編譯Busybox後,執行 make install CONFIG_PREFIX=/home/hao/nfs/fs_mini_mdev_new/ , 這樣,基本的檔案系統架構出來了。
接著,安裝glibc庫, 拷貝交叉編譯工具鏈目錄下的 這兩個庫的所有的so檔案拷貝到 fs_mini_mdev_new目錄下的lib目錄(建立立的lib目錄),拷貝的時候,注意 cp *so* /home/hao/nfs/fs_mini_mdev_new/lib –d -d選項拷貝保留連結屬性。目錄屬性對應一致。
構建基本的linux目錄,etc目錄,這個目錄可以參考以前已經建立好的etc目錄
dev目錄,這個目錄下,需要事先建立兩個特殊裝置 console 和null ,具體資訊可以參考linux系統上的裝置
其他必須的目錄有,proc,tmp,mnt,sys,root等。
建立jffs2檔案類型的根檔案系統:
mkfs.jffs2 -n -s 2048 -e 128KiB -d fs_mini_mdev_new -o fs_mini_mdev_new.jffs2
-s 扇區大小
-e 可擦除塊
-d 來源目錄
-o 輸出檔案
如果出現 :
說明,核心收到結束代碼為0x04的訊號,經過查閱得知為非法指令,可能是核心不支援由此編譯器編譯出的init的特殊指令,需要設定核心支援此指令。
Kernel Features –> Use the ARM EABI to compile the kernel 選中已支援 eabi特性。
為什麼核心不支援yaffs2檔案系統呢?因為核心代碼中不包含yaffs檔案系統源碼,但是包含jffs2檔案系統源碼。
通過git命令下載yaffs2檔案系統源碼:git clone git://www.aleph1.co.uk/yaffs2
切換到yaffs2目錄中,執行 ./patch-ker.sh c m /to/linux/dir ,然後去linux源碼中,通過make menuconfig來配置yaffs2即可。
編譯yaffs2中出現的錯誤,是yaffs中結構體函數引用不正確,加上底線就可以了。
另外,需要在 最新版本的Uboot的代碼 drivers/mtd/nand/nand_util.c 中 ,添加 WITH_YAFFS_OOB這一項,就可以正常啟動yaffs格式的uImage了。
// drivers/mtd/nand/nand_util.c
555 if (!need_skip && !(flags & WITH_DROP_FFS) && !(WITH_YAFFS_OOB)) {
556 rval = nand_write(nand, offset, length, buffer);
557 if (rval == 0)
558 return 0;
559
560 *length = 0;
561 printf("NAND write to offset %llx failed %d\n",
562 offset, rval);
563 return rval;
564 }
4. 裁剪核心
現在 .config設定檔中找支援的單板類型,然後在menuconfig中搜尋選項配置位置,按圖索驥,去掉對於支援類型選項。
去掉核心支援的其他單板類型,只保留指定單板代碼:
搜尋可知: ,去掉對於支援的類型即可。
在嵌入式領域用不到的檔案系統,可以去掉,例如 ext2、ext3、ext4等。msdos要保留,應該以後可能會接隨身碟,而隨身碟一般為vfat檔案系統。
……..寫的不好,未完待續……………..
Technorati 標籤: kernel 移植
移植3.4.2的Kernel到JZ2440