无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站广告联系 微信:wuyouceo QQ:184822951
楼主: chenall
打印 上一主题 下一主题

[原创]支持外置硬盘控制器驱动,可任意方式启动的PE[10-01-13稳定版]

  [复制链接]
1#
发表于 2008-3-6 12:17:28 | 显示全部楼层
这个光盘用正常的光驱是可以启动的,但是,把 ISO 放在硬盘 /boot/micrope.iso 的位置用 grub 启动,却失败,蓝屏 0x0000007E。第 1,2,3,4 项都是失败的,都是 7E 蓝屏。用真实光盘可以启动,1,2,3,4 都成功。
回复

使用道具 举报

2#
发表于 2008-3-6 18:21:21 | 显示全部楼层
当然是最新3月3日版的。

你说的这些,我好像还不明白,仿真的先后顺序,有这么重要吗?

map (cd)/TEST.IMG (fd0)
map --mem --unsafe-boot (cd)/WINPE.IMG (hd0)
map --hook



map --mem --unsafe-boot (cd)/WINPE.IMG (hd0)
map (cd)/TEST.IMG (fd0)
map --hook

这两种应该是等价的,如果其中一个出了毛病,那应该算是无盘天使的毛病,你报告给无盘天使,让他们解决吧,应该很容易解决。

我的测试是,1、2、3、4都不行,都是07E蓝屏(而第5是因为我没有SCSI驱动,所以根本无法测试,file not found)。所以,可能是你的程序本身还有若干不完善之处吧。测试是在一台清华同方AMD笔记本上进行的,真实机器下的测试。
回复

使用道具 举报

3#
发表于 2008-3-7 12:39:16 | 显示全部楼层
对不起,前面的报告没有说清楚。

我在前面是用 USB 闪盘启动测试的,U 盘被认成 HDD,作为硬盘 0x80 启动的。

今天把 MicroPE.ISO 放在硬盘 boot 目录下用 grub 启动,则 1,2 两项是成功的,而 3,4 两项都是 07B 蓝屏。

看来是因为没有 USB 驱动的原因了。

这个实验很容易,大家都可以测试。就是说,只要把 MicorPE.iso 放在 U 盘上 boot 目录,然后用 grub 来启动这个 ISO,就会出现 07E 蓝屏,1、2、3、4这四项都是相同的出错代码 07E。

chenall 新的命令序列我没有测试,我觉得这不是关键的地方。另外,map (hd0) (0xff) 似乎是有问题的,因为 (0xff) 是光盘。不知这条 map 的意图是什么?
回复

使用道具 举报

4#
发表于 2008-3-7 14:27:47 | 显示全部楼层
清除之前的光盘,应该用

map (0xff) (0xff)
map --rehook

然后再用

map (hd0) (hd1)
map --rehook

或者不用它也应该行的。

用 map (hd0) (0xff) 是有问题的。这样一来,(0xff)就成了一个光盘,其中的扇区大小是 2048 字节。这个光盘的内容却是硬盘,这在实模式下应该是要出错的,除非到了保护模式,也许驱动程序能够发现这是一个硬盘。

-------------

lianjiang,nn2nn,chenall,你们都在这里,这不是逼着我也来吗?不会是不欢迎吧?来这里学习都不让?估计世界上没这个道理吧?玩笑。微软是要推翻滴,无忧也是得来滴,两件事都得做,而且一定都能做到。
回复

使用道具 举报

5#
发表于 2008-3-7 18:18:52 | 显示全部楼层
chenall,这确实是个问题,我没想到这里仍然有问题。

问题主要与 --mem 有关。当使用 --mem 时,磁盘、光盘的映像被放置在内存顶端。如果只使用了一次 --mem,这其实不严重,直接卸载就完事,是安全的。但是,如果用了两个 --mem 的映像,那么它们在内存中就有一个先后的问题。最后加载的映像应该最先被释放掉,而不能够先释放掉早期加载的映像。

