mips架构内核启动时默认从BFC00000地址开始取指运行,也就是对应KSEG1,物理地址的1fc00000开始运行。
在文件arch/mips/kernel/vmlinux.lds中指定了第一个运行的函数:
汇编伪指令frame用来声明堆栈布局:
有三个参数:
1,第一个参数framereg:声明用于访问局部堆栈的寄存器,一般为$sp
2,第二个参数framesize:声明该函数已分配堆栈的大小,应该符合$sp+framesize=原来的$sp
3,第三个参数returnreg:这个寄存器用来保存返回地址。
对指令的一些宏定义封装:
在文件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