Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

嵌入式Linux编译内核步骤 / 重点解决机器码问题 / 三星2451 #27

Open
carloscn opened this issue Apr 11, 2022 · 0 comments

Comments

@carloscn
Copy link
Owner

嵌入式系统更新内核

1. 前言

手里有一块Friendly ARM的MINI2451的板子,这周试着编译内核,然后更新一下这个板子的Linux内核,想要更新Linux Kernel 4.1版本,但是种种原因实在是没有更新成功;于是使用Friendly ARM板子提供的3.6版本的内核,但是他们的内核全都配置好了,你只需要按照常规的方法进行编译就好了,貌似不能更深入的理解内核, 后来我从kernel.org官网上下载原版内核,然后一点点的把2451这个板子需要文件移植过去,可谓是问题百出啊,也学习到了很多东西。

2. 准备材料

  • FriendlyARM 的mini2451板子一块
  • 使用的bootloader是FriendARM提供的闭源Superboot2451.bin
  • Linux3.6内核源代码(在官网下的,纯净的)
  • mini2451提供的.config文件

3. 烧写内核的几个重点

3.1 拿到全新内核的几个步骤

我们拿到全新内核的时候,一定要注意几个步骤,好像并没有几个书上由我写的这么详细的,基本上都是给一个大体的思路,但是到了真刀真枪上场的时候,真的是问题百出。以下讲围绕这几个方面进行讨论。

a) 修改顶层Makefile

b) Machine ID的处理( 在arch/arm/ 的mach中增加C文件 -> 修改Kconfig -> 修改Makefile文件 )

c) 在arch/arm/tools/mach-types 文件中增加Machine ID

3.1.1 修改顶层的Makefile

Makefile一共要修改2个地方即可:

  • 修改arch架构: ARCH ?= arm 注意,arm这几个后面不要打空格啊,要不然make的时候不识别。

    • 修改cross_compile 路径:CROSS_COMPILE?= /home/user/toolchian/arm-linux-

    注意1,CROSS_COMPILE的表述,我这里给的是全路径,而不是像书籍和网络博客上给的 arm-linux- ,这里为什么呢?因为你的电脑里面可能装了不是一个交叉编译环境的工具链,所以这里强烈推荐使用交叉编译环境的绝对路径,绝对不会出错,可以放心大胆的使用。

    注意2,arm-linux- 后面不要加空格,否则不会识别的,和ARCH那个选项一样,都不要有空格。 否则就会抛出:“ make: ** /home/delvis/work/linux-3.6/arch/arm: 是一个目录。 停止。”的错误。

Makefile只需要改这两个位置就可以了,大可保存。

3.1.2 为了Machine ID准备之修改C文件

路径就是 -> ./arch/arm/ 里面关于mach-"各种型号",你在教学视频或者书上经常看见如下的说明:

找一个和你板子型号相近的c文件然后复制一份出来。

我使用的是Linux3.2内核且,我的板子的型号是S3C2451的,所以很理所应当的找到mach-s3c24xx这个文件夹, ! 但是我发现在Linux4.1和Linux2.4版本的内核中没有mach-s3c24xx这个文件夹,其实没有什么关系,只要找到和你板子芯片型号相近的就可以的。

我这里是复制FriendlyARM提供的mach-mini2451.c这个文件,在这个文件需要注意几个地方,我现在还不是很明白这个文件是做什么的,看里面很多初始化的程序包括GPIO、时钟、定时器、中断等等,应该是对2451板子进行初始化的。暂时我还不会写,靠移植吧。

  • 文件末尾MACHINE_START( USER_DEFINE_STRING, "USER_DEFINE_STRING" ) { .... } 这个就是MACHINE id 的位置
  • 还有其中定义的函数,需要依赖很多头文件,原生内核里面没有,缺什么我就从FriendlyARM里面拷贝到相应的目录。

文件末尾的MACHINE_START传递的参数的USER_DEFINE_STRING就是我们一会儿要写入machine id的宏定义,我这里宏定义的字符串是MACH_MINI2451

3.1.3 修改mach-xxxx中的Kconfig文件

刚才刚刚添加了新的mach-mini2451.c的文件,就要在和这个文件同一个目录下的Kconfig中加入这个的配置项,我给出我的配置项:

config MACH_MINI2451
        bool "MINI2451BYDELVIS"
        #select S3C24XX_SMDK
        select S3C_DEV_FB
        select S3C_DEV_HSMMC
        select S3C_DEV_HSMMC1
        select S3C_DEV_NAND
        select S3C_DEV_USB_HOST
        select S3C2416_SETUP_SDHCI
        select WIRELESS_EXT
        select WEXT_SPY
        select WEXT_PRIV
        select AVERAGE
        help
          Say Y here if you are using an FriendlyARM MINI2451

在Kconfig中增加这个字符串,在顶层进行make menuconfig的时候,这个选项就会出来,我们在make menuconfig的时候,最先应该的就是选择板子的架构

  1. System Type --> ARM sytem type( Samsung S3C24XX Socs ) --> Samsung S3C24XX SoCs

选择后返回上一层

2)SASUNG S3C24XX SoCs Support ---> 先选上 SASUNG S3C2416/S3C2450 ---> 下面自动出 MINI2451BYDELVIS 一会儿说这个菜单的显示逻辑如何的

3)Exit 并且 Save 成为.config

这些菜单的逻辑和归属主要是Kconfig决定的,我们的config MACH_MINI2451这个条目要放到正确的位置,不是随便放一个位置就行,我们的每一个子菜单对于.config来说都是一项配置。

Kconfig中config MACH_MINI2451的位置

