歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Uncompressing Linux... done, booting the kernel

Uncompressing Linux... done, booting the kernel

日期:2017/3/1 10:21:47   编辑:Linux編程

今天用主線Linux內核移植到MINI6410,主線內核2.6.37.1基本已經支持了MINI6410的板子,所以移植到能夠啟動起來的階段很簡單,但是在移植的時候還是出現了一個比較常見的問題:

  1. MINI6410 # bootm 0x50008000
  2. ## Booting kernel from Legacy Image at 50008000 ...
  3. Image Name: Linux-2.6.37.1
  4. Image Type: ARM Linux Kernel Image (uncompressed)
  5. Data Size: 3800644 Bytes = 3.6 MiB
  6. Load Address: 50008000
  7. Entry Point: 50008040
  8. Verifying Checksum ... OK
  9. XIP Kernel Image ... OK
  10. OK
  11. Starting kernel ...
  12. Uncompressing Linux... done, booting the kernel.
  13. 停住不動了~~~~
這種問題比較常見,由於輸出的信息有限,不是很好找原因,如果去代碼中追蹤的話也比較麻煩。在查找原因解決這個問題的時候,我找到了一些可能出現的原因,在這裡總結一下:
1、machine type 不匹配
在內核自解壓完成以後內核會首先會進入 bl __lookup_machine_type函數(在arch/arm/kernel/head.S中),檢查machine_type是否匹配,如果不匹配會跳入__error_a函數(在arch/arm/kernel/head-common.S中),導致啟動失敗。
例如arch/arm/mach-s3c64xx/mach-mini6410.c 查看下面這個結構體:
  1. MACHINE_START(MINI6410, "MINI6410")
  2. /* Maintainer: Darius Augulis <[email protected]> */
  3. .boot_params = S3C64XX_PA_SDRAM + 0x100,
  4. .init_irq = s3c6410_init_irq,
  5. .map_io = mini6410_map_io,
  6. .init_machine = mini6410_machine_init,
  7. .timer = &s3c24xx_timer,
  8. MACHINE_END
這個宏的定義在arch/arm/include/asm/mach/arch.h
  1. /*
  2. * Set of macros to define architecture features. This is built into
  3. * a table by the linker.
  4. */
  5. #define MACHINE_START(_type,_name) \
  6. static const struct machine_desc __mach_desc_##_type \
  7. __used \
  8. __attribute__((__section__(".arch.info.init"))) = { \

  9. .nr = MACH_TYPE_##_type, \

  10. .name = _name,

  11. #define MACHINE_END \
  12. };
這個宏定義擴展之後的machine type 就成了 MACHINE_TYPE_MIN6410。 MACHINE_TYPE_MIN6410這個宏定義在include/generated/mach-types.h
    1. #define MACH_TYPE_MINI6410 2520
machine type在u-boot的配置在board/samsung/mini6410/mini6410.c
    1. /*
    2. * Miscellaneous platform dependent initialisations
    3. */

    4. int board_init(void)
    5. {
    6. s3c64xx_gpio * const gpio = s3c64xx_get_base_gpio();

    7. .....

    8. gd->bd->bi_arch_number = MACH_TYPE;
    9. gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;

    10. return 0;
    11. }
這個宏的定義在:include/configs/mini6410.h
    1. /*
    2. * Architecture magic and machine type
    3. */
    4. #define MACH_TYPE 2520
只要這兩個數對上就可以了。

2、串口驅動沒有編譯入內核

在弄MINI6410的時候我就犯了這個錯誤,因為還沒有MINI6410的默認配置文件,所有這個要自己選上的。位置在Device Drivers->Character devices->Serial drivers中

  1. <*> Samsung SoC serial support
  2. [*] Support for console on Samsung SoC serial port
  3. <*> Samsung S3C6400/S3C6410/S5P6440/S5P6450/S5PC100 Serial port support

3、內核啟動參數設置錯誤

內核的啟動參數的錯誤也可以造成同樣的錯誤,但是這種錯誤可能有幾種:

(1)控制台串口配置字符串不匹配

比如有一個配置是:

  1. noinitrd root=/dev/mtdblock4 rootfstype=jffs2 rw console=ttySAC0,115200 init=/linuxrc mem=64M

關鍵是在console=ttySAC0,115200上,如果ttySAC0弄錯了,或者波特率不對就會出問題。

不同的CPU的console有可能不一樣,比如:

有的可能是ttyS0,

三星的CPU一般是ttySAC0,

早期TI ARM 處理器的一般是ttyS2,

後來TI Omap系列的高版本內核變成了ttyO2。把“S”變成了“ O”,代表Omap。自戀阿~~~~

(2)內存大小配置錯誤 如果在“mem=64M這個參數上配置出現了問題,比如配置過大了,也會出現同樣的現象。 請注意你的系統內存和這個值的匹配關系。

4、在bootloader中開啟並配置了外部總線(GPMC) 在移植TI Omap系列的內核時,發現如果在uboot中開啟並配置了GPMC的某個bank,可能導致無法啟動,也是這個現象。這個可能和Linux內核中對於啟動時的GPMC寄存器讀取和設置有關,暫時還沒有去分析過代碼。 解決的辦法是在bootloader用完外部總線,將控制權交給內核前,關閉外部總線,讓內核自己去配置。或者干脆就別開。
Copyright © Linux教程網 All Rights Reserved