IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> Linux——lookup_machine_type(nr);匹配机器 -> 正文阅读

[嵌入式]Linux——lookup_machine_type(nr);匹配机器

一. 内核中对于每种支持的开发板都会使用宏MACHINE_START、MACHINE_END来定义一个machine_desc结构,它定义开发板相关的一些属性及函数,比如机器类型ID、起始I/O物理地址、Bootloader传入的参数的地址、中断初始化函数、I/O映射函数等,
//可以看出在\arch\arm\mach-at91(mach-xx) —mach中封装好硬件对象

MACHINE_START(AT91SAM9G45EKES, "Atmel AT91SAM9G45-EKES")
	/* Maintainer: Atmel */
	.phys_io	= AT91_BASE_SYS,					//system controller
	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,		//存储空间地址偏移
	.boot_params	= AT91_SDRAM_BASE + 0x100,			//SDRAM 地址参数
	.timer		= &at91sam926x_timer,			//设置时钟
	.map_io		= ek_map_io,				//配置时钟
	.init_irq		= ek_init_irq,				//初始化中断控制器,使能gpio中断
	.init_machine	= ek_board_init,                                                        //外部硬件初始化
MACHINE_END

//\arch\arm\include\asm\mach


#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				\
};
truct 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);
};///物理设备对象

============================================

二:在内核启加载硬件程序
在main.c中
|
start_kernel(void)
|
setup_arch(&command_line);//加载硬件
|
mdesc = setup_machine(machine_arch_type);
|
list = lookup_machine_type(nr);//根据machine_arch_type从mach list中查找,

问题:lookup_machine_type如何通过machine_arch_type找到在make menuconfig 是配置的硬件???
解决:
查看连接脚本arch/arm/kernel/vmlinux.lds.S
所有machine_desc结构体都处于“.arch.info.init”段中,在连接内核时,它们被组织在一起,开始地址为__arch_info_begin,结束地址为__arch_info_end,从”中可以看出:

          38    __arch_info_begin = .;   //machine_desc结构体的开始地址

          39        *(.arch.info.init)   //所有machine_desc都在这里面

          40    __arch_info_end = .;    //machine_desc结构体的开始地址
  1. 不同的machine_desc结构用于不同的开发板,U-BOOT调用内核时,会在r1寄存器中给出开发板的标记(机器类型ID);对于S3C2410、S3C2440开发板,U-Boot传入的机器类型ID为MACH_TYPE_SMDK2410、MACH_TYPE_S3C2440,它们对应的machine_desc结构分别在arch/arm/mach-s3c2410/mach-smdk2410.c和
    arch/arm/mach-s3c2440/mach-smdk2440.c中定义
190 3:   .long .                  //当前行编译链接后的虚拟地址

191      .long  __arch_info_begin //machine_desc结构体的开始地址(虚拟地址)

192       .long __arch_info_end   //machine_desc结构体的结束地址(虚拟地址)

 

        .........................

205  __lookup_machine_type:

206       adr r3, 3b              //r3 = 190行的物理地址

207       ldmia  r3, {r4, r5, r6} //[r3]->r4,[r3+4]->r5,[r3+8]->r6

                                    r4 = 190行的虚拟地址

                                    r5 = __arch_info_begin (VA)

                                    r6 = __arch_info_end (VA)

208       sub r3, r3, r4         //r3=(190行的物理地址)-(190行的虚拟地址)

209       add r5, r5, r3         //r5= __arch_info_begin(物理地址)

210       add r6, r6, r3        //r6= __arch_info_end(物理地址)  

211 1:    ldr r3, [r5, #MACHINFO_TYPE]     //r5是machine_desc结构体地址

                          r3 = r5 + MACHINFO_TYPE=machine_desc结构中定义的nr成员,即机器类型ID

212       teq r3, r1          //r1是Bootloader调用内核时传入的机器类型ID

213       beq 2f              //相等则跳转到218行

214       add r5, r5, #SIZEOF_MACHINE_DESC    //否则跳转到下一个machine_desc结构体

215       cmp r5, r6         //是否已经比较完所有的machine_desc结构体

216       blo 1b             //没有则继续比较(lo:无符号小于)

217       mov r5, #0         //比较完毕,但没有匹配的machine_desc结构体,r5=0

218 2:    mov pc, lr         //返回

上面代码功能说明:

__lookup_machine_type函数将这个r1寄存器中的机器类型ID与machine_desc结构中的nr成员比较,如果相等则表示找到了匹配的machine_desc结构,于是返回它的地址(存于r5中),如果__arch_machine_begin和__arch_machine_end间所有machine_desc结构的nr成员都不等于r1寄存器中的值,则返回0(r5等于0)

在配置菜单时,选中两个开发板即可:

    System Type--->

        S3C2410 Machines--->

             [*] SMDK2410/A9M2410

        S3C2440 Machines--->

             [*] SMDK2440

参考:http://blog.sina.com.cn/s/blog_63ac1cef0100vco1.html

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-25 12:22:20  更:2021-08-25 12:24:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 2:02:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码