看图,首先注意两个画红圈的位置,我们讲config MACH_MINI2451这一坨放在了 if CPU_S3C2416 ..... endif这个里面,也就是说我们在make menuconfig中选择了”MINI2451BYDELVIS“这个选项的时候,MACH_MINI2451默认在.config文件CPU为S3C2416,(也可见,我们的mach-mini2451.c文件是复制mach-s3c2416.c文件改装而来了)

在make menuconfig菜单中,也只有选择S3C2416这个CPU型号,我们的这个选项才会出现

3.1.3 修改mach-s3c24xx文件下的Makefile文件

我们平白无故的增加了mach-mini2451.c文件,如果进行全局编译的时候,是不会进行编译的,因为没有makefile进行指导编译,所以我们需要修改这一层的Makefile,当我进行全局编译的时候,就有规则指导编译器进行编译。

# add by Carlos 2017.12.6
obj-$(CONFIG_MACH_MINI2451)             += mach-mini2451.o mini2451-lcds.o

在这一层的Makefile文件中随便找一个位置,然后按照这个格式输出文件。

3.1.4 增加机器码

说到机器码,我真的不得不吐槽一下Friendly ARM,在购买Friendly ARM的时候,购买的宣传界面,大篇幅的说他们花了重金开发了Superboot2451.bin企业级的bootloader,重点是闭源,bootloader还是不错的,从SD卡引导,支持串口,驱动支持的挺全的,还有一个他们独创的可视化界面miniTools的USBMODE一键安装系统,一键下载程序。**但是好歹闭源的同时,把bootloader的关键参数给出啊!!!!**我找了他们的Wiki,找了官网,手册,就是没有知道Superboot2451.bin的Machine ID,好歹把ID值给出来啊。

恩,后来经过实验输出,得到强大的闭源Superboot2451.bin的 机器码 machine id 是: 0x00000695

好了,吐槽到此为止,我还是建议自己开发uboot,这样方便。

只有bootloader和kernel中的机器码一样,内核才能正常启动,否则将会抛出:

Error: unrecognized/unsupported machine ID (r1 = 0x33f60264).

我们要么改正uboot中的ID,要么改正kernel中的ID,总之,无论数字是什么,要一样。

好了,Superboot2451.bin的既然是闭源的就没办法进行改正了,那么我们只能改正Kernel中的ID了,那么Kernel中的ID该怎么改正呢?

切换到: arch/arm/tools/文件夹,里面有个mach-types文件,我们在后面追加一个:

mini2451 MACH_MINI2451 MINI2451 0x695

细心的朋友已经发现了,在上面的章节中,零零散散的文件用的也是这些字符,也就是mini2451、MACH_MINI2451、MINI2451这个宏定义都是这个ID值。

到此我们的的内核配置完毕了。

3.2 make menuconfig配置

切换到最后一步,进行make menuconfig进行.config的配置,在韦东山老师的视频里面,提到这个.config文件来源于三个部分

  1. 进行make menuconfig配置后的,你需要一条条的进行配置。
  2. 使用默认配置,在上面修改
  3. 使用厂家提供的

我这里,使用厂家提供的mini2451_linux_config文件,在上面进行修改,首先就把运行把这个config文件复制过来,并且名字改为.config覆盖原有的.config文件,然后进行make menucofig,在system type中如同上面讲述的选择正确的板子的型号。如果你没有选择,就会出现这样的异常,在内核编译到最后的时候,出现编译kernel出现no machine record defined 错误。然后一些鬼一样的网站给出馊主意,还被大量的博客转载,简直就是误导人,你经过google或者百度,会有一个这样的解决方案

这里给一个!反!面!教!材!:

放狗搜后,按照如下方法可以解决。将arch/arm/kernel/vmlinux.lds的最后两行(如下),给注释起来,但都没说是为了什么
ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support"),
ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")

反面教材来源:uncompressing linux .................................................后没反应解决办法 前半部分

简直是神一样的操作,出错了,注释起来就可以维持了,什么逻辑,简直是对技术的侮辱!!!我尝试过了,的确内核编译通过了,可以把内核传输到ARM上面,到Load Kernel的下一步,就抛出了Error: unrecognized/unsupported machine ID (r1 = 0x33f60264). 的异常,显然是没有机器码没有定义。

注释这个鬼方法根本就不能用好吗?谁出的馊主意!!

正确的解法是:

按照我们上面的章节进行配置,顺理成章的解决Machine ID的问题: ->

  1. Machine ID的处理( 在arch/arm/ 的mach中增加C文件 -> 修改Kconfig -> 修改Makefile文件 )

  2. 在arch/arm/tools/mach-types 文件中增加Machine ID

  3. 在make menuconfig的menu中选择system type,选择正确的型号,会自动配置到.config

3.3 make

然后开始make就可以了,编译内核,我一般都喜欢用make -j8 多线程编程,速度快,但是很烧CPU。。。

基本上都是这样的状态。。。看温度。

编译完成之后,按照Friendly ARM提供的文档,把zImage文件拷到SD卡正确的路径,然后从SD卡启动正常烧写就好了。

4 总结

看到这样的输出的时候,真的很激动,终于内核开始正常解压了。磨了人好几天。


第15周主要搞内核的搞完了,最近要忙着复习考试,内核事情可能要稍微缓缓了。以后再慢慢研究。

参考文献:

[1] 贵气的博客著.Error: unrecognized/unsupported machine ID (r1 = 0x33f60264)..新浪博客.2011-03-20.

[2]韦东山著.《嵌入式Linux完全开发手册-应用开发》书籍.

[3]FriendlyARM著.2451开发手册. 用户手册.


版权声明:

1. 本文为MULTIBEANS团队研发跟随文章,未经允许不得转载。

2· 文中涉及的内容若有侵权行为,请与本人联系,本人会及时删除。

3· 尊重成果,本文将用的参考文献全部给出,向无私的工程师,爱好者致敬。


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant