nswcfd
发表于 2016-03-31 15:00
回复 7# _nosay
不好意思,5楼的解释是错误的
nswcfd
发表于 2016-03-31 15:02
08048423 <r_here>:
8048423: a1 23 84 04 08 mov 0x8048423,%eax
不是由于链接的原因,打印的确实是mov指令的二进制码
nswcfd
发表于 2016-03-31 15:54
不过,有一个问题还是不太清楚,
“movl $0xA5A5A5A5, trampoline_data - r_base”,0xA5A5A5A5是存到什么位置去了?
nswcfd
发表于 2016-03-31 16:14
本帖最后由 nswcfd 于 2016-03-31 17:07 编辑
按照as里对减法的定义,结果是个绝对地址(not relocatable)
`-'
"Subtraction".If the right argument is absolute, the result
has the section of the left argument.If both arguments are
in the same section, the result is absolute.You may not
subtract arguments from different sections.
感觉这个表达式(trampoline_data - r_base )应该是个负数(在16bit下就是比较靠近0xFFFF的地方)或者是0?
当然另外一种看法是吧rbase看作一个偏移,那结果就是在trapoline_data附近的一个地址,不过感觉不像是这样。
asm("head: nop; nop; end = .; nop; nop; mov $(end-2), %rax; mov $(end-head), %rax");
其中的end-2是相对地址,而end-head是绝对地址。
nswcfd
发表于 2016-03-31 16:37
根据https://www.linux.com/learn/docs/ldp/605-linux-i386-boot-code-howto&layout=standard&show_faces=false&width=450&action=like&font&colorscheme=light&height=35%22#trampoline的描述,目的是应该像达到如下效果。
// write marker for master knows we're running
trampoline_base = 0xA5A5A5A5;
_nosay
发表于 2016-03-31 17:07
回复 13# nswcfd
我在fun1()里面加了一句“movl r_here - r_base, %%edx\n\t ”,反汇编得到“mov 0x0, %edx”。
nswcfd
发表于 2016-03-31 17:17
回复 14# nswcfd
好吧,前面的注释写的很清楚,必须是绝对地址。
* On entry to trampoline_data, the processor is in real mode
* with 16-bit addressing and 16-bit data.CS has some value
* and IP is zero.Thus, data addresses need to be absolute
* (no relocation) and are taken with regard to r_base.
*
* If you work on this file, check the object module with
* objdump --reloc to make sure there are no relocation
* entries。
_nosay
发表于 2016-03-31 17:52
回复 17# nswcfd
嗯,就是说相对于该段代码开始处的0位置,就要用真实的0地址,但我不理解的是,为什么要用绝对地址?
我理了一下启动流程是这样的:
BIOS(硬件检测 & bootstartroutine)→ bootsect.S(0x7c00->0x90000,加载setup、zImage)→ setup.S(0x90200,为进入保护模式做好准备工作) → trampoline.S(切换到段保护模式)→ bzImage(头部为heas.S)
要理解trampoline.S,好像要对前后的代码都要比较理解才行,还可能包括BIOS里面做的事。
_nosay
发表于 2016-03-31 18:10
本帖最后由 _nosay 于 2016-03-31 18:19 编辑
回复 17# nswcfd
BP是直接执行的这段代码,AP是把这段代码拷贝到另外一个地方再执行的。
跟启动相关的一些链接:
http://tldp.org/LDP/lki/lki-1.html#ss1.1
http://www.intel.com
http://wenku.baidu.com/link?url=1gTYztR5BzxIb8L4eUv9aEUtLudtcrCaX2VwpfJlOgDfUrHsq2Sbfg5krDYOW30pAHQ3NW70PbHDxVOOHaxh-hdB8F3AoZLHVfVaERBIV7a
http://blog.sina.com.cn/s/blog_54f82cc2010121ur.html
http://www.360doc.com/content/13/0129/15/7982302_263057911.shtml
http://emuch.net/fanwen/436/59088.html
http://www.embeddedlinux.org.cn/html/yingjianqudong/201112/31-1911.html
还有个很好奇的问题:bootsect为什么先被加载到0x7C00处,然后又自己把自己移到0x90000 ?
nswcfd
发表于 2016-03-31 19:07
因为还是real mode,所以寻址方式是ds: offset(注:ds的值同cs)。
那么答案是,0xA5A5A5A5被拷贝到了cs: 0。
接下来的问题是,AP的CS是怎么被初始化的? 貌似跟startup IPI有关系?