一起分析Linux系统设计思想——03内核启动流程分析(四)

在学习资料满天飞的大环境下,知识变得非常零散,体系化的知识并不多,这就导致很多人每天都努力学习到感动自己,最终却收效甚微,甚至放弃学习。我的使命就是过滤掉大量的垃圾信息,将知识体系化,以短平快的方式直达问题本质,把大家从大海捞针的痛苦中解脱出来。


由于内核启动流程(二)和(三)的铺垫,本篇的代码分析起来就轻松多了,随着对Linux学习的深入,必然会融会贯通。所以,掌握Linux背后的逻辑和思想,然后举一反三才是我们最需要锻炼的能力。

5 __lookup_machine_type剖析(接上篇)

__lookup_machine_type函数和__lookup_processor_type函数设计和实现的思路是一样的,在之前的文章中已经深入分析过,在这里不做重复性工作了。仅对代码作出注释。

/*
 * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
 * more information about the __proc_info and __arch_info structures.
 */
	.long	__proc_info_begin
	.long	__proc_info_end
3:	.long	.
	.long	__arch_info_begin
	.long	__arch_info_end

/*
 * Lookup machine architecture in the linker-build list of architectures.
 * Note that we can't use the absolute addresses for the __arch_info
 * lists since we aren't running with the MMU on (and therefore, we are
 * not in the correct address space).  We have to calculate the offset.
 *
 *  r1 = machine architecture number
 * Returns:
 *  r3, r4, r6 corrupted
 *  r5 = mach_info pointer in physical address space
 */
	.type	__lookup_machine_type, %function
__lookup_machine_type:
	adr	r3, 3b             @ adr伪指令将标号3的物理地址(实际存在的地址)赋值给r3寄存器
	ldmia	r3, {r4, r5, r6} @ ldmia多寄存器寻址指令等价于: r4 <- [r3] = "."(.代表该行代码的虚拟地址)
	                        @ r5 <- [r3+4] = __arch_info_begin(虚拟地址), r6 <- [r3+4*2]
	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,寄存器相对寻址,MACHINFO_TYPE为type在结构体arch_info中的偏移
	teq	r3, r1				@ matches loader number? 判断r3中的值是否与r1中的值相等
	beq	2f				@ found 如果相等就跳转到标号2处,此时r5指向的就是匹配的arch_info结构体
	add	r5, r5, #SIZEOF_MACHINE_DESC	@ next machine_desc 否则,r5指针向前跳一个arch_info结构体的大小
	cmp	r5, r6              @ 检查r5此时是否已经指向__arch_info_end处
	blo	1b                  @ r5 小于 r6时跳转到标号1处
	mov	r5, #0				@ unknown machine 否则给r5清零,并退出循环
2:	mov	pc, lr               @ 函数返回

6 lookup_machine_type剖析

lookup_machine_type函数和lookup_processor_type函数设计和实现的思路是一样的,在之前的文章中已经深入分析过,在这里不做重复性工作了。仅对代码作出注释。

/*
 * This provides a C-API version of the above function.
 */
ENTRY(lookup_machine_type)
	stmfd	sp!, {r4 - r6, lr}    @ 压栈,保护现场
	mov	r1, r0                   @ 将入参(r0)赋值给r1
	bl	__lookup_machine_type  @ 调用汇编函数
	mov	r0, r5                   @ 将结果(r5)赋值给返回值(r0)
	ldmfd	sp!, {r4 - r6, pc}    @ 弹栈,恢复现场,并进行函数返回

<完>

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

穿越临界点

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值