Linux内核源代码分析——Linux内核的入口

来源:互联网 发布:seo资源网 编辑:程序博客网 时间:2024/04/30 18:43

Jack:hi,淫龙,在Linux内核的源代码里,有几段汇编代码,那几段代码是负责Linux内核引导的。

我:是的。早期的Linux内核引导代码只有bootsect.s、setup.s、head.s这3个文件,这三个文件都是Linus在1991年左右亲手写的。后来的代码虽然进行了加固,但是原型还是这几个。

Jack:我想弄清楚。这几个汇编代码做了些什么事情。

我:我不能在对话中一句代码一句代码地给你进行注释,这是不现实的。我希望能把你最困惑的知识点解释清楚,起到画龙点睛的作用,而不是手把手地教你它是什么。

Jack:那我提一个最困惑的问题吧。Linux的内核是如何开始执行main()函数的?(在1.0之后?的代码中,所有的Linux入口函数已经改名为start_kernel())。

我:我给你看一段head.s的代码吧。

head.s line 135-141

 

after_page_tables:pushl $0# These are the parameters to main :-)pushl $0pushl $0pushl $L6# return address for main, if it decides to.pushl $_main            # 把main函数的地址压入栈内,等待出栈,指令跳转jmp setup_paging        # 跳转到setup_paging标签

 

head.s line 210-218

 

1:stosl/* fill pages backwards - more efficient :-) */subl $0x1000,%eaxjge 1bxorl %eax,%eax/* pg_dir is at 0x0000 */movl %eax,%cr3/* cr3 - page directory start */movl %cr0,%eaxorl $0x80000000,%eaxmovl %eax,%cr0/* set paging (PG) bit */ret/* this also flushes prefetch-queue */#弹栈,调用_main

关键就在这里:入栈函数地址,ret返回顺便调用_main。

 

Jack:明白了。原来是这样。我再问一个问题。Linux的内核的入口函数为什么可以是start_kernel()——C语言的入口地址不是main()吗?

我:这个问题你可以尝试从汇编的角度来思考。C语言的入口地址不是main()吗?——这个是不一定的。仅仅从C语言的角度来思考,这话是对的。如果从汇编的角度来思考,这话就不对了。

Jack:从汇编的角度来思考C语言?我操。

我:你用gcc -S选项编译一个source file,会生成一个汇编源代码文件。之后才会生成二进制文件。C只是一层皮,真正的骨在于汇编。

Jack:你的意思是,C其实是需要翻译成汇编的,从汇编的层面来思考代码才能把握本质的东西。

我:great。你明白了。

0 0
原创粉丝点击