linux 2.6.32.2 mini2440平臺移植--內核移植、yaffs2文件系統移植

1.1           獲取Linux內核源代碼

有很多方式可以獲取Linux內核源代碼,如果你的linux平臺可以上互聯網,可以直接在命令行輸入以下命令獲取到Linux-2.6.32.2:

#wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.32.2.tar.gz

當然你也可以先在Windows系統下使用迅雷等工具下載完,再複製到linux中。

1.2 解壓內核源代碼

假定我們剛纔把內核源代碼下載到了/root/mini2440目錄,執行以下解壓命

令:

#cd  /opt/FriendlyARM/mini2440

#tar  xvzf  linux-2.6.32.2.tar.gz

1.3 指定交叉編譯變量

我們移植目的是讓Linux-2.6.32.2可以在mini2440上運行。

首先,我們要使得Linux-2.6.32.2的缺省目標平臺成爲ARM的平臺。

修改總目錄下的Makefile

export KBUILD_BUILDHOST := $(SUBARCH)

ARCH  ?= $(SUBARCH)

CROSS_COMPILE ?= 

改爲

export KBUILD_BUILDHOST := $(SUBARCH)

ARCH  ?= arm

CROSS_COMPILE ?= arm-linux-

其中,ARCH是指定目標平臺爲armCROSS_COMPILE是指定交叉編譯器,這裏指定的是系統默認的交叉編譯器,如要使用其它的,則要把編譯器的全路徑在這裏寫出。

接下來,要測試一下linux的編譯是否能正常通過。

執行:

#make s3c2410_defconfig ;使用缺省內核配置文件,s3c2410_defconfigSMDK2440的缺省配置文件,我的s3c2410_defconfig文件位於/arch/arm/configs/s3c2410_defconfig

#make ;編譯時間較長

 

編譯通過,在此我們先不必燒寫到開發板驗證它的正確性。

 

1.4 克隆建立自己的目標平臺

1.4.1關於機器碼

 

以上編譯是用的Linux內核本身支持的目標平臺配置,它對應於SMDK2440。現在我們要參考SMDK2440加入自已的開發板平臺,我們使用的是mini2440,因此取名爲MINI2440。需要說明的是,Linux-2.6.32.2本身已經包含了mini2440的支持,這樣就出現了重名。那怎麼辦呢?在此我們依然使用MINI2440這個名稱,只不過在後面的移植步驟中,把原始內核自帶的mini2440代碼部分直接刪除就可以了,以免和我們自己移植的混淆了。首先,很關鍵的一點,內核在啓動時,是通過bootloader傳入的機器碼(MACH_TYPE)確定應啓動哪種目標平臺的,友善之臂已經爲mini2440申請了自己的機器碼爲1999,它位於linux-2.6.32.2/arch/arm/tools/mach_types文件中.

如果內核的機器碼和bootloader傳入的不匹配,就會經常出現下面的錯誤:

Uncompressing Linux.................................................................................................................................. done, booting

the kernel.

運行到這不就停住了

提示:在U-boot/include/asm-arm/mach-types.h中可以看到mini2440的機器碼定義

接下來,我們注意到linux-2.6.32.2/arch/arm/mach-s3c2440目錄下有個

mach-mini2440.c文件,它其實就是國外愛好者爲mini2440移植添加的主要內容了,但我們不用它,把它直接刪除。將linux-2.6.32.2/arch/arm/mach-s3c2440/目錄下的mach-smdk2440.c複製一份。命名爲mach-mini2440.c

找到MACHINE_START(S3C2440, "SMDK2440"),修改爲

MACHINE_START(MINI2440, "FriendlyARM Mini2440 development board")

提示:開發板運行後,在命令行終端輸入:cat /proc/cpuinfo 可以看到我們添加的開發板信息

 

1.4.2 修改時鐘源頻率

現在再來修改系統時鐘源,在mach-mini2440.c(就是我們剛剛通過複製

mach-smdk2440.c得到的)的第160static void __init smdk2440_map_io(void)函數中,把其中的16934400(代表原SMDK2440目標板上的晶振是16.9344MHz)改爲mini2440開發板上實際使用的12,000,000(代表mini2440開發板上的晶振12MHz,元器件標號爲X2)

 

1.4.3 SMDK2440MINI2440

