分析mips架构linux启动流程(一)

mips架构内核启动时默认从BFC00000地址开始取指运行,也就是对应KSEG1,物理地址的1fc00000开始运行。

在文件arch/mips/kernel/vmlinux.lds中指定了第一个运行的函数:
#define mips mips
OUTPUT_ARCH(mips)
ENTRY(kernel_entry)
PHDRS {
	text PT_LOAD FLAGS(7);	/* RWX */
	note PT_NOTE FLAGS(4);	/* R__ */
}

#ifdef CONFIG_32BIT
	#ifdef CONFIG_CPU_LITTLE_ENDIAN
		jiffies	 = jiffies_64;
	#else
		jiffies	 = jiffies_64 + 4;
	#endif
#else
	jiffies	 = jiffies_64;
#endif

SECTIONS
{
#ifdef CONFIG_BOOT_ELF64
	. = 0xffffffff80300000;
#endif
	. = VMLINUX_LOAD_ADDRESS;
.......


elf文件的入口地址,即bootloader移动完内核后,直接跳转到的地址,由ld写入elf的头中,其会依次使用下面的方法尝试设置入口点,遇到成功时则停止:
a.命令行选项-e entry
b.脚本中的ENTRY(symbol)
c.如果由定义的start符号,则使用start符号
d.如果存在.text的section,则使用第一个字节的地址
e.地址0

这里指定了地址位kernel_entry,那加载完内核后就跳转到这个地址。

kernel_entry定义:arch/mips/kernel/head.s

声明的入口地址的宏:

#define NESTED(symbol, framesize, rpc)			\
		.globl	symbol;				\
		.align	2;				\
		.type	symbol, @function;		\
		.ent	symbol, 0;			 \
symbol:		.frame	sp, framesize, rpc

汇编伪指令frame用来声明堆栈布局:
有三个参数:
1,第一个参数framereg:声明用于访问局部堆栈的寄存器,一般为$sp
2,第二个参数framesize:声明该函数已分配堆栈的大小,应该符合$sp+framesize=原来的$sp
3,第三个参数returnreg:这个寄存器用来保存返回地址。

对指令的一些宏定义封装:
32位架构:
#define PTR_ADD		add
#define PTR_ADDU	addu
#define PTR_ADDI	addi
#define PTR_ADDIU	addiu
#define PTR_SUB		sub
#define PTR_SUBU	subu
#define PTR_L		lw
#define PTR_S		sw
#define PTR_LA		la
#define PTR_LI		li
#define PTR_SLL		sll
#define PTR_SLLV	sllv
#define PTR_SRL		srl
#define PTR_SRLV	srlv
#define PTR_SRA		sra
#define PTR_SRAV	srav
#define	PTR_SCALESHIFT	2
#define	PTR		.word
#define	PTRSIZE		4
#define	PTRLOG		2


#define	LONG_ADD	add
#define	LONG_ADDU	
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值