内核移植——开发板的软件抽象(struct machine_desc)

news2024/11/23 9:10:07

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。

内核支持什么架构、支持哪款cpu,这是如何确定的?主要是通过机器码来确定的。

内核中定义了一份机器码,uboot也会给内核传递一个机器码。

在内核启动的汇编阶段,head.S文件对比uboot传给内核的机器码和内核定义的机器码,如果匹配则继续启动。

本文主要讲内核如何定义机器码的(以下内容说的是三星待移植版本内核)。

1、struct machine_desc 结构体

这个结构体定义在/arch/arm/include/asm/mach/arch.h文件中,它的内容如下:

struct machine_desc {
	/*
	 * Note! The first four elements are used
	 * by assembler code in head.S, head-common.S
	 */
	unsigned int		nr;		/* architecture number	*/
	unsigned int		phys_io;	/* start of physical io	*/
	unsigned int		io_pg_offst;	/* byte offset for io 
						 * page tabe entry	*/

	const char		*name;		/* architecture name	*/
	unsigned long		boot_params;	/* tagged list		*/

	unsigned int		video_start;	/* start of video RAM	*/
	unsigned int		video_end;	/* end of video RAM	*/

	unsigned int		reserve_lp0 :1;	/* never has lp0	*/
	unsigned int		reserve_lp1 :1;	/* never has lp1	*/
	unsigned int		reserve_lp2 :1;	/* never has lp2	*/
	unsigned int		soft_reboot :1;	/* soft reboot		*/
	void			(*fixup)(struct machine_desc *,
					 struct tag *, char **,
					 struct meminfo *);
	void			(*map_io)(void);/* IO mapping function	*/
	void			(*init_irq)(void);
	struct sys_timer	*timer;		/* system tick timer	*/
	void			(*init_machine)(void);
};

这个结构体的一个实例,就是一块开发板的软件抽象。

2、mach-xxx/mach-yyy.c文件

在内核源码/arch/arm/目录中有许多mach-xxx目录(不同的xxx表示不同的CPU),这些mach-xxx目录中又有许多mach-yyy.c文件(表示采用相同CPU的不同开发板,而且开发板名字就叫yyy)。

分析发现,每个mach-yyy.c文件中,都通过MACHINE_START宏,定义了一个表征某个开发板的struct machine_desc类型的变量。而且这些结构体变量都被放到.arch.info.init段,表示当前内核可以支持这些机器码对应的开发板。

2.1 宏 MACHINE_START 的简介

这个宏定义在/arch/arm/include/asm/mach/arch.h文件中,它的内容如下:

/*
 * Set of macros to define architecture features.  This is built into
 * a table by the linker.
 */
#define MACHINE_START(_type,_name)			\
static const struct machine_desc __mach_desc_##_type	\
 __used							\
 __attribute__((__section__(".arch.info.init"))) = {	\
	.nr		= MACH_TYPE_##_type,		\
	.name		= _name,

#define MACHINE_END				\
};

这个宏用来定义一个数据类型为 struct machine_desc 的变量(实际上只定义了结构体前面部分的内容),而且这个变量会被定义到一个特定段.arch.info.init,因此这个变量将来会被链接器链接到这个.arch.info.init段中。

2.1.1 举例说明 

比如在/arch/arm/mach-s5pv210/mach-smdkv210.c文件中,有代码如下:

MACHINE_START(SMDKV210, "SMDKV210")
	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
	.phys_io	= S3C_PA_UART & 0xfff00000,
	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
	.boot_params	= S5P_PA_SDRAM + 0x100,
	.init_irq	= s5pv210_init_irq,
	.map_io		= smdkv210_map_io,
	.init_machine	= smdkv210_machine_init,
#ifdef CONFIG_S5P_HIGH_RES_TIMERS
	.timer		= &s5p_systimer,
#else
	.timer		= &s3c24xx_timer,
#endif
MACHINE_END

这段代码其实等价于下面这段代码:

