细说 Intel Mac 安装 Windows XP

2006年03月22日 01:44 次阅读 稿源: 条评论
作者:刀枪Blue
上周六简单说了在Intel Mac上安装Windows XP的方法,只涉及如何操作,关于怎么实现并没什么多的言语,当时许诺周日写点多的,忙累加上懒,就推到现在才有--当然,你看,我还知道是男人就要守承诺哈,虽然晚了点。
按理说,narf 和 blanka 能写得更多,不过估计得胜的幸运儿正数钱数得手抽筋,所以到底还是只缺时间不缺能力的Clay来得厚道,只差一步也不影响小伙儿的心情和热心,他在自己的blog上写了Dual-booting Windows XP and Mac OS X on Intel Macs

Clay 的做法和获胜的narf 及 blanka (这二人正好可简称NB,果然NB)非常类似,都用了自己的EFI CSM driver模拟legacy BIOS,这样XP就能启动了。Clay 只是非常好奇NB二人如何搞定VGA的。

这次经历Clay看作非常好的学习机会,到来时机也是相当的~~恰当。Intel汇编和保护模式编程刚刚进入Clay的兴趣视野,这可是数年前Clay 做DOS编程时认为非常具有挑战性的内容。在他开始这个项目之前几个星期,Clay就在阅读相关的书籍和资料了,主要是汇编和保护模式。

在这场XP上Mac的竞赛中,Clay也看着NB二人的进展,随着deadline的来临和目睹NB在flickr上发表的进步情况,他也加快了编码的步伐,没花太多时间考虑优不优美,好不好维护。当然,小子还是很为自己的代码自豪,简洁是一,还完成了相当的功能,感兴趣的读者可以细读(代码其实挺漂亮)。


主函数在OSXP.c里。代码内容包括,读取Mac OS X 所用的GPT partition table;写Windows要用的MBR;从El Torito 可启动CD加载bootloader。

从保护模式切换会实模式的代码在thunk.c和asmthunk.s。Clay的首个保护模式下汇编作品,不general,不过,管用 ;-)
rmisr.s 里建立实模式中断向量表和相应的服务程序ISR,大部分其实复制了thunk代码,不过顺序是反过来的,从实模式切换到保护模式,然后切回实模式。要使用native EFI 函数(读磁盘扇区,打印字符等)模拟BIOS,这个反向thunk少不了。

pmisr.c 里是保护模式下的ISR,这是完成真正的BIOS模拟的地方,通过读写二道贩子堆栈上保存的寄存器上下文,在中断返回后和实模式代码交换情报。

完成thunk和这些ISR后,大约50%的工作完成。这些代码已经让Clay很happy了。第一次thunk进MBR代码时,程序工作得比Clay想象的要好,真的找到了激活的分区,然后从那加载并跳到了boot sector。boot到CD 的bootload也工作了--虽然挂在了诊测内存的地方。


除了享受代码工作的乐趣外,Clay还分享了一些自己调试方面的经历。在preboot环境下运行EFI程序可没那多的东西可用,比如至少没办法启动gdb,然后打上一堆断点,舒舒服服地开始调程序--深表理解和同情。

一开始,Clay 的方法--不说,你也知道--是写上详尽的debug输出,轰炸控制台屏幕。他的tester,Chris,负责运行程序并对屏幕结果截图。那时Clay甚至还没有一台真正的Intel Mac,所以进度很慢。这个方法用了很久。Clay甚至没有亲眼看过自己写的所有分区表代码(GPT 和 MBR)的运行情况,流程是Chris发来截图,Clay改动代码,重编,Chris重新下载代码并重启。Again and again,向Chris致敬。


当列出Chris的 Macbook Pro上的所有block IO设备时,Clay开始拿不定如何在EFI下访问CDROM了--因为这玩意儿根本就没出现。这时候出现了一位不需别人拯救,却拯救了别人的Ryan,他非常好心地把自己的新Mac Mini借给了Clay,Clay非常高兴地发现,只要CDROM中有盘的话,就能找到光驱--这是个问题吗?如果是,是Apple 还是Intel?--后面 Clay 也高兴地确认了自己的代码几乎毫无问题。