因爲我們要製作自己的mini2440平臺體系,因此mach-mini2440.c中所有的

smdk2440字樣改爲mini2440,可以使用批處理命令修改,在vim的命令模式下輸入:

%s/smdk2440/mini2440/g

上面這句的意思是:把所有和“smdk2440”匹配的字符串全部替換爲“mini2440”,前面的“%s“代表字符串匹配,最後的“g”代表global,是全局的意思,

除此之外,還有一個地方需要改動,mini2440_machine_init(void)函數中,把

smdk_machine_init()函數調用註釋掉,因爲我們後面會編寫自己的初始化函數,不需要調用smdk2440原來的.

 

1.4.4 編譯測試

Linux源代碼根目錄下執行

#make mini2440_defconfig ;使用Linux官方自帶的mini2440配置

#make zImage ;編譯內核,時間較長,最後會生成zImage

我的s3c2410_defconfig文件位於/arch/arm/configs/mini2440_defconfig

重新編譯並把生成的內核文件zImage(位於arch/arm/boot目錄)下到板子中,可以看到內核已經可以正常啓動了,但此時大部分硬件驅動還沒加,並且也沒有文件系統,因此還無法登陸。

注意:

1)如果你先前已經編譯過內核了,請先清理一下,不然會提示編譯的文件過時了。

2)注意在先前關於機器碼一項時修改的MACHINE_START(S3C2440, "SMDK2440"),修改爲

MACHINE_START(MINI2440, "FriendlyARM Mini2440 development board")

這裏的MINI2440必須要大寫,我自己的理解是跟機器碼裏面的類型一致。

 

1.5 關於內核配置菜單中的mini2440選項

 

在開始移植其他驅動之前,我們再瞭解一些看起來比較“神祕”的常識,那就是運行make menuconfig時,內核配置菜單中的mini2440選項是如何出現的。

在命令行執行:

#make menuconfig  ;前面已經執行了make mini2440_defconfig加載了缺省配置,因此這裏可以直接執行該命令

按上下鍵移動到System Type,按回車進入該子菜單,再找到S3C2440 Machines,按回車進入該子菜單

在此就可以看到Linux天生內核對mini2440開發板的支持選項了,那麼它們是從哪裏來的呢?

打開Linux-2.6.32.2/arch/arm/mach-s3c2440/Kconfig文件可以找到相關信息。

 

現在明白了吧,“MINI2440 development board”正是在這個Kconfig文件中定義說明的,

當然你可以根據自己的喜好改爲其他顯示信息。

這裏的顯示信息只是在內核配置菜單中出現的,要讓選擇的配置實際起效,還需要根據此配置在Makefile中添加相應的代碼文件,請看該目錄下的Makefile。

 

這樣,配置文件就跟實際的代碼文件通過配置定義聯繫在一起了,這裏的配置定義是“CONFIG_MACH_MINI2440”,內核中還有很多類似的配置定義,並且有的配置定義還存在依賴關係,我們在此就不對它們詳細說明了,隨着對內核代碼結構的不斷熟悉,你就會逐漸學會分析和查找你所需要的各種配置和定義等。

 

1.6 移植Nand驅動並更改分區信息

1.6.1 Linux-2.6.32.2內核所支持的Nand Flash類型

 

Linux2.6.32.2已經自帶了大部分Nand Flash驅動,在

linux-2.6.32.2/drivers/mtd/nand/nand_ids.c文件中,定義了所支持的各種Nand Flash類型。

 

1.6.2 修改Nand Flash分區表

 

但是系統默認的分區不是我們所需的,所以要自已修改,除此之外,還有Nand Flash的結構信息需要增加填寫,以便能夠適合系統自帶的Nand Flash驅動接口,這可以參考SMDK2440中關於Nand Flash設備註冊的一些信息。

打開/arch/arm/plat-s3c24xx/common-smdk.c,可以看到這樣一個結構體:

注意這裏是參考這個文件夾的內容,改動還是在mach-mini2440.c

static struct mtd_partition smdk_default_nand_part[] = {

        [0] = {

                .name   = "Boot Agent",

                .size   = SZ_16K,

                .offset = 0,

        },

        [1] = {

                .name   = "S3C2410 flash partition 1",

                .offset = 0,

                .size   = SZ_2M,

        },

