内核分析2(setup_arch)

本文详细探讨了Linux内核中的`setup_arch`函数,该函数主要负责确定内核机器码并获取CPU信息。内容包括:1.介绍`setup_arch`的功能;2.解析`machine_desc`结构;3.阐述`setup_processor()`的作用;4.讲解`mdesc = setup_machine(machine_arch_type)`的过程;5.解释`lookup_machine_type(nr)`如何查找对应机器码的结构体。
摘要由CSDN通过智能技术生成

1.函数的作用

确定当前内核的机器码,然后确定当前内核所用的CPU

2.machine_desc

机器码的描述符。里面包含了机器平台的相关信息。

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	*/
	//uboot所传的参数
	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);
};

3.setup_processor()

static void __init setup_processor(void)
{
	//CPU信息的链表
	struct proc_info_list *list;

	/*
	 * locate processor in the list of supported processor
	 * types.  The linker builds this table for us from the
	 * entries in arch/arm/mm/proc-*.S
	 */
	 //查找CPU的类型,read_cpuid_id()是通过协处理器查找CPU的id号
	list = lookup_processor_type(read_cpuid_id());
	if (!list) {
		printk("CPU configuration botched (ID %08x), unable "
		       "to continue.\n", read_cpuid_id());
		while (1);
	}

	cpu_name = list->cpu_name;

#ifdef MULTI_CPU
	processor = *list->proc;
#endif
#ifdef MULTI_TLB
	cpu_tlb = *list->tlb;
#endif
#ifdef MULTI_USER
	cpu_user = *list->user;
#endif
#ifdef MULTI_CACHE
	cpu_cache = *list->cache;
#endif

	printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n",
	       cpu_name, read_cpuid_id(), read_cpuid_id() & 15,
	       proc_arch[cpu_architecture()], cr_alignment);

	sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS);
	sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
	elf_hwcap = list->elf_hwcap;
#ifndef CONFIG_ARM_THUMB
	elf_hwcap &= ~HWCAP_THUMB;
#endif

	cacheid_init();
	cpu_proc_init();
}

4.mdesc = setup_machine(machine_arch_type);

含义:通过machine_arch_type来查找正确机器码描述符,得到正确的CPU信息

查找machine_arch_type的定义命令:grep “machine_arch_type” * -nR
定义machine_arch_type的文件: generated/mach-types.h

5.lookup_machine_type(nr)

含义:通过所传CPU的机器码到内核段中寻找相对应的机器码结构体描述符。

machine_arch_type
	__lookup_machine_type
	.align	2
3:	.long	__proc_info_begin
	.long	__proc_info_end
4:	.long	.
	.long	__arch_info_begin
	.long	__arch_info_end

__lookup_machine_type:
	adr	r3, 4b
	ldmia	r3, {r4, r5, r6}
	sub	r3, r3, r4			@ get offset between virt&phys
	add	r5, r5, r3			@ convert virt addresses to
	add	r6, r6, r3			@ physical address space
1:	ldr	r3, [r5, #MACHINFO_TYPE]	@ get machine type
	teq	r3, r1				@ matches loader number?
	beq	2f				@ found
	add	r5, r5, #SIZEOF_MACHINE_DESC	@ next machine_desc
	cmp	r5, r6
	blo	1b
	mov	r5, #0				@ unknown machine
2:	mov	pc, lr
ENDPROC(__lookup_machine_type)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值