接下来就是硬骨头了,回到实模式,Clay 要编写并静静地花数小时审阅自己的代码(right,我们都这样 ;-) ),然后,下载,运行,再然后,机器令人沮丧地重启。因为不知道那条指令造成了重启,就在一块代码后加上死循环,重编,运行(right,我们还这样 ;-) );机器挂住说明前面代码OK;后移死循环,重编,运行……周而复始,直到找到代码里所有的bug(right,我们仍然这样)。Clay 说所有的代码都和语法而不是自己的逻辑有关,这个ATT老鬼转到Intel语法上确实有点不习惯。


一旦thunk和中断handler代码能工作。Clay开始解决为什么NTLDR在诊测内存的时候挂掉。NTLDR 有233k大小--中文版XP上251k,英文版244k,怎么Clay的来个233k?--反汇编出来有97000行左右。从最后一个BIOS中断调用的输出中,Clay找到了大概是在哪里挂掉的,只是,需要比较精确地定位到具体的routine。


看来Clay差点就要写自己的调试器了,通过handle INT 3,他的代码能随意地控制使用INT 3的NTLDR了。以反汇编为参考,Clay列出了所有可能造成停止的地方,然后写了个函数把这些代码替换成0xCC(INT 3的操作码),后面就好说了,写好INT 3的ISR,在这里头替换原来的指令,改变一下返回地址,就能在ISR返回后,执行改才的原始指令了--基本的软断点功能--还真的能工作了 :-)
此后Clay又做了点扩展,在INT 3中自动使能trap模式,这样就能在执行原始指令后再次把指令替换成0xCC,这样循环或者某函数被调用时,原来的断点还在。此后的再进一步是提供了断点选项,能让trap模式一直使能,这样就能得到两点之间所有指令执行的trace信息了。



最后是VGA text mode的难题了。标准的图形及字符framebuffer(0xA0000 and 0xB8000)根本就没有map进内存,读取VGA寄存器只得到一堆garbage。Clay 如果了解更多PCI编程的话,就能映射framebuffer,并配置IO了,只是Clay还不太了解。在此期间,他已经在load-time对NTLDR打了patch,能让其向Clay自己的字符framebuffer写东西了,在每次中断的时候,都扫描这段framebuffer,然后绘制一部分模拟的字符模式屏幕。这招儿就是太慢,也足够hackish。Clay 也清楚应该可以使能真正的VGA模式--narf 和 blanka 就做到了--不过Clay不知如何下手。


不管怎么说,总而言之,Clay 对自己的代码非常happy--即便没有赢得比赛。这次经历让Clay学到很多技巧,期待下一次,还是让我们面朝Mac,春暖话开。


后话。

虽然一定不是唯一以及不一定是最好的做法,Clay的实现提供的很有用的参考,happy reading。


获胜者之一的Blanka也在Clay的这篇blog上留言,悻悻相惜的一句Awesome work 后,Blanka简要说了如何搞定VGA。主要又3个步骤:

1. Disable IGD (internal graphics device) from decoding legacy VGA IO ports (PCI configuration on i945)
2. Enable legacy VGA forwarding on the PCIX bus (PCI conf i945 too)
3. Configure M56 to enable framebuffer at 0xB8000 (done through legacy VGA ports)

好像上面3条没什么好翻的。
再多可以去看看留言,Blanka 提到他们也会很快发布代码。

为Clay提供帮助的Chris在留言中留下了flickr地址,看看这两人合作的心酸血泪史…debugging via camera,多有意思 ;-)

在响应一位Galvanick Lucipher的留言时,

Clay列出了自己阅读的数目:
Master Class: Assembly Language (Wrox Press) :关于保护模式编程的两章不错

Mastering Turbo Assembler (Sams):包含不错的i386汇编和中断处理程序的资料

上面两本书躺在Clay的书架上超过10年咯。

线上材料 Transition from Protected Mode to Real ModeAT&T Assembly Syntax (这个很有用);包含一些thunk代码的TianoCore EFI Development Kit ,在Edk/Sample/Cpu/Pentium/Cpu/Dxe/Ia32/Thunk.c。


 

新闻来源:刀枪Blue

至歉:本站几日前转载刀枪Blue的文章没有遵守CC规定,特在这向原作者刀枪Blue表示深深的歉意.

对文章打分

细说 Intel Mac 安装 Windows XP

1 (33%)
已有 条意见

    最新资讯

    加载中...

    编辑精选

    加载中...

    热门评论

      Top 10

      招聘

      created by ceallan