目前grub程序中的处理似乎不够周全(就是说,可能有bug),所以,在没有解决bug之前,卸载仿真的时候,最好是按照“先进后出”的原则来释放,不管是带 --mem 的,还是 不带 --mem 的,一律按照先进后出的原则来释放。似乎不带 --mem 的,总是可以释放,而带有 --mem 的,释放时才会出问题。

目前来说,因为加载 ISO 在前,所以,暂且先不要用 --mem 来加载它,这样释放它就比较容易。
回复

使用道具 举报

6#
发表于 2008-3-10 22:45:15 | 显示全部楼层
时空论坛3月10日上载了新的 grub4dos,

map --rehook 功能有变化,可以方便卸载内存盘。

chenall 试验一下,看看有没有问题。
回复

使用道具 举报

7#
发表于 2008-3-12 09:48:10 | 显示全部楼层
chenall,时空论坛 grub4dos 3 月 12 日有更新。
回复

使用道具 举报

8#
发表于 2008-3-12 12:01:41 | 显示全部楼层
grub4dos 已经上载了 3 月 12 日 的版本到 http://grub4dos.jot.com/

估计那些已经发现了的问题都解决了。

=================

另外,chenall,如果一个 MicroPE.iso 只是在内存中提供一个 WINPE.IMG 之类的映像就不再使用了,那将来我们还可以有更好一点的启动方式,大致如下:

map --mem=0x8000 (hd0,0)/BOOT/MicroPE.iso (0xff)
map (0xff) (0xff)

第一条 map 已经把 ISO 文件放置在内存的低端(位于物理地址16M处)了,第二条 map 把这个映射卸载。

然后,你可以用 (rd) 设备访问内存中的 iso 文件(设置好 rd-base, rd-size 等)。再用

map (rd)/...../WINPE.IMG (hd0)

来操作。

我们需要一条命令用来方便地把 (rd) 的基地址和长度设置为某个内存盘(例如 (hd0) 或者 (0xff) 等)的基地址和长度。这是下一个要完成的任务。
回复

使用道具 举报

9#
发表于 2008-3-12 16:19:17 | 显示全部楼层
3月12日又上载了一个(第二个) grub4dos 到 http://grub4dos.jot.com/ 问题应该解决了。
回复

使用道具 举报

10#
发表于 2008-3-13 12:07:48 | 显示全部楼层
好久没有测试了,今天下载了 0812 的测试,仍然有问题。是在dell机器上用u盘Hdd启动测试,ISO 在 u盘的/boot/micrope.iso,用 grub 启动它。测试结果:

=============

第0,3,4,5项出现错误:

找不到 \MiniPE\system.wim, 只能启动到 CMD 模式。

输入 xp_shell 后,出现:

Shell Explorer.EXE 启动失败,自动转入 CMD 命令行。
J:\MiniPE>_

手动按 Ctrl+Alt+Del 调出任务管理器,找到 C:\Windows\explorer.exe 运行,出现错误说:Normaliz.dll 找不到。失败。没有办法,只能按下机箱上的关机、重启按钮。

============

第 1,2 项直接出现 07E 蓝屏。这和以前的测试是一样的。

==================================

以上都是 U 盘启动的结果。硬盘启动没有试,应该可以成功的。
回复

使用道具 举报

11#
发表于 2008-3-22 14:39:53 | 显示全部楼层
我下载了 3 月 20 日的,我的用法很单纯,我只用 grub4dos 来启动 MicroPE.ISO。我对 Windows 这种 PE 很陌生,我自己没时间研究这些组件的制作,我只用现成的。

我跟踪 chenall 这个 PE 已经很长时间了,现在再继续跟踪,已经没有太大意义。这个技术还在不断完善。如果有重大变动,我希望有人通知我一声。比如说,某人以 chenall 的工作为基础,制作了某个功能版本,我希望有人能张贴一条消息在显眼的位置,让我知道。
回复

