快乐虾
http://blog.csdn.net/lights_joy/
本文适用于
ADI bf561 DSP
uclinux-2008r1.5-rc3 (移植到vdsp5)
Visual DSP++ 5.0(update 5)
欢迎转载,但请保留作者信息
linux-2.6.x\arch\blackfin\mach-bf561\head.S是uclinux的入口点,uclinux的第一条语句就是从__start这个入口开始执行的,本文分析的就是head.s这个文件。
/* R0: argument of command line string, passed from uboot, save it */
R7 = R0;
这一行看起来很简单,实际上涉及到很多内容。
首先要知道的是R0保存的是什么东西。由于uclinux是由u-boot这类的bootloader进行引导的,这类程序通常需要将内核解压缩到一个指定的地址,然后通过一个函数调用将控制权交给内核,通常还要传递一个”console=/dev/ttyBF0”之类的字符串给内核,R0就保存了这个字符串的头指针,因此这行代码先把这个指针保存起来。
下面的代码来自于u-boot-1.1.6-2008R1.5\lib_blackfin\boot.c,从中可以看出这个参数的传递过程:
void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
ulong addr, ulong *len_ptr, int verify)
{
int (*appl) (char *cmdline);
char *cmdline;
#ifdef SHARED_RESOURCES
swap_to(FLASH);
#endif
appl = (int (*)(char *))ntohl(header.ih_ep);
printf("Starting Kernel at = %x\n", appl);
cmdline = make_command_line();
if (icache_status())
icache_disable();
if (dcache_status())
dcache_disable();
(*appl) (cmdline);
}
全局变量header中存放了压缩的uClinux映象文件的信息(参见《用u-boot引导uclinux》一文),ip_ep这个成员存放的就是uClinux解压后的入口点的地址,所以在此直接将它赋给appl作为函数指针。而cmdline这个变量存放的就是要传递给uClinux的参数,它是一个字符串。
关键的调用是由(*appl)(cmdline);来完成的,看看它的汇编代码:
R0 = [FP – 4];
P1 = [FP – 8];
CALL(P1);
[FP-4]存放的就是cmdline这个局部变量的值,而[FP-8]存放的则是app1这个局部变量的值。也就是说,编译器是将要传递的字符串参数指针放在R0中的。
在保存了这个指针之后,uclinux在下面还要将这个指针指向的内容复制到uclinux自己的数据段中。