新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > Linux2.6.22內核移植

        Linux2.6.22內核移植

        作者: 時間:2016-11-21 來源:網絡 收藏
        平臺:mini2440 交叉工具鏈:arm-linux-gcc-4.3.2
        一、內核移植基本知識
        移植內核也叫構建BSP(boardsupprot packet)。BSP的作用有兩個:一是為內核運行提供底層支持,二是屏蔽與板相關的細節。
        BSP的構建分三個層次
        1、體系結構層次
        對一些體系結提供linux內核支持,比如說ARM,X86等芯片。這一類工作一般在arc/xxx/下面額除了palt-xxx和mach-xxx目錄的其他目錄完成。
        2、SOC層次
        對一些公司提供的SOC微處理器提供linux內核支持,比如說三星公司的 S3C2440。這一類工作一般在arch/xxx/plat-xxxxarch/xxx/mach-xxxx目錄下完成。我們可以看到在arch /arm/目錄下同時有plat-s3c24xx和mach-s3c2440兩個目錄,這樣做是因為plat-s3c24xx目錄下存放了所有s3c24 系列相同的代碼,mach-s3c2440則只存放了與S3C2440有關的代碼。
        2,板級層次
        這是我們一般的菜鳥要做的,上面兩個層次一般有芯片公司的大牛完成了,但是不同的電路板的板級層次則需要由我們菜鳥完成的。這一類工作主要在mach- xxxx/目錄下面的板文件完成,比如說mach-s3c2440/smdk-s3c2440.c這個S3C2440標準板文件。很多文檔很多書籍都都直接在這個文件里面進行修改,這樣是不對的,對于不同的電路板應該建立不同的板文件,比如說我的是mini2440,就應該建立一個smdk- mini2440.c文件或者mach-mini2440.c文件在mach-s3c2440下面。如果直接在里面修改是非常不規范的做法,這樣不是在移植內核,這樣是在破壞內核!(這一句是宋寶華說的)。
        下面開始移植。
        二、BSP構建
        1.建立板文件支持
        這一步我會重新建立一個板文件mach-mini2440.c,而不是直接在smdk-s3c2440.c里面修改,這樣或許麻煩一些,但是為了保持對內核尊重的態度和規范的做法,認為應該這樣做。
        如果我們重新建立一個空的板文件將會導致大量的工作量,幸運的是smdk-s3c2440.c文件已經幫我們做了大量的工作,我們直接拷貝過來命名為mach-mini2440.c
        cp arch/arm/mach-s3c2440/smdks3c2440.c arch/arm/mach-s3c2440/mach-mini2440.c
        修改arch/arm/mach-s3c2440/mach-mini2440.c文件將MACHINE_START宏括號里面的名字換成ID換成 MINI2440,名字隨便取,我們取“MINI2440”,這個ID最終會被擴展為MACH_TYPE_MINI2440,然后到arch/arm /tools/mach_types里面找對應的ID號,所有做完以這一步我們要在mach_types添加我們機器的ID
        MACHINE_START(MINI2440,"MINI2440")
        .phys_io = S3C2410_PA_UART,
        .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18)& 0xfffc,
        .boot_params = S3C2410_SDRAM_PA + 0x100,
        .init_irq = s3c24xx_init_irq,
        .map_io = smdk2440_map_io,
        .init_machine = smdk2440_machine_init,
        .timer = &s3c24xx_timer,
        MACHINE_END
        然后在mach_types里面添加我們機器的ID,再最后一行添加
        mini2440 MACH_MINI2440 MINI2440 1999
        第一個表示機器名字,這個也隨便取,第二個在Kconfig配置項里面定義的宏名稱,下面一步我們會定義到,我們取名為MACH_MINI2440,第三表示MACH_START第一個參數ID名字,第四個是ID號。ID號我們取為1999。
        修改arch/arm/mach-s3c2440/目錄下的Kconfig和Makefile,以建立內核對板文件的支持使其可以被配置和編譯進內核。
        首先修改Kconfig,在endmenu之前加入下面的內容:
        87 config MACH_MINI2440 // 開發板名稱宏定義
        88 bool "mini2440" // 開發板名稱
        89 select CPU_S3C2440 // 開發板使用的處理器類型
        90 help
        91 Say Y here if you are using the mini2440. // 幫助信息
        再修改Makefile:
        obj-$(CONFIG_MACH_MINI2440)+= mach-mini2440.o
        注意這一行要添加在obj-$(CONFIG_ARCH_S3C2440)+= smdk-s3c2440.o后面,否則會編譯錯誤。
        這樣我們就可以通過makemenuconfig配置mini2440的板文件是否編譯進內核。
        我們再跳到linux-2.6.22目錄,執行makemenuconfig
        執行加載默認配置文件后,可以開始配置新增加的菜單。進入System Types菜單項,打開S3C24XX Implementations菜單,出現一個目標開發板的列表:
        [ ] Simtec ElectronicsBAST (EB2410ITX)
        [ ] IPAQ H1940
        [ ] Acer N30
        [ ] SMDK2410/A9M2410
        [ ] SMDK2440
        [ ] AESOP2440
        [ ] Thorcom VR1000
        [ ] HP iPAQ rx3715
        [ ] NexVision OTOM Board
        [ ] NexVision NEXCODER2440 Light Board
        [ ] mini2440
        選中mini2440選項
        然后執行makezImage,如果能夠正常編譯,已經能夠將mini2440板文件編譯進內核了。如果不行,請檢查上述步驟。
        2.修改機器碼
        將編譯在arch/arm/boot下面生成的zImage燒寫到nand的kernel分區,然后啟動。
        Copylinux kernel from 0x00060000 to 0x30008000, size = 0x00500000 ... done
        zImage magic = 0x016f2818
        Setup linux parameters at 0x30000100
        linux command line is: "console=ttySAC0 root=/dev/nfsnfsroot=192.168.1.101:/home/work/shiyan/rootfsip=192.168.1.102:192.168.1.101:192.168.1.1:255.255.255.0:mini2440:eth0:off"
        MACH_TYPE = 362
        NOW, Booting Linux......
        UncompressingLinux.................................................................................................done, booting the kernel.
        Error: unrecognized/unsupported machine ID (r1 = 0x0000016a).
        內核提示不能識別的機器ID,于是修改bootloader的參數使其機器ID為1999,我用的是supervivi使用命令:
        set parammach_type 1999
        3.修改時鐘源頻率
        啟動內核,出現一系列的亂碼,這是因為時鐘源設置的不對,我的開發板用的是12M的晶振,所以在arch/arm/mach-s3c2440.c的 s3c24xx_init_clocks(16934400);處將16924400修改為12000000。即改為 s3c24xx_init_clocks(12000000);
        4.添加nand分區信息
        再啟動,發現還是不能啟動,這是因為內核中填寫的nand分區信息不對。于是修改nand分區信息,很多人的做法是直接修改arch/arm /plat-s3c24xx/Common-smdk.c文件里面的smdk_default_nand_part數據結構,這樣是不提倡的做法,因為還是那句話,破壞了內核。我們應該再arch/arm/mach-s3c2440/mach-mini2440.c文件中建立我們自己板文件的nand信息。我們在mach-mini2440.c的staticstruct platform_device *smdk2440_devices[]前面添加
        static struct mtd_partition smdk_default_nand_part[] = {
        //這里面填的是我用的mini2440分區信息//
        [0] = {
        .name = "patition1 supervivi",
        .size = 0x00040000,
        .offset = 0,
        },
        [1] = {
        .name = "patition2 param",
        .offset =0x00040000,
        .size = 0x00020000,
        },
        [2] = {
        .name = "patition3 kernel",
        .offset =0x00060000,
        .size = 0x00500000,
        },
        [3] = {
        .name = "patition4 root",
        .offset = 0x00560000,
        .size = 64*1024*1024,
        },
        [4] = {
        .name = "patition5 nand",
        .offset = 0,
        .size = 64*1024*1024,
        },
        };
        static struct s3c2410_nand_set smdk_nand_sets[] = {
        [0] = {
        .name = "NAND",
        .nr_chips = 1,
        .nr_partitions = ARRAY_SIZE(smdk_default_nand_part),
        .partitions = smdk_default_nand_part,
        },
        };
        再修改mach-mini2440.c的smdk2440_machine_init函數,將我們的nand傳給給nand設備
        static void __init smdk2440_machine_init(void)
        {
        s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg);
        //將我們的nand信息傳給nand設備//
        s3c_device_nand.dev.platform_data= &smdk_nand_info; //set nand infoto nand
        platform_add_devices(smdk2440_devices,ARRAY_SIZE(smdk2440_devices));
        //smdk_machine_init();
        //smdk_machine_init()函數屏蔽,因為他會將arch/arm/plat-s3c24xx/Common-smdk.c里面的分區信息傳給nand,這樣我們的自己的nand信息就被覆蓋了
        s3c2410_pm_init();//添加加這個函數是因為smdk_machine_init()里面調用了。
        }
        再修改mach-mini2440.c的smdk2440_devices
        static struct platform_device *smdk2440_devices[] __initdata = {
        &s3c_device_usb,
        &s3c_device_lcd,
        &s3c_device_nand,//向內核添加nand設備
        &s3c_device_wdt,
        &s3c_device_i2c,
        &s3c_device_iis,
        };
        6.添加YAFFS文件系統支持
        完成上述步驟工作后,還是不能正常掛載根文件系統,因為內核還沒對yaffs文件系統進行支持。
        下載cvs-root-yaffs.tar.gz補丁包文件,解壓,運行yaffs2文件夾里面的腳本文件patch-ker.sh來給內核打補丁,用法如下
        Usage: ./patch-ker.sh c/l kernelpath
        if c/l is c,then copy, if l then link
        如果是l則yaffs2源碼被鏈接到內核,如果是c則復制
        我們運行./patch-ker.sh c work/kernel_make/linux2.6.22
        給內核打上yaffs2補丁,然后使用makemenuconfig配置內核使其支持yaffs2文件系統
        File systems --->
        Miscellaneous filesystems --->
        <*>YAFFS2 file system support
        7.配置內核支持EABI接口
        完成上面的步驟之后運行,內核會在輸出
        VFS: Mounted root (yaffs filesystem) on device 31:2.
        Freeing init memory: 132K
        之后卡住,這個打印反應出內核實際上已經掛接上了根文件系統,之所以卡在這里是因為無法啟動根文件系統上的init進程。是由于內核和根文件系統的應用程序的接口不一致。所以在內核中使用make menuconfig配置EABI支持
        Kernel Features --->
        Memory split...--->
        [ ]preemptible Kernel...
        [*]Use the ARM EABI to compile thekernel
        [*] Allow old ABI binaries to run......
        Memory model(flatMemory)--->
        [ ]Add lru list to tarcknon-evictable pages


        關鍵詞: Linux2.6.22內核移

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 碌曲县| 安丘市| 贡觉县| 灵川县| 丽江市| 福安市| 治多县| 靖宇县| 宿州市| 瑞金市| 古丈县| 乾安县| 普陀区| 张家港市| 鱼台县| 桐柏县| 安图县| 轮台县| 桑日县| 偃师市| 图片| 江孜县| 新安县| 伽师县| 潢川县| 肃南| 德安县| 格尔木市| 沅江市| 工布江达县| 开阳县| 博客| 临颍县| 崇州市| 永靖县| 游戏| 盖州市| 翁牛特旗| 巩义市| 烟台市| 方城县|