使用道具 举报

12#
发表于 2008-4-12 14:06:22 | 显示全部楼层
grub4dos 2008-03-14 和 04-10 应该是最好的了,刚刚上载的 04-12, 只更新了 grub.exe,下载地址:

http://grub4dos.jot.com/  

此次更新又解决了一个 grub.exe 的问题(即探测某些中断向量失败的问题),试试看还有无问题?

应该是这样的吧:报错本身就不对,说明老版本还不能前进到蓝屏就失败了。新版本虽然蓝屏,但说明已经能够走得更远,能够走到蓝屏的位置。

[ 本帖最后由 不点 于 2008-4-12 03:12 PM 编辑 ]
回复

使用道具 举报

13#
发表于 2008-4-12 22:34:31 | 显示全部楼层
不可能啊,怎么会呢?你确定是grub的毛病了吗?你的命令序列是什么样的,map --status 的显示正常吗?
回复

使用道具 举报

14#
发表于 2008-4-13 01:49:12 | 显示全部楼层
证据不足,不能证明新版有问题。要想证明新版有问题,你需要在完全相同的环境下测试(非压缩的影像大小也完全相同,字节数也丝毫不差)。并且,映像里面的工具也都换成同一个版本来测试才行。比较两个版本的 map --status 有何差别。map --status 能够显示内存盘的大小和占据的绝对内存位置。不要用 Windows 的占用来说明问题,那样是找不到问题的症结的。
回复

使用道具 举报

15#
发表于 2008-4-16 21:53:49 | 显示全部楼层
看看最新版 grub4dos 占用内存的问题是否解决: http://grub4dos.jot.com/
回复

使用道具 举报

16#
发表于 2008-4-23 01:58:59 | 显示全部楼层
大家看看,这个上传空间好不好?

http://www.free-spaces.info/

PcFile.org全球中文免费文件上传,支持 250M 的文件。
回复

使用道具 举报

17#
发表于 2009-11-21 06:50:14 | 显示全部楼层
有机会上网回复一下。

貌似 displaymem 仅仅显示系统内存,不会包括 map 之后的影响。所以,由 displaymem 显示的内存总是一样的,不必显示很多次。

map --status 的显示当然很重要。chenall 怀疑 --rehook 有问题,我也怀疑。但是目前我不能看代码,所以,希望 chenall 再研究一下 rehook 的代码部分,看看是否能找出什么毛病来。

另外,虽然你的 displaymem 显示你的内存已经超过了 4G,但是,map 所映射的内存并未放在 4G 以上,而是在 4G 以内。因此,这个问题似乎与内存的大小无关。

另外,测试者应该很容易确定,究竟为什么 (hd0,0) 不能被识别。比如,测试者可以运行 cat --hex (hd0,0)+XXXXXXXX 之类的命令,看看 (hd0,0) 的扇区数据是否被破坏了。另外,当 ls (hd0,0)/ 报错时,紧接着再尝试一次 root (hd0,0),看看能否成功。
回复

使用道具 举报

18#
发表于 2009-11-23 20:34:43 | 显示全部楼层
原帖由 chenall 于 2009-11-21 10:04 发表
长度自动加了0x20=32
刚好是CSPE.IMG的一个磁道。。


佩服这个猜测,一下子就找到家了。
回复

使用道具 举报

19#
发表于 2009-11-24 16:37:17 | 显示全部楼层
rehook增加一个磁道的问题好像很难解决。

现在不知道出错的具体位置。

根据报告,在小于 4G 的机器上,没有问题。在 4G+ 的机器上就有问题了。但我们的代码实际上与内存的大小无关,那么问题也就难以定位了。怀疑是某个未知的 bug,它在一定的条件下表现出来了。

能够让 map 增加一个磁道的可能情况有以下几种:

1)map (md)XXXX+YYYY 的时候,读取的 (md)XXXX+YYYY 的第一扇区(放置在 0000:8000 处,也就是 BS 所在的位置)被后续的某个操作覆盖掉了。这样,map 就不能发现分区表的存在,于是就构造一个新的分区表。