        [2] = {

                .name   = "S3C2410 flash partition 2",

                .offset = SZ_4M,

                .size   = SZ_4M,

        },

        [3] = {

                .name   = "S3C2410 flash partition 3",

                .offset = SZ_8M,

                .size   = SZ_2M,

        },

        [4] = {

                .name   = "S3C2410 flash partition 4",

                .offset = SZ_1M * 10,

                .size   = SZ_4M,

        },

        [5] = {

                .name   = "S3C2410 flash partition 5",

                .offset = SZ_1M * 14,

                .size   = SZ_1M * 10,

        },

        [6] = {

                .name   = "S3C2410 flash partition 6",

                .offset = SZ_1M * 24,

                .size   = SZ_1M * 24,

        },

        [7] = {

                .name   = "S3C2410 flash partition 7",

                .offset = SZ_1M * 48,

                .size   = SZ_16M,

        }

};

這其實就是Nand Flash的分區表,在Linux-2.6.32.2中,nand驅動是被註冊爲平臺設備的,這同樣可在/arch/arm/plat-24xx/common-smdk.c文件中看出,如下:

static struct s3c2410_platform_nand smdk_nand_info = {

        .tacls          = 20,

        .twrph0         = 60,

        .twrph1         = 20,

        .nr_sets        = ARRAY_SIZE(smdk_nand_sets),

        .sets           = smdk_nand_sets,

};

 

/* devices we initialise */

 

static struct platform_device __initdata *smdk_devs[] = {

        &s3c_device_nand,

        &smdk_led4,

        &smdk_led5,

        &smdk_led6,

        &smdk_led7,

};

參考以上結構信息,我們也在自己的mach-mini2440.c中照此添加實現,同時需要參考友善之臂原廠內核中的Nand分區表

 

 

 

因此,在mach-mini2440.c中加入以下代碼:

首先添加幾個頭文件:

#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>

#include <plat/nand.h> 

然後加入以下代碼:

static struct mtd_partition mini2440_default_nand_part[] = {

        [0] = {

                .name   = "supervivi", //這裏是bootloader所在的分區,可以放置u-boot, supervivi等內容,對應/dev/mtdblock0

                .size   = 0x00040000,

                .offset = 0,

        },

        [1] = {

                .name   = "param", //這裏是supervivi的參數區,其實也屬於bootloader的一部分,如果u-boot比較大,可以把此區域覆蓋掉,不會影響系統啓動,對應/dev/mtdblock1

                .offset = 0x00040000,

                .size   = 0x00020000,

        },

 

 

        [2] = {

                .name   = "Kernel", //內核所在的分區,大小爲5M,足夠放下大部分自己定製的巨型內核了,比如內核使用了更大的Linux Logo圖片等,對應/dev/mtdblock2

                .offset = 0x00060000,

                .size   = 0x00500000,

        },

        [3] = {

                .name   = "root", //文件系統分區,友善之臂主要用來存放yaffs2文件系統內容,對應/dev/mtdblock3

                .offset = 0x00560000,

                .size   = 1024 * 1024 * 1024, //

        },

        [4] = {

                .name   = "nand", //此區域代表了整片的nand flash,主要是預留使用,比如以後可以通過應用程序訪問讀取/dev/mtdblock4就能實現備份整片nand flash了。

                .offset = 0x00000000,

                .size   = 1024 * 1024 * 1024, //

        }

};

//這裏是開發板的nand flash設置表,因爲板子上只有一片,因此也就只有一個表

static struct s3c2410_nand_set mini2440_nand_sets[] = {

        [0] = {

                .name           = "NAND",

                .nr_chips       = 1,

                .nr_partitions  = ARRAY_SIZE(mini2440_default_nand_part),

                .partitions     = mini2440_default_nand_part,

        },

};

//這裏是nand flash本身的一些特性,一般需要對照datasheet填寫,大部分情況下按照以下參數填寫即可

static struct s3c2410_platform_nand mini2440_nand_info = {

        .tacls          = 20,

        .twrph0         = 60,

        .twrph1         = 20,

        .nr_sets        = ARRAY_SIZE(mini2440_nand_sets),

        .sets           = mini2440_nand_sets,

        .ignore_unset_ecc = 1,

};