static const struct machine_desc __mach_desc_SMDKV210	\
 __used							\
 __attribute__((__section__(".arch.info.init"))) = {	\
	.nr		        = MACH_TYPE_SMDKV210,\//机器码2456		
	.name		    = "SMDKV210",
//MACHINE_START(SMDKV210, "SMDKV210")展开后是上面这部分(没有“}”这个符号)

    .phys_io	    = S3C_PA_UART & 0xfff00000,
	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
	.boot_params	= S5P_PA_SDRAM + 0x100,
	.init_irq	    = s5pv210_init_irq,
	.map_io		    = smdkv210_map_io,
	.init_machine	= smdkv210_machine_init,
	.timer		    = &s5p_systimer,
};

即这段代码定义了一个 struct machine_desc 类型的变量__mach_desc_SMDKV210,它是SMDKV210这个开发板的软件抽象。

(1).nr=MACH_TYPE_SMDKV210

这个表示这个开发板的机器码是MACH_TYPE_SMDKV210。

机器码值“MACH_TYPE_SMDKV210”在/include/generated/mach-types.h文件中定义。

该文件在内核配置过程中自动生成,维护着该版本内核所支持的全部机器码。

(2).name= "SMDKV210"

这个表示这个开发板的名字叫“SMDKV210”。

(3).init_machine = smdkv210_machine_init

表示这个开发板的硬件初始化函数是 smdkv210_machine_init。

该函数包含了内核中各种硬件的初始化操作。

2.2 为 X210 选择 mach-yyy.c 文件 

我们的目标开发板叫做X210,采用s5pv210这款CPU,按理应该对应着/arch/arm/mach-s5pv210/mach-x210.c文件。

但是在三星版本内核的/arch/arm/mach-s5pv210/中,找不到X210开发板对应的mach-x210.c文件。

为了减少移植工作量,我们在三星版本内核的/arch/arm/mach-s5pv210/中,寻找一个mach-yyy.c文件,使得该文件对应的开发板与X210开发板最为接近(都使用相同的CPU),并以此文件为基础进行移植。

九鼎的X210开发板是根据三星SMDKV210开发板进行设计的,因此要寻找SMDKV210开发板对应的文件,按理应该是三星版本内核的/arch/arm/mach-s5pv210/mach-smdkv210.c文件。

但是分析三星版本内核源码/arch/arm/mach-s5pv210/Makefile文件后得知,CONFIG_MACH_SMDKV210这个宏(在内核配置阶段生成的./config文件中)实际绑定的是/arch/arm/mach-s5pv210/mach-smdkc110.c这个文件,而非mach-smdkv210.c文件。

因此后续将以/arch/arm/mach-s5pv210/mach-smdkc110.c这个文件为基础进行移植。

 

2.3 分析mach-smdkc110.c文件 

在该文件的最后有以下代码:

#ifdef CONFIG_MACH_SMDKC110
MACHINE_START(SMDKC110, "SMDKC110")
#elif CONFIG_MACH_SMDKV210  //选择这个
MACHINE_START(SMDKV210, "SMDKV210")
#endif
	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
	.phys_io	= S3C_PA_UART & 0xfff00000,
	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
	.boot_params	= S5P_PA_SDRAM + 0x100,
	.init_irq	= s5pv210_init_irq,
	.map_io		= smdkc110_map_io,
	.init_machine	= smdkc110_machine_init,
	.timer		= &s5p_systimer,
MACHINE_END

它展开后内容如下:

static const struct machine_desc __mach_desc_SMDKV210	\
 __used							\
 __attribute__((__section__(".arch.info.init"))) = {	\
	.nr		= MACH_TYPE_SMDKV210,\//机器码2456		
	.name		= "SMDKV210",
	.phys_io	= S3C_PA_UART & 0xfff00000,
	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
	.boot_params	= S5P_PA_SDRAM + 0x100,
	.init_irq	= s5pv210_init_irq,
	.map_io		= smdkv210_map_io,
	.init_machine	= smdkv210_machine_init,//初始化各种硬件
	.timer		= &s5p_systimer,
};

其中,init_machine这个函数指针,指向一个机器硬件初始化函数smdkv210_machine_init。