试试 cat --hex (md)XXXX+1 看看能否正确显示 MBR 扇区数据?(估计这一点是没问题的)

2)读的第一扇区并未被破坏掉,但 probe_mbr 函数本身发生了错误,未能发现由 map 自动构造的合法分区表。

具体的原因我们可能没有精力去仔细查找了,但我们可以设法阻止 rehook 去构造 MBR 磁道,这一点应该容易做到,比如通过 设置 map 的 flags 参数来实现,或者通过一个全局变量来控制。
回复

使用道具 举报

20#
发表于 2009-12-25 14:07:32 | 显示全部楼层
pxe unload,有点意思.........

看了 bean 的 fsys_pxe.c 的代码,发现如下的一个片段:


  1.   i = 0;
  2.   while (code[i])
  3.     {
  4.       grub_memset (&unload, 0, sizeof(unload));
  5.       pxe_call (code[i], &unload);
  6.       if (unload.Status)
  7.         {
  8.           grub_printf ("PXE unload fails: %d\n", unload.Status);
  9.           goto quit;
  10.         }
  11.       i++;
  12.     }
  13.   if (*((unsigned short *)0x413) == pxe_basemem)
  14.     *((unsigned short *)0x413) = pxe_freemem;
  15.   pxe_entry = 0;
  16.   ROM_int15 = *((unsigned long *)0x54);
  17.   grub_printf ("PXE stack unloaded\n");
复制代码

意思就是说,把 pxe bios 所占用的内存释放掉。释放掉之后呢?.....

因为 pxe bios 很有可能把 int15 接管了,所以,pxe 的 bios 在卸载时会恢复原先的 ROM int15。因此此时确实应该把 GRUB4DOS 所记录的 ROM_int15 进行更新。

但是由此我们也能想到,会不会某个 PXE BIOS 连 int13 也更改了呢?如果它曾经接管了 int13,那么,在卸载它自己的时候,它应该也会恢复原先的 ROM int13。因此此时我们也应该把 GRUB4DOS 所记录的 ROM_int13 和 ROM_int13_dup 进行更新:

  1. extern unsigned long ROM_int13;
  2. extern unsigned long ROM_int13_dup;

  3.   i = 0;
  4.   while (code[i])
  5.     {
  6.       grub_memset (&unload, 0, sizeof(unload));
  7.       pxe_call (code[i], &unload);
  8.       if (unload.Status)
  9.         {
  10.           grub_printf ("PXE unload fails: %d\n", unload.Status);
  11.           goto quit;
  12.         }
  13.       i++;
  14.     }
  15.   if (*((unsigned short *)0x413) == pxe_basemem)
  16.     *((unsigned short *)0x413) = pxe_freemem;
  17.   pxe_entry = 0;
  18.   ROM_int15 = *((unsigned long *)0x54);
  19.   ROM_int13_dup = ROM_int13 = *((unsigned long *)0x4C);
  20.   grub_printf ("PXE stack unloaded\n");
复制代码


同时需要把 asm.S 中的

ROM_int13:

改成

VARIABLE(ROM_int13)

而把

ROM_int13_dup:

改成

VARIABLE(ROM_int13_dup)

[ 本帖最后由 不点 于 2009-12-25 14:09 编辑 ]
回复

使用道具 举报

21#
发表于 2009-12-30 21:13:50 | 显示全部楼层
@chenall

我又更改了 echo.c 的代码和编译选项。请看注释部分。

