日期:2014-05-16  浏览次数:20720 次

run_init_process 挂死,请教大侠!!
在移植Linux   2.6.17的内核到PNX8950(MIPS架构)上,出现Init程序挂死。  
文件系统采用CPIO格式,由BusyBox   1.2.1得到,编译到内核中。  
交叉工具链由Buildroot构建,采用uClib库。  

单板启动到“Freeing   unused   kernel   memory:   972k   freed”后,挂死;  

跟踪Linux   2.6.17的内核启动代码:  

static   int   init(void   *   unused)  
{  
。。。。。。  

if   (sys_open((const   char   __user   *)   "/dev/console ",   O_RDWR,   0)   <   0)   <------运行正常  
printk(KERN_WARNING   "Warning:   unable   to   open   an   initial   console.\n ");  

。。。。。。  

if   (execute_command)   {  
run_init_process(execute_command);   <--------挂死位置,   execute_command值“/init ",   在BusyBox做文件系统时,init已链接到/sbin/init;  
printk(KERN_WARNING   "Failed   to   execute   %s.   Attempting   "  
"defaults...\n ",   execute_command);  
}  

run_init_process( "/sbin/init ");  
run_init_process( "/etc/init ");  
run_init_process( "/bin/init ");  
run_init_process( "/bin/sh ");  

panic( "No   init   found.   Try   passing   init=   option   to   kernel. ");  
}  

经过定位,调用关系如下:  

run_init_process-> execve-> sys_execve-> do_execve-> search_binary_handler-> load_elf_binary  

在   load_elf_binary挂掉,仔细分析过程,发现load_elf_binary函数的padzero时挂死,加上调试代码,代码片断如下:  
static   int   load_elf_binary(struct   linux_binprm   *   bprm,   struct   pt_regs   *   regs)  
{  

。。。。。。  
loc-> elf_ex.e_entry   +=   load_bias;  
elf_bss   +=   load_bias;  
elf_brk   +=   load_bias;  
start_code   +=   load_bias;  
end_code   +=   load_bias;  
start_data   +=   load_bias;  
end_data   +=   load_bias;  

printk(KERN_WARNING   "loc-> elf_ex.e_entry   :0x%8x\n ",   loc-> elf_ex.e_entry);  
printk(KERN_WARNING   "load_bias:   0x%8x\n ",   load_bias);  
printk(KERN_WARNING   "elf_bss:   0x%8x\n ",   elf_bss);  
printk(KERN_WARNING   "elf_brk:   0x%8x\n ",   elf_brk);  
printk(KERN_WARNING   "start_code:   0x%8x\n ",   start_code);  
printk(KERN_WARNING   "end_code:   0x%8x\n ",   end_code);  
printk(KERN_WARNING   "start_data:   0x%8x\n ",   start_data);  
printk(KERN_WARNING   "end_data:   0x%8x\n ",   end_data);  

/*   Calling   set_brk   effectively   mmaps   the   pages   that   we   need  
*   for   the   bss   and   break   sections.   We   must   do   this   before  
*   mapping   in   the   interpreter,   to   make   sure   it   doesn 't   wind  
*   up   getting   placed   where   the   bss   needs   to   go.  
*/  
retval   =