Uncompressing Linux... done, booting the kernel

本文详细解析了在使用主线Linux内核移植到MINI6410时遇到的启动失败问题,并总结了几个常见原因:1. machinetype不匹配;2. 串口驱动未编译入内核;3. 内核启动参数设置错误;4. bootloader中配置了外部总线。提供了具体的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://blog.chinaunix.net/uid-20543672-id-129729.html


今天用主线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 <augulis.darius@gmail.com> */
       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.     
      10. .nr        = MACH_TYPE_##_type,        \
      11.     
      12. .name        = _name,
      13.


      14. #define MACHINE_END                \
      15. };


    这个宏定义扩展之后的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.


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


         9. .....
        10.


        11.     gd->bd->bi_arch_number = MACH_TYPE;
        12.     gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
        13.


        14.     return 0;
        15. }


    这个宏的定义在: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用完外部总线,将控制权交给内核前,关闭外部总线,让内核自己去配置。或者干脆就别开。

### Linux 启动问题与引导加载程序 #### 解决 Uncompressing Linux... done, booting the kernel 的问题 当遇到 `Uncompressing Linux..................................................done, bootting the kernel.` 停滞不前的情况,这通常意味着内核已经解压完毕但未能成功启动。可能的原因包括但不限于内存不足、文件系统损坏或硬件兼容性问题[^1]。 对于此类问题的排查方法如下: - **检查日志**:通过串口连接或其他方式获取更详细的启动日志信息。 - **更新固件/驱动**:确保使用的U-boot版本是最新的,并且所有必要的设备驱动都已加载。 - **验证镜像**:确认所使用的Linux内核映像是完整的并且适用于当前平台。 #### 使用 Systemd 工具分析启动性能 Systemd 提供了一系列命令用于诊断和优化系统的启动过程。例如,`systemd-analyze time` 可以显示整个启动过程中各个阶段花费的时间;而 `systemd-analyze blame` 则能指出哪些服务消耗了大量的启动时间[^4]。 ```bash # 显示总的启动时间和各部分耗时详情 $ systemd-analyze time # 查看具体的服务及其对应的启动延迟 $ systemd-analyze blame ``` 这些工具不仅有助于理解启动流程中的瓶颈所在,还可以帮助识别潜在的问题源并采取相应的措施加以改进。 #### 调整 RTC 设置加速启动速度 禁用“从RTC设置系统时间”的选项可以在一定程度上加快启动速度。可以通过修改BIOS配置或者在初始化脚本中加入特定指令来实现这一点。比如,在某些情况下执行 `hwclock -s` 替代默认行为能够减少不必要的等待时间[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值