发现 -fPIE 选项比 -fPIC 好。这个 -fPIE 可以把函数的地址也按照动态去处理了。
  1. /*
  2. * compile:                     

  3. gcc -nostdlib -fno-zero-initialized-in-bss -fno-function-cse -fno-jump-tables -Wl,-N -fPIE echo.c

  4. * disassemble:                 objdump -d a.out
  5. * confirm no relocation:       readelf -r a.out
  6. * generate executable:         objcopy -O binary a.out b.out
  7. *
  8. * and then the resultant b.out will be grub4dos executable.
  9. */

  10. /*
  11. * This is a simple ECHO command, running under grub4dos.
  12. */

  13. int i = 0x66666666;     /* this is needed, see the following comment. */

  14. /* gcc treat the following as data only if a global initialization like the
  15. * above line occurs.
  16. */

  17. /* a valid executable file for grub4dos must end with these 8 bytes */
  18. asm(".long 0x03051805");
  19. asm(".long 0xBCBAA7BA");
  20. /* thank goodness gcc will place the above 8 bytes at the end of the b.out
  21. * file. Do not insert any other asm lines here.
  22. */

  23. int
  24. main()
  25. {
  26.         void *p = &main;

  27. //      void *p = &&label002;
  28. //label002:
  29. //        asm("1:");
  30. //        asm("subl $(1b-main), %0":"=m"(p));
  31.         
  32.         return
  33.         /* the following line is calling the grub_sprintf function. */
  34.         ((int (*)(char *, const char *, ...))((*(int **)0x8300)[0]))
  35.         /* the following line includes arguments passed to grub_sprintf. */
  36.                 (0, p - (*(int *)(p - 8)));
  37. }
复制代码
说明:0x8300 处放置的是一个指针,指向 system_functions。

