1、拿到三星官方移植过的内核
2、在Linux下解压一份在共享目录下,解压一份在Linux的源生目录下。一份编辑,一份编译
3、建立SI工程,添加kernel源代码
4、在Linux下先看makefile中的CROSS_COMPINE交叉编译工具链和ARCH的架构对不对
5、在arch/arm/configs这个目录下找到和我们开发板最接近的一个配置,用这个配置文件,我们在kernel根目录下,make xx_defconfig这个配置文件,得到一个将这个配置文件的内容复制到.config的这个文件,在make menuconfig,退出后,在make -j2 我的Ubuntu是2个处理器,所以可以用2线程加速编译,编译好后,在uboot下用tftp命令下载到内存中,启动一下这个内核看下情况。
5、
(1)我们启动后发现,内核无法启动,并且第一句话都没有打印出来,就是那句解压代码运行的时候打印的信息都没有打印出来,
(2)所以问题就是出在了这里,但是解压代码是不可能出现问题的,因为解压代码是和架构无关的。
(3)所以问题出在内核配置中,配置解压代码将内核解压后,将内核放在哪里了,可能是解压代码解压后将内核放的内存位置不对导致的,这个是在内核配置中可以配置的
(4)内核配置的解压地址应该和内核的链接地址一样,否则自解压后内核是无法运行的。
所以要看内核的链接地址等于多少?内核配置的解压后的内核地址是多少
(5)但是这里面有个问题,就是,我们内核链接的地址是虚拟地址,而我们解压代码解压内核的时候需要的是物理地址,所以上面说的内核配置的解压后的地址的等于,应该是等于内核链接处虚拟地址对应的物理地址。
(6)所以我们要看我们的物理地址和虚拟地址分别是多少,内核链接的时候
在head.S中,虚拟地址找到 虚拟地址是 0XC0008000 物理地址是0X20008000。所以可以知道我们内核配置的自解压地址应该是0X30008000,
(7)自解压地址在mach/Makefile.boot中可以找到,但是这个文件中没有对应的我们开发板的宏中的地址,因为我们的物理地址是根据SMDKV210这个宏找的,所以我们要在这个文件中添加一个配置,配置信息如下:
# override for SMDKV210
zreladdr-$(CONFIG_MACH_SMDKV210) := 0x30008000
params_phys-$(CONFIG_MACH_SMDKV210) := 0x30000100
这里面还有内核参数的地址,都不对,解压地址需要弄成30008000,参数地址要弄成30000100,虽然这个文件中默认配置的解压地址是20008000,内核参数地址是20000100,并且内核物理链接地址在这个kernel中配置的也是20008000,但是因为我们DDR在uboot阶段初始化配置的时候,我们的DDR是从0X30000000-0X3FFFFFFF这段空间的,所以没有2开头的物理内存来用,在下载内核的时候我们也不能将内核下载到这个20008000地址去运行,所以是不行的,多以需要改成30008000,内核链接的物理地址,和解压的物理地址都要改成30008000
1、6、老朱插播的一节课,内核中机器码的确定
1、MACHINE_START宏
(1)这个宏是用来定义一个机器码的数据结构的
(2)在每一个mach-xxx.c的文件中,最后的位置都有一个这个宏,这个宏定义了这个开发板对应的机器码对应的数据结构,这个宏带的参数一个是tpye,一个是name,如果我们将这个宏解析开后,会发现一个是将MACH_TYPE_XXX(这个XXX用tpye这个参数替代了)的机器码,和对应的开发板的名字,并且这个宏将定义的这一个结构体变量放在了一个特定的段中,将我们通过和我们uboot中传递过来的机器码来在这个段中进行机器码的匹配,匹配到了就将这个机器码对应的结构体数据结构取出来准备进行使用。
(3)经过对arch/arm/mach-s5pv210/Makefile的分析,我们发现我们用的是mach-smdkc110.c这个开发板。所以这个文件才是我们值得关注的文件,
2、硬件驱动的加载和初始化函数执行
(4)这个宏中定义的那个结构体变量中,.init_machine = smdkc110_machine_init这个很重要,这个函数就是将来我们内核启动的时候,加载硬件驱动时的初始化函数,如果一旦找到了对应的机器码对应的结构体变量,就会把这个结构体变量拿出来使用,这个变量中的这个.init_machine = smdkc110_machine_init成员,在使用的时候,就会对硬件驱动加载。所以这个函数非常的重要。
分析:由于我们在这个文件machine-smdkc110.c中用那个宏定义了一个结构体变量,放在了特定段中,包含了开发板的机器码。开发板的名字。开发板对应的硬件驱动加载初始化函数的函数指针,这个函数是我们内核启动时初始化所有硬件,内核初始化硬件时打印的相关信息也是从这里打印出来的。
在我们的start_kernel这函数中,将uboot的bootargs参数分割成一个一个的项目,然后又将uboot中传过来的机器码在自己的那个特定段中进行匹配所对应的那个数据结构,这个循环匹配是最终搜索是在.S文件中用__loop去寻找的,并且返回了一个这个类型的结构体指针给一个结构体指针,在后来这个结构体中的那个关于初始化硬件,硬件驱动加载的那个函数就被调用了。所以对硬件驱动进行了加载。所以我们才能在内核启动的时候看到那么多的硬件信息
1、7、之前我们启动内核的时候,内核会重新启动,解决内核启动时的错误
1、认识内核启动OOPS
(1)内核启动时的致命信息就叫OOPS,内核死的原因就在这附近
(2)经过分析这两个错误信息提供了有效信息
PC is at dev_driver_string+0xc/0x44
LR is at max8698_pmic_probe+0x150/0x32c
(3)因为我们的x210开发板,没有这个max8698电源管理IC,而我们的内核中却配置了这个电源IC的驱动,所以会找不到硬件,所以会错误,我们只要在内核配置信息中,将这个配置信息去掉就行,利用make menuconfig,用/搜索max8698,将这项配置取消就行。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。