/*
* The C runtime environment should now be setup sufficiently.
* Set up some pointers, and start decompressing.
* r4 = kernel execution address
* r7 = architecture ID
* r8 = atags pointer
*/
mov r0, r4
mov r1, sp @ malloc space above stack
add r2, sp, #0x10000 @ 64k max
mov r3, r7
bl decompress_kernel
bl cache_clean_flush
bl cache_off
b __enter_kernel
这里补充一下,栈生长方向是向下的,也就是向地址减小的方向。
堆的生长方向是向上的,也就是向地址增加的方向。
注意这里用的是A模式,而不是我们熟悉的B
现在可以知道如下信息
r0: 解压后的内核的地址,也是执行的地址
r1: 栈顶,也是堆的顶,两者背向生长
r2: 堆底
r3: 架构ID
看decompress_kernel
arch/arm/boot/compressed/misc.c
void
decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
unsigned long free_mem_ptr_end_p,
int arch_id)
{
int ret;
output_data = (unsigned char *)output_start;
free_mem_ptr = free_mem_ptr_p;
free_mem_end_ptr = free_mem_ptr_end_p;
__machine_arch_type = arch_id;
arch_decomp_setup();
putstr("Uncompressing Linux...");
ret = do_decompress(input_data, input_data_end - input_data,
output_data, error);
if (ret)
error("decompressor returned an error");
else
putstr(" done, booting the kernel.\n");
}
我手里的rv1126用的是LZ4,具体的解压代码不去分析,分析了我也看不懂。。。
不过我尝试追了一下,因为rv1126有个DECOM模块,支持解压
但是实际上,rockchip的sdk并没有使用这个DECOM模块,让人失望....
最后开始执行内核代码
__enter_kernel:
mov r0, #0 @ must be 0
mov r1, r7 @ restore architecture number
/* 注意这里的r8值有可能是dtb的地址 */
mov r2, r8 @ restore atags pointer
ARM( mov pc, r4 ) @ call kernel