//除此之外,還需要把nand flash設備註冊到系統中,

static struct platform_device *mini2440_devices[] __initdata = {

 &s3c_device_usb,

 &s3c_device_lcd,

 &s3c_device_wdt,

 &s3c_device_i2c0,

 &s3c_device_iis,

 &s3c_device_nand, //nand flash設備添加到開發板的設備列表結構

};

 

找到下邊程序添加一條語句:

static void __init mini2440_machine_init(void){

s3c24xx_fb_set_platdata(&mini2440_fb_info);

s3c_i2c0_set_platdata(NULL);

s3c_device_nand.dev.platform_data = &mini2440_nand_info;  //添加

platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));

}


注意:mini2440_default_nand_partmini2440_nand_setsmini2440_nand_info三個結構體順序不能錯。另外,這三段最好放在頂端頭文件的下邊,之前測試過放在下邊有編譯出錯的情況不知時候與位置有關。。。

到這裏就完成了NandFlash的驅動的移植,可以下載到開發板運行看看啓動的信息了。

 

 

1.6.3 從啓動信息中查看分區表

注意:雖然說開始信息裏面uncorrectable error :這樣的錯誤,但是還是可以繼續成功,這裏不要在意這些error。

 

至此,就完成了nand flash驅動的移植,此時在內核根目錄執行“make zImage”,把生成的zImage燒寫到開發板,可以在啓動時看到如圖紅色信息,它們正是我們剛剛添加的nand flash分區信息,以及開發板本身nand flash的一些信息,這裏可以看到是256M的nand flash。

 

 

S3C24XX NAND Driver, (c) 2004 Simtec Electronics

s3c24xx-nand s3c2440-nand: Tacls=3, 29ns Twrph0=7 69ns, Twrph1=3 29ns

s3c24xx-nand s3c2440-nand: NAND soft ECC

NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bi

t)

Scanning device for bad blocks

Bad eraseblock 256 at 0x000002000000

Bad eraseblock 257 at 0x000002020000

Bad eraseblock 317 at 0x0000027a0000

Bad eraseblock 1261 at 0x000009da0000

Creating 5 MTD partitions on "NAND 256MiB 3,3V 8-bit":

0x000000000000-0x000000040000 : "supervivi"

uncorrectable error :

0x000000040000-0x000000060000 : "param"

ftl_cs: FTL header not found.

0x000000060000-0x000000560000 : "Kernel"

0x000000560000-0x000040560000 : "root"

mtd: partition "root" extends beyond the end of device "NAND 256MiB 3,3V 8-bit"

-- size truncated to 0xfaa0000

ftl_cs: FTL header not found.

0x000000000000-0x000040000000 : "nand"

mtd: partition "nand" extends beyond the end of device "NAND 256MiB 3,3V 8-bit"

-- size truncated to 0x10000000

uncorrectable error :

dm9000 Ethernet Driver, V1.31

dm9000 dm9000: eth%d: Invalid ethernet MAC address. Please set using ifconfig

eth0: dm9000e at c486e300,c4872304 IRQ 51 MAC: 00:00:00:00:00:00 (chip)

ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver

s3c2410-ohci s3c2410-ohci: S3C24XX OHCI

s3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1

s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000

usb usb1: configuration #1 chosen from 1 choice

hub 1-0:1.0: USB hub found

hub 1-0:1.0: 2 ports detected

usbcore: registered new interface driver libusual

s3c2440-usbgadget s3c2440-usbgadget: S3C2440: increasing FIFO to 128 bytes

mice: PS/2 mouse device common for all mice

S3C24XX RTC, (c) 2004,2006 Simtec Electronics

s3c2410-rtc s3c2410-rtc: rtc disabled, re-enabling

s3c2410-rtc s3c2410-rtc: rtc core: registered s3c as rtc0

i2c /dev entries driver

S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics

s3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq enabled

cpuidle: using governor ladder

sdhci: Secure Digital Host Controller Interface driver

sdhci: Copyright(c) Pierre Ossman

s3c-sdi s3c2440-sdi: powered down.

s3c-sdi s3c2440-sdi: mmc0 - using pio, sw SDIO IRQ

usbcore: registered new interface driver hiddev

usbcore: registered new interface driver usbhid

 

1.7 移植yaffs2