这个函数绑定了内核启动过程中会初始化的各种硬件的信息,在此函数中添加的硬件才会被初始化,没有在此函数中添加的硬件不会被初始化。

关于smdkv210_machine_init的更多介绍,见驱动栏目中的“Linux设备驱动模型”的内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1532017.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PowerShell 一键更改远程桌面端口

前言 提高工作效率,安全性和规范化,最终实现一键更改Windows 远程桌面端口 前提条件 开启wmi,配置网卡,参考 一键更改远程桌面端口自动化脚本 默认端口3389变更后的端口3390win+r mstsc YOU_ip常规更改的连接方式win+r mstsc YOU_ip:3390需要恢复到原来的端口3390更改成3…

wireshark抓tcp包使用指南

本博文源于笔者不断探索加上去网络总结获得的经验&#xff0c;撰写wireshark如何抓tcp包 文章目录 1、打开wireshark2、选择网络源3、搜索ip地址与tcp条件4、看灰色的条纹 1、打开wireshark 2、选择网络源 选择自己当前的ip地址适用于的网络源&#xff0c;比如这里选择“以太…

.net使用excel的cells对象没有value方法——学习.net的Excel工作表问题

$exception {"Public member Value on type Range not found."} System.MissingMemberException 代码准备运行问题解决1. 下载别的版本的.net框架2. 安装3. 运行 代码 Imports Excel Microsoft.office.Interop.Excel Public Class Form1Private Sub Button1_Click(…

CTF题型 匿名函数考法例题总结

CTF题型 匿名函数考法&例题总结 文章目录 CTF题型 匿名函数考法&例题总结一 .原理分析二 .重点匿名函数利用1.create_function()如何实现create_function代码注入 2.array_map()3.call_user_func()4.call_user_func_array()5.array_filter() 三.例题讲解1.[Polar 靶场 …

netty基础_12.用 Netty 自己实现简单的RPC

用 Netty 自己实现简单的RPC RPC 基本介绍我们的RPC 调用流程图己实现 Dubbo RPC&#xff08;基于 Netty&#xff09;需求说明设计说明代码封装的RPCNettyServerNettyServerHandlerNettyClientHandlerNettyClient 接口服务端(provider)HelloServiceImplServerBootstrap 客户端(…

Spring Web MVC入门(5)

响应 在我们前面的代码例子中, 都已经设置了响应数据Http响应结果可以是数据, 也可以是静态页面, 也可以针对响应设置状态码, Header信息等. 返回静态页面 创建前端页面index.html(注意路径) html代码如下: <!DOCTYPE html> <html lang"en"> <hea…

算法沉淀——贪心算法四(leetcode真题剖析)

算法沉淀——贪心算法四 01.最长回文串02.增减字符串匹配03.分发饼干04.最优除法 01.最长回文串 题目链接&#xff1a;https://leetcode.cn/problems/longest-palindrome/ 给定一个包含大写字母和小写字母的字符串 s &#xff0c;返回 通过这些字母构造成的 最长的回文串 。 …

初始Java篇(JavaSE基础语法)(2)

个人主页&#xff08;找往期文章包括但不限于本期文章中不懂的知识点&#xff09;&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 目录 逻辑控制 顺序结构 分支结构 if语句 switch 语句 循环结构 while 循环 for 循环 do while 循环 输入输出 输出到控制台 从键盘输入 …

C++ UML类图

参考文章&#xff1a; &#xff08;1&#xff09;C UML类图详解 &#xff08;2&#xff09;C基础——用C实例理解UML类图 &#xff08;3&#xff09;C设计模式——UML类图 &#xff08;4&#xff09;[UML] 类图介绍 —— 程序员&#xff08;灵魂画手&#xff09;必备画图技能之…

npm出现内部错误,重新设置镜像

问题&#xff1a; 报错解释&#xff1a; 这个错误表明你尝试从一个指定的npm镜像源的响应时失败了。可能的原因包括网络问题、镜像源不可用、DNS解析问题或者镜像源的确已经下线或更改。 1.重新设置镜像源 设置淘宝镜像源&#xff1a; npm config set registry https://re…

⾃定义类型:联合和枚举

1.联合体 1.1 联合体类型的声明 像结构体⼀样&#xff0c;联合体也是由⼀个或者多个成员构成&#xff0c;这些成员可以不同的类型。 但是编译器只为最⼤的成员分配⾜够的内存空间。联合体的特点是所有成员共⽤同⼀块内存空间。所以联合体也叫&#xff1a;共⽤体。 给联合体…

安装MySQL5.7.19 + 解决数据库乱码

文章目录 1.删除mysql服务 sc delete mysql2.解压到D:\mysql5.7下3.配置管理员环境变量4.D:\mysql5.7\mysql-5.7.19-winx64下创建my.ini1.创建文件2.文件内容 5.管理员打开cmd&#xff0c;切换到 D:\mysql5.7\mysql-5.7.19-winx64\bin6.输入 mysqld -install 安装mysql服务7.初…

腾讯云服务器怎么买省钱?先领券,再下单!

腾讯云代金券领取渠道有哪些&#xff1f;腾讯云官网可以领取、官方媒体账号可以领取代金券、完成任务可以领取代金券&#xff0c;大家也可以在腾讯云百科蹲守代金券&#xff0c;因为腾讯云代金券领取渠道比较分散&#xff0c;腾讯云百科txybk.com专注汇总优惠代金券领取页面&am…

2024年腾讯云服务器优惠券领取入口和代金券使用教程(收藏)

腾讯云代金券领取渠道有哪些&#xff1f;腾讯云官网可以领取、官方媒体账号可以领取代金券、完成任务可以领取代金券&#xff0c;大家也可以在腾讯云百科蹲守代金券&#xff0c;因为腾讯云代金券领取渠道比较分散&#xff0c;腾讯云百科txybk.com专注汇总优惠代金券领取页面&am…

C语言经典算法-6

文章目录 其他经典例题跳转链接31.数字拆解32.得分排行33.选择、插入、气泡排序34.Shell 排序法 - 改良的插入排序35.Shaker 排序法 - 改良的气泡排序 其他经典例题跳转链接 C语言经典算法-1 1.汉若塔 2. 费式数列 3. 巴斯卡三角形 4. 三色棋 5. 老鼠走迷官&#xff08;一&…

10分钟带你了解分布式系统的补偿机制

我们知道&#xff0c;应用系统在分布式的情况下&#xff0c;在通信时会有着一个显著的问题&#xff0c;即一个业务流程往往需要组合一组服务&#xff0c;且单单一次通信可能会经过 DNS 服务&#xff0c;网卡、交换机、路由器、负载均衡等设备&#xff0c;而这些服务于设备都不一…

浏览量这么低,还要不要继续坚持?

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 曾经在一个群里聊天&#xff0c;有群友看到我两位数的浏览量&#xff0c;说到&#xff1a;浏览量这么低还坚持什么&#xff1f; 浏览量低是事实&#xff0c;大多数是十几二十的&#xff0c;上百的都是少数&#xff0c…

Day62:WEB攻防-PHP反序列化CLI框架类PHPGGC生成器TPYiiLaravel等利用

目录 反序列化链项目-PHPGGC&NotSoSecure NotSoSecure(综合类) PHPGGC(单项类) 反序列化框架利用-ThinkPHP&Yii&Laravel [安洵杯 2019]iamthinking Thinkphp V6.0.X 反序列化 CTFSHOW 反序列化 267 Yii2反序列化 CTFSHOW 反序列化 271 Laravel反序列化 知识…

JVM学习-类加载

目录 1.类文件结构 2.类加载器 3.类加载的三个阶段 3.1加载 3.2链接 3.2.1验证 3.2.2准备阶段 3.2.3解析阶段 3.3初始化 4.拓展&#xff1a;反射 4.1获取类对象 4.2创建实例 4.3获取方法 4.4方法调用 1.类文件结构 2.类加载器 类加载器用来将类文件的二进制字节码加载到JV…

咨询交流论坛|基于JSP+ Mysql+Java+ B/S结构的东理咨询交流论坛设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java&#xff0c;ssm&#xff0c;springboot的平台设计与实现项目系统开发资源&#xff08;可…