linux arm32 mmu 启动代码分析(汇编部分)

linux arm32启动代码分析

首先将 linux kernel 代码编译好以后,在目录 arch/arm/kernel 下生成链接脚本文件 vmlinux.lds (vmlinux.lds由vmlinux.lds.S编译而来)。首先分析此脚本来熟悉 linux kernel 二进制代码分布结构。

vmlinux.lds.S

ENTRY(stext)

指明了linux内核入口,入口为stext。符号stext定义在 arch/arm/kernel/head.S 文件中:

	.arm

	__HEAD
ENTRY(stext)
 ARM_BE8(setend	be )			@ ensure we are in BE8 mode

 THUMB(	adr	r9, BSYM(1f)	)	@ Kernel is always entered in ARM.
 THUMB(	bx	r9		)	@ If this is a Thumb-2 kernel,
 THUMB(	.thumb			)	@ switch to Thumb now.
 THUMB(1:			)

ENTRY在 include/linux/linkage.h 中定义

#ifndef ENTRY
#define ENTRY(name) \
	.globl name ASM_NL \
	ALIGN ASM_NL \
	name:
#endif

通过代码可以看到 ENTRY 宏只是对全局符号的导出起到包装作用,
下面分析ENTRY语句下的五条指令

1、ARM_BE8(setend be )
ARM_BE8在 arch/arm/include/asm/assembler.h 中定义

/* Select code for any configuration running in BE8 mode */
#ifdef CONFIG_CPU_ENDIAN_BE8
#define ARM_BE8(code...) code
#else
#define ARM_BE8(code...)
#endif

如果开启 CONFIG_CPU_ENDIAN_BE8 选项,code(setend be)则会被原封不动编译到内核中,如果没有开启此选项,code(setend be)就不会被编译到内核中。

(extension) #define后的省略号的意义如下(以PDEBUG为例):

#define PDEBUG(fmt, args...) printk( KERN_DEBUG "scull: " fmt, ## args)
// example
PDEBUG("a=%d, b=%d", a, b);
// 展开后
printk( KERN_DEBUG "scull: " "a=%d, b=%d", a, b);

(1)arm BE8 mode 是什么
根据博客 https://blog.richliu.com/2010/04/08/907/arm11-be8-and-be32 所述:
BE8 和 BE32 是字节序相关的概念,举例:
假设需要将 0x11223344 存入内存中:
little endian:

memory address 0 1 2 3
data 0x44 0x33 0x22 0x11

big endian:

memory address 0 1 2 3
data 0x11 0x22 0x33 0x44

现假设对0x11223344内存存储分布如下:

memory address 0 1 2 3
data 0x11 0x22 0x33 0x44

在BE32 mode下:

LDR r0, [0]
# r0 = 0x44332211
LDRB r0, [0]
# r0 = 0x00000044
LDRB r0, [3]
# r0 = 0x00000011

在BE8 mode下:

LDR r0, [0]
# r0 = 0x11223344
LDRB r0, [0]
# r0 = 0x00000011
LDRB r0, [3]
# r0 = 0x00000044

关于 byte invariant endianness 的概念可以参照博客 https://blog.csdn.net/moreaction/article/details/5280067/
(2)setend be 指令的含义
setend 指令选择数据访问的字节序,在百度文库 https://wenku.baidu.com/view/6f83c4c2951ea76e58fafab069dc5022aaea46e5.html 解释了这个指令。在linux内核代码中,如果开启了 CONFIG_CPU_ENDIAN_BE8 选项,则 setend be 指令会被编译到内核中并执行,此指令的执行代表选择数据访问的字节序为 BE8 模式,BE8 模式的数据访问效果如上文所述。

2、THUMB( adr r9, BSYM(1f) )
3、THUMB( bx r9 )
4、THUMB( .thumb )
5、THUMB(1: )
2\3\4\5 中,THUMB、BSYM都定义在 arch/arm/include/asm/unified.h 中:

#ifdef CONFIG_THUMB2_KERNEL

#if __GNUC__ < 4
#error Thumb-2 kernel requires gcc >= 4
#endif

/* The CPSR bit describing the instruction set (Thumb) */
#define PSR_ISETSTATE	PSR_T_BIT

#define ARM(x...)
#define THUMB(x...)	x
#ifdef __ASSEMBLY__
#define W(instr)	instr.w
#define BSYM(sym)	sym + 1
#else
#define WASM(instr)	#instr ".w"
#endif

#else	/* !CONFIG_THUMB2_KERNEL */

/* The CPSR bit describing the instruction set (ARM) */
#define PSR_ISETSTATE	0

#define ARM(x...)	x
#define THUMB(x...)
#ifdef __ASSEMBLY__
#define W(instr)	instr
#define BSYM(sym)	sym
#else
#define WASM(instr)	#instr
#endif

#endif	/* CONFIG_THUMB2_KERNEL */
  • 34
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值