1.7.1 獲取yaffs2源代碼

 

現在大部分開發板都可以支持yaffs2文件系統,它是專門針對嵌入式設備,特別是使用nand flash作爲存儲器的嵌入式設備而創建的一種文件系統,早先的yaffs僅支持小頁(512byte/page)nand flash,現在的開發板大都配備了更大容量的nand flash,它們一般是大頁模式的(2K/page),使用yaffs2就可以支持大頁的nand flash,下面是yaffs2的移植詳細步驟。

http://www.yaffs.net/node/346

 可以下載到最新的yaffs2源代碼,需要使用git工具,在命令行輸入:

#git  clone git://www.aleph1.co.uk/yaffs2

稍等片刻,就可以下載到最新的yaffs2的源代碼目錄。

 

1.7.2 爲內核打上yaffs2補丁

這可以通過yaffs2目錄下的腳本文件patch-ker.sh來給內核打補丁,用法如下:

[root@localhost yaffs2]# ./patch-ker.sh c /root/linux-test/linux-2.6.32.2
usage:  ./patch-ker.sh  c/l m/s kernelpath
 if c/l is c, then copy. If l then link
 if m/s is m, then use multi version code. If s then use single version code  //注意這一句話,根據自己需要選用第二個參數是m還是s
[root@localhost yaffs2]# ./patch-ker.sh c s /root/linux-test/linux-2.6.32.2

*** Warning ***
You have chosen to use the single kernel variant of the yaffs VFS glue code
that only works with the latest Linux kernel tree. If you are using an older
version of Linux then you probably wanted to use the multi-version variant by
re-running the patch-ker.sh script using m as a the second argument.
 ie ./patch-ker.sh c m /root/linux-test/linux-2.6.32.2

Updating /root/linux-test/linux-2.6.32.2/fs/Kconfig
Updating /root/linux-test/linux-2.6.32.2/fs/Makefile
[root@localhost yaffs2]#

注意第二個參數m/s,如果不指定,有時會執行失敗。

上述命令完成下面三件事://有助於理解

<1>修改內核文件/fs/Kconfig,增加下面兩行(在177行附近):

if MISC_FILESYSTEMS

source "fs/adfs/Kconfig"
source "fs/affs/Kconfig"
source "fs/ecryptfs/Kconfig"
source "fs/hfs/Kconfig"
source "fs/hfsplus/Kconfig"
source "fs/befs/Kconfig"
source "fs/bfs/Kconfig"
source "fs/efs/Kconfig"
source "fs/yaffs2/Kconfig"
source "fs/jffs2/Kconfig"
# UBIFS File system configuration

<2>修改內核文件/fs/Makefile,增加下面兩行(在129行附近):

obj-$(CONFIG_GFS2_FS)           += gfs2/
obj-$(CONFIG_EXOFS_FS)          += exofs/
obj-$(CONFIG_YAFFS_FS)  += yaffs2/

<3>在內核文件的fs目錄下創建yaffs2子目錄,然後複製如下文件:

將yaffs2源碼目錄下的Makefile.kernel文件複製爲內核fs/yaffs2/Makefile文件。

將yaffs2源碼目錄下的Kconfig文件複製爲內核fs/yaffs2/目錄下。

將yaffs2源碼目錄下的*.c、*.h文件(不包括子目錄下的文件)複製爲內核fs/yaffs2/目錄下。

1.7.3 配置和編譯帶YAFFS2支持的內核

 Linux 內核源代碼根目錄運行:make menuconfig,移動上下按鍵找到 File Systems,按回車進入該子菜單再找到"Miscellaneous filesystems"菜單項,按回車進入該子菜單,找到"YAFFS2 file system support",並按空格選中它,這樣我們就在內核中添加了 yaffs2文件系統的支持,按"Exit"退出內核配置。

在命令行執行:

#make zImage

最後會生成linux-2.6.32.2/arch/arm/boot/zImage,使用supervivi的“k“功能把它燒寫到nand flash,按“b“啓動系統,這時,如果nand flash已經存在文件系統(可以使用supervivi的“y“功能燒寫友善之臂提供的現成的yaffs2文件系統映像root_qtopia-128M.img用以測試),如果可以進入文件系統了,這說明yaffs2已經移植成功。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章