所以,(*(int **)0x8300) 就是 system_functions 的地址。
所以,((*(int **)0x8300)[0]) 就是 system_functions 数组的首项的值。这个值又是 grub_sprintf 的地址。
因此,在其前面加上一个类型转换符 ((int (*)(char *, const char *, ...)) 就变成了函数的地址了。

最后一行是传递给 grub_sprintf 函数的参数。第一个参数 0 表示输出的目的地是屏幕。第二个参数就是 Format 格式字符串,这里指向命令行。

下面解释为什么第二个参数是指向命令行的。

p 是 main 的地址。(p-8)处的整数,即 *(int *)(p-8) 是命令行起始地址到main的距离(以字节计)。
因此,p 再减去这个整数就是命令行的地址了。

这里仍然需要解释,grub4dos 在装载程序映像到内存之前,先建立一个程序段前缀 PSP,这里沿用 DOS 的术语。不过,DOS 的 PSP 是固定长度,恰好有 256 个字节,而我们的 PSP 却是不定长的,由 grub4dos 动态决定 PSP 的长度。程序映像紧接 PSP 之后放置,就像 DOS 的 com 程序的情况那样。

我们的 PSP 的长度记录在紧接程序映像之前的一个整数中,因此这个整数的地址相对于 main 的偏移量就是 -4 了。而偏移量 -8 处的整数则就是我们的命令行的地址了。这些位于 main 之前的整数、字符串,都在 PSP 中。grub4dos 的程序装载器会把命令行等必要的数据复制到 PSP 中,保证程序能够正常运行。

grub4dos 现在的运行程序的功能虽然是初步的,但确实已经可以工作了。我们还没有实现内存管理的功能,但是却抢先实现了进程的管理。
因为没有实现内存管理,所以,应用程序无法动态申请内存,也无法释放内存。不过,应用程序可以使用静态内存,这样就避免使用动态内存了。静态内存就是在程序中显式定义了的内存,例如 C 语言的 int i; 就是显式定义了一个整数 i。这个 i 所使用的空间就是静态的,无须再经过“向操作系统申请内存”的步骤。

所以,其实现在用户已经可以编写很多简单的程序了,只要这些程序不访问磁盘文件,而且也不申请动态内存便可。
回复

使用道具 举报

22#
发表于 2009-12-31 09:19:10 | 显示全部楼层
@chenall

boot land 上有人报告 message 文件导致 gfxmenu 死机,你能否跟踪一下,看看问题在哪里?

http://www.boot-land.net/forums/index.php?showtopic=10096
回复

使用道具 举报

23#
发表于 2010-3-14 14:28:18 | 显示全部楼层
因为GRUB4DOS的各种版本也是间隔性的支持UltraISO编辑的,那就要找找GRUB4DOS的原因了。


我从未研究过 ultraISO,因此以往在我负责期间也从未明确支持过 ultraISO。应该说是 ultraISO 有意无意(或者碰巧)支持了 grub4dos。

我们的目的是制作一个可启动的光盘,别的都不要谈。至于说哪个 ISO 工具制作得好,那需要实践的检验。
mkisofs 有一套明确的制作规范,有它的特色。并且它还是开放源码的。这样的话,一旦它出问题了,世界上就有很多人可以修补它。到目前为止,就 grub4dos 与 mkisofs 的关系而言,由 mkisofs 制作的 grldr 光盘还从未出现过一例失败的情况(仅就2007年12月以后的 bug 报告的数量而言,是0个;但2007年11月以前的 grldr 在制作可启动光盘方面是有毛病的,同时也一直有 bug 报告)。这就更加确立了 mkisofs 在 grub4dos 中的地位,它的不可代替的地位。

我并未深入研究 mkisofs 的技术层面。我猜测,mkisofs 通过恰当安排引导扇区文件的物理位置,保证了启动的成功率。其它工具一旦修改了经由 mkisofs 制作的 iso 文件,则很容易破坏掉 mkisofs 的精心安排,导致启动失败。这些工具如果不改动 mkisofs 对于引导扇区文件物理位置的安排,我猜测,将不会破坏启动的成功率。

启动成功率(是否启动失败死机?)很重要,而启动之后是否因为文件名大小写问题而找不到菜单,则是一个很小的问题,不足挂齿。可以用很多不同的方法来解决这个问题。这就不在这里讨论了。

[ 本帖最后由 不点 于 2010-3-14 14:29 编辑 ]
回复

使用道具 举报

24#
发表于 2010-3-14 15:37:34 | 显示全部楼层
h99h99 用的是 U 盘测试,那就不知道原因了。3.14 新版是基于 chenall 的最新版制作的。

怀疑是这样的:grub4dos 在这台机器上探测 U 盘的 CHS 参数不准确,导致装入文件的扇区出错,因此死机。

试试从硬盘上加载同一个 img ,看看能否成功?

如果是 U 盘,用 fbinst 强化引导,看看问题是否解决?
回复

使用道具 举报

25#
发表于 2010-3-14 17:01:03 | 显示全部楼层
h99h99

你先把顺序弄好。当grub4dos都不能载入映像的时候,你再去讨论载入映像以后的问题,岂不可笑?

你先得保证映像能够顺利加载和启动(在 BIOS 的实模式阶段),然后再考虑保护模式下的仿真磁盘驱动问题。

你最好试试 fbinst,这是个强大的启动工具,专门对付那些糟糕的 BIOS 的,让死机变活。
回复

使用道具 举报

26#
发表于 2010-3-15 12:34:37 | 显示全部楼层
yyjdelete,你的情况可不能算是糟糕的。相反,我认为你的机器对 grub4dos 的支持是比较好的。

不要太过于强求完美,完美是达不到的。有很多机器在 BIOS 中都不能识别大硬盘。137G是一个界限,有很多机器的 BIOS 不能访问位于 137G 以后的扇区。

因此,这个问题是 BIOS 造成的,但又是普通的问题,所以也就不算是问题了。

你的主分区占有 30G,你的第一个逻辑分区是 137G,因此,你的第一个逻辑分区的大部分(107G)都落在 BIOS 可以访问的区域中,这个分区中剩余的 30G 可能无法被 BIOS 访问。而你的第二个逻辑分区就可能完全无法被 BIOS 访问了(因为它完全位于 137G 以后)。

如果是这样的话,这完全在意料之中。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-5-12 14:33

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表