相信大家在开发嵌入式Linux系统时,一定遇到过卡在Starting kernel...而运行不下去的情况,这种类型的问题主要有两个原因,下面我们就一一了解下。
Device Tree出现之前
Device Tree出现之前,也就是kernel 3.0之前的版本,这种情况下,当bootloader将控制权移交给kernel时,kernel会将自身的Machine ID与bootloader的Machine ID进行对比,这时,如果二者不一致,则会出现卡在Starting kernel的情况。那么这个Machine ID是什么?又在哪里进行修改呢?
由于ARM嵌入式系统芯片和平台种类繁多,也不像x86硬件系统有自己的标准体系,所以,Linux Kernel需要依赖bootloader告诉它是什么ARM平台,这样才能知道去匹配相应的hard code在kernel里的相关硬件定义及BSP代码(也就是arch/arm/mach-xxxx目录),这就是Machine ID出现的根源所在。
所以当我们做了一个新板子时,需要先向社区申请Machine ID(http://www.arm.linux.org.uk/developer/machines/),或者沿用类似已有平台的Machine ID,之后,我们要修改u-boot下的Machine ID,则需要到board/xxx/xxx.c中的board init函数中去制定相应的Machine ID。比如以ti的am335x评估板为例,其名称为MACH_TYPE_AM335EVM,修改目录在/board/ti/am335x/evm.c。
然后可以在u-boot的arch/arm/include/asm/mach-types.h中查看相应的Machine ID的数值。
另外,如果在u-boot命令终端下,可以通过bdinfo命令查看arch_number的数值即Machine ID。
Device Tree出现之后
Kernel自3.0以后,开始统一用Device Tree来描述板级硬件,这样避免了大量hard code在kernel中的与平台相关的代码,这些原本hard code的代码,现在通过Device Tree进行描述和动态展开。
在Device Tree时代,不再通过Machine ID进行板子的匹配,而是通过Device Tree,所以,当uboot环境变量fdt_file与生成的Device Tree的dtb文件名称不一致或找不到相应的dtb文件时,就会出现卡在Starting kernel的情况。这种类型的错误,现在一般u-boot层面会报出相应的错误log,所以比较容易定位问题。
所以当我们做了一个新板子时,需要到kernel的arch/arm/boot/dts目录下创建和修改自己的Device Tree文件,而u-boot下,我们只需要修改环境变量fdt_file指定相应的dtb文件。
小结
出现卡在Starting kernel...的主要原因有两种,分Device Tree出现前后对应的两种可能的原因,另外,也注意检查下uboot向kernel传递的参数有没有拼写错误之类的低级原因。
欢迎大家扫描下方二维码关注我的个人微信公众号EmbeddedLinuxer,一起交流学习,谢谢。