无忧启动论坛

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

[已解决] VBE模式在VirtualBox下用不了,另外,VBE相关命令的用户交互似乎有问题

  [复制链接]
跳转到指定楼层
1#
发表于 2013-12-15 13:33:59 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 stevenldj 于 2013-12-24 18:51 编辑

使用环境 Ubuntu 13.10 amd64 + VirtualBox 4.2.16,虚拟机类型使用 Windows XP,grub4dos-0.4.5c-2013-11-30.7z

在虚拟机的 Grub4Dos 命令行中输入 setvbe 800x600x32,确认后,屏幕全黑,但是可以继续输入命令,只是看不见输入的是什么,输入 reboot 还可以重启。设置其它分辨率也是一样。而通过 graphicsmode -1 800 600 却可以正常修改分辨率。在 Windows 下用 FbinstTool 的 Qemu 虚拟机测试,也是同样的效果。在实际电脑中测试也是同样的效果,不过实际电脑中好一点,可以切换各种8位的显示模式。

还有,VirtualBox 和 Qemu 在 gfxmenu /message 环境下,通过菜单进入 commandline 后,屏幕下方花屏(Qemu黑屏),同样可以继续输入命令,输入 halt 还可以关机。



另外关于VBE相关命令交互的问题,输入 vbeprobe 后,一屏显示不完,提示 [Hit Q to quit, any other key to continue],此时按 q 或者 Q 都不会退出,而是 continue。setvbe 也同样存在这个问题。

另外问几个初级问题:《0401更新,grub4dos0.4.5c帮助文档》的“设备命名规则”一章中说“cd      :     0x9F (这个不一定正确,视bios而定)”,这里的设备 (cd) 有什么作用?我们平时访问光驱不都是用 (cd0)、(cd1) 这样的设备吗?用 (cd) 能访问什么呢?

在《0401更新,grub4dos0.4.5c帮助文档》的“设备命名规则”一章中说“nd 为 network device ,网络驱动器,现已不常用”,(nd) 是什么设备,能否给个具体例子?

还有关于内存的一些疑问,如果用户需要一些缓冲区来存放数据,比如临时的菜单文件,用什么范围的内存比较合适呢?看《0401更新,grub4dos0.4.5c帮助文档》中“内存使用简析”一章中说:

现在 grub4dos 本身对常规内存的占用情况如下:
00000~10000 被 grub4dos 的程序代码和堆栈占用。
10000~20000 为 grub4dos 将来的代码和数据保留。
20000~30000 被 grub4dos 内核中的自动几何参数探测占用,作为缓冲区。
30000~38000 被 grub4dos 内核中的常规磁盘读写缓冲区占用。
38000~40000 保留给 grub4dos 将来的扩展。
100000~110000 被 dd 命令的磁盘缓冲区占用。

是不是用 100000 之后的内存就安全呢?向内存中写入数据,会不会影响到 map 出来的内存盘?我看到在有些菜单中,使用 20000~30000 这个范围的内存来存放临时数据,不知到有没有相关的内存使用规范?



推荐
 楼主| 发表于 2013-12-16 13:06:21 | 只看该作者
本帖最后由 stevenldj 于 2013-12-16 16:43 编辑

我理解开发团队缺少更多的人帮助开发 Grub4Dos,可惜我不懂 C 语言和汇编,也不懂硬件底层,所以帮不上什么忙,我能帮忙的只能是学好 Grub4Dos 的用法,然后将学习心得分享出来。

我知道怎么通过 map 命令设置 (rd) 设备,只是不知道 (rd) 设备有什么特性,设计这样一个 (rd) 设备是用来干什么的?什么情况下需要用到 (rd)。比如下面的代码:

# 备份旧 rd 信息
set /a rdnum=*0x82CC
set /a rdbase=*0x82D0
set /a rdsize=*0x82D8
# 设置新 rd 信息
map --mem --rd-base=50000
map --mem --rd-size=30000

这样的 (rd) 设备使用了 50000 - 7FFFF 的内存,这块内存会像 (fd126) 一样被保护起来吗?会被其它代码(比如 dd 的缓存)修改吗?这块内存使用完需要释放吗?对 (rd) 的特性和用途完全不了解。

还有一个问题,我通过 map --mem=-2880 /somefile (126) 获得了一块内存区域,如何得到这块内存区域的起始地址和内存块的长度(长度大概可以通过 2880x512 得到,起始地址如何获取)。

这些天在根据《0401更新,grub4dos0.4.5c帮助文档》学习 Grub4Dos,所以问题比较多,见谅!




回复

使用道具 举报

推荐
发表于 2013-12-16 01:56:49 | 只看该作者
其实是说明文档没能跟上开发的进度。旧版 grub4dos 使用地址 16M 以下的内存。但新版增加到 32M 了。因此,dd 的缓冲区必须设置在 32M 以上。

还要提醒一下,用户自己设置 dd 缓冲区,属于黑客行为,因此,需要用户自己来保证内存使用的合理,不要导致内存冲突。

比如说,用户可以把缓冲区设置在 32M 处,缓冲区大小也设置为 32M,即 32M - 64M 之间的空间作为 dd 缓冲区。此时,如果运行了 kernel 命令来加载 Linux 内核,那么,grub4dos 会把 Linux 的内核放在地址 32M 处。如果 dd 的缓冲区也是在 32M 处,那么,dd 命令将破坏内存中的 Linux 内核。用户运行的 32 位程序代码,也是位于 32M 处。因此,如果 dd 缓冲区设置在 32M 处,用户的 32 位进程的代码区就要遭到 dd 命令的破坏了,当然就会造成死机了。如果用户所执行的 32 位程序本身不调用 dd 命令,那是比较安全的。因为我们现在的进程都不是常驻内存的,即,活动的进程只有一个,只有在它退出时,才能执行下一个程序。因此,目前而言,只要这个活动的进程不再调用 dd 命令,那么就不会有冲突。但将来很难说。将来如果实现常驻内存程序,那就需要保证在前提条件 “没有常驻内存程序存在” 的情况下,才能安全地使用 dd 命令的用户缓冲区。

当然了,黑客们还应该保证,dd 使用的输入、输出文件,不可以与 dd 的缓冲区相互覆盖,否则,dd 自己将产生内存冲突。

map --mem=-2880 /somefile (fd127)


这个办法在理论上是对的,但是你碰巧使用了 (127) 这个盘号。你知道,(127) 就是 (0x7F) ,它刚好是 (rd) 默认的盘号。看来 grub4dos 应该把 rd 的默认盘号设置为 (0xFF7F),这样就不会与用户自己的 (fd127) 相冲突了。

目前你可以换成 (126) 这个盘号,这就没问题了。

给用户预留的内存,就是前面曾经提到的 0x50000 - 0x7FFFF 这段内存。你的 32 位进程在接管控制后,所有的剩余自由内存都属于它的管辖范围。目前我们缺乏完善的进程管理。chenall 开发了 malloc 函数和 free,可以让用户申请内存和释放内存。但是,整个进程的管理体系没有建立起来,那么用户使用 malloc 和 free 函数,也就不那么放心了。所以,需要有人做进程管理的一套完整的设计。如果你有兴趣,不妨尝试一下。我承认,这可能属于我未完成的工作。但是,我也是摸着石头过河,我也不懂进程管理,我不知道怎么做最好,所以,我也就没有做下去了。

目前来说,你的 map --mem=-2880 /somefile (126) 的思路,可以当作权宜之计。你可以以这种方式建立你自己的 “内存管理体系”,当你需要内存时,你就用 map --mem=-2880 /somefile (126);map --hook;当你不需要它时,你就用 map (126) (126);map --unhook;map --hook;来撤销它(释放它)。

(rd) 是内存设备,用户可以设置它的基地址和长度。换句话说,用户可以指定任何一个内存区域作为 (rd) 设备的内容。map 命令有一些参数是与 (rd) 设备有关的,你可以看看源代码,也可以读读 readme 文件。

回复

使用道具 举报

推荐
 楼主| 发表于 2013-12-15 23:46:00 | 只看该作者
本帖最后由 stevenldj 于 2013-12-16 00:06 编辑

谢谢“不点”老大的指点,基本上明白了,但是关于 1M 以上的空间还有疑问:

位于 1M 以上的内存,叫做扩展内存。用户不可以直接使用扩展内存。扩展内存中,位于地址 32M 以内的这部分空间,是由 grub4dos 内核使用的。地址 32M 以上,则由用户的 “32位可执行程序” 使用。用户不可以直接写入这些空间,因为那可能破坏 grub4dos 内核,也可能破坏用户的可执行程序的代码或数据。


在《0401更新,grub4dos0.4.5c帮助文档》的“命令索引”一章中说:

dd
用法: dd if=IF of=OF [bs=BS] [count=C] [skip=IN] [seek=OUT] [buf=ADDR] [buflen=SIZE]

更新: 新选项实现了让使用者自定义dd 命令的读写缓存。
默认读写缓存起始于地址0x50000,长度为0x10000 (即64KB)。
你不能指定起始地址ADDR 低于0x100000(即 1 MB)的缓存位置。
此外,你必须指定参数SIZE 大于0x10000(即64K)。
通常,你需要令ADDR大于或等于0x1000000 (16MB),并且 SIZE 也要大于或等于16MB 。
增大 SIZE 的值能够加快 dd 的读写速度。


按照上述说明,如果将 ADDR 设置为 16M,并且将 SIZE 设置为 32M,岂不是会破坏 grub4dos 内核。

关于存储自定义数据,我想了一个办法,通过 map --mem=-2880 /somefile (fd127) 的方式创建一个固定大小的内存盘,然后通过 (fd127)m+n 的方式存取自己的数据,不知道这样是否是比较好的方法。

是否应该考虑给用户预留一块内存,或者允许用户随时申请一块内存来存放自己的数据

还有,关于 (rd) 设备有什么用?什么时候会用到?《0401更新,grub4dos0.4.5c帮助文档》中没有详细说明。


回复

使用道具 举报

推荐
发表于 2013-12-15 21:41:29 | 只看该作者
谢谢您对于 grub4dos 的支持,谢谢您的提问。由于问题提得多,所以,我尽量简单答复,请原谅。

setvbe 命令主要是为了某些 Linux 启动过程的图形界面而设计的,一般是用不着的。建议永远不要使用它。如果你能避免使用它,就尽量避免使用它。通常 Linux 在自己的启动过程中,会自行设置相应的图形模式,而不是需要经过 grub4dos 的设置才行。所以,将来有可能取缔这条 setvbe 命令。为了保持兼容性,我们现在不会取缔它。但当将来代码空间紧张的时候,setvbe 就有可能被未来的开发者取缔了。

还有一点需要强调,grub4dos 的 vbe 不支持 16 位及更低的色深,只支持 24 位和 32 位色深。所以,你的所有的 graphicsmode 命令,都需要显式地指定 24:32 的色深,不可以省略。比如,使用 graphicsmode -1 和 graphicsmode -1 800 600 都是不完全正确的,应该分别改成 graphicsmode -1 -1 -1 24:32 和 graphicsmode -1 800 600 24:32 才算是对的。

特别地说,grub4dos 不支持 8 位色深。用户使用 4位、8 位、15 位或16位这样的色深,所带来的问题,开发者无法解决。

另外,gfxmenu 命令与 grub4dos 本身的关系是松散的,两者各自属于不同的系统。grub4dos 仅仅是调用 gfxmenu 命令而已,后续的工作完全由 gfxmenu 的 message 文件来控制,属于 “进入了新的环境”。在新的环境下,你不一定能够运行 grub4dos 的命令,或者虽然你能运行,但可能出现某些不正常的效果。建议尽量避免使用 gfxmenu 命令。

关于 vbeprobe 显示满屏不能停止的问题,如果是 gfxmenu 之下引起的,则可能没人去解决了。如果是普通的正常模式下的问题,我觉得这适合由 chenall 来解决,如果 chenall 确实能够解决、并且愿意解决。

(cd) 是主板 BIOS 传递过来的光驱号码。当主板是从 “无仿真模式” 的 CDROM 盘片或 “无仿真模式” 的 USB-CDROM 启动时,BIOS 都会为相应的 CDROM 介质分配一个盘号,这个盘号就被 grub4dos 捕捉到了,并保存为 (cd) 。如果 BIOS 不是从 cdrom 启动的,则可能不存在 (cd) 这个盘号。

(cd0)、(cd1) 之类的,都不是 BIOS 传递过来的。它们是 cdrom --init 这个硬件驱动程序所建立的。因此,它们一开始都是不存在的,只有 cdrom --init 这条命令才能创建它们。但 cdrom --init 的通用性太差,很多电脑都不支持。因此,这条命令将被废弃(在未来的某个新版本中,有可能取缔 cdrom --init 命令)。建议永远不要使用它了。因此,相应的 (cd0)、(cd1) 等等,就都不存在了。

(nd) 是原始的 GNU GRUB 里面的 “网络设备”,新版 grub4dos 已经取缔了它。所以,今后就不存在 (nd) 了。我们使用 bean 所开发的 pxe 网络启动功能,其设备名为 (pd)。

关于内存使用,你引用的那段内容是我写的。但 chenall 后来又有的新的补充规定。 也就是说,还有别的一些内存被 grub4dos 占用,比如说从 0x40000 开始的一些内存就被 chenall 使用了。

用户自己可以随便使用的内存,我觉得,大致在 0x50000 ~ 0x7FFFF 吧。你可以向 chenall 求证,看看是不是这样的。0x80000 ~ 0x9FFFF 这段内存,有可能被主板的 pxe 程序和代码占用,以及被主板的 EBDA(即所谓 “扩展 bios 数据区”)占用。如果用户写入了这些为主板特别保留的区域,那就可能造成 bios 系统的紊乱,因而 grub4dos 也将崩溃。

位于 1M 以上的内存,叫做扩展内存。用户不可以直接使用扩展内存。扩展内存中,位于地址 32M 以内的这部分空间,是由 grub4dos 内核使用的。地址 32M 以上,则由用户的 “32位可执行程序” 使用。用户不可以直接写入这些空间,因为那可能破坏 grub4dos 内核,也可能破坏用户的可执行程序的代码或数据。

有些地址空间,虽然被 grub4dos 使用,但却是被 grub 当作临时、暂存空间来使用的,它们也可以被用户当作临时、暂存空间来使用。

比如,0x20000 ~ 0x2FFFF 这个 64K 的空间,就属于临时的、暂存的空间。grub4dos 如何使用它?当 grub4dos 需要确定磁盘介质的参数的时候,比如说,当 grub4dos 需要了解磁盘的 “CHS 或 LBA 支持” 情况的时候,grub4dos 会自动读取磁盘数据到这个空间中,探测 CHS 参数和 LBA 支持能力。

用户怎么样使用这段内存?用户心目中应该明白,这段内存有可能被 grub4dos 写入。因此,用户也只能把它当成临时的、暂存的空间来使用。就是说,用户可以随便写入它,但说不定 grub4dos 也会写入它。所以,用户写入后,应该尽快使用它,抢在 grub4dos 写入之前,赶快使用它。一般来说,如果用户一直都不使用磁盘介质,那么用户就可以认为这段空间没有被 grub4dos 毁掉。或者,用户一直都只使用某个磁盘,比如,一直都使用 (hd1)(而不会切换到别的盘),或一直都使用 (fd0)(而不会切换到别的盘),那么,用户就可以认为,grub4dos 也不会使用这段空间。如果用户切换到别的盘,则这段空间就可能被破坏了。举例来说,dd 命令有可能同时使用两个盘,如果这两个盘中正好有一个盘是先前没有访问过的,那么 grub4dos 就会自动探测这个新盘的 CHS 和 LBA 特性,这样也就有可能抹掉这段内存空间了。同样,find 命令也可能 “在暗地里”、“偷偷地” 访问多个盘,如果这些盘之中正好有一个盘是先前没有访问过的,那么 grub4dos 就会自动探测这个新盘的 CHS 和 LBA 特性,这样也就有可能抹掉这段内存空间了。只要用户保证在写入这段内存之后不再访问那些新盘,那么就比较有保证了。一旦开始访问一个新盘,那么,grub4dos 就可能要破坏这段内存了。

回复

使用道具 举报

6#
发表于 2013-12-16 18:00:54 | 只看该作者
本帖最后由 不点 于 2013-12-16 18:02 编辑

你提问的方式,表明你很严谨。

而 grub4dos 的开发进程,与文档的建立,两者之间是脱节的。这一点也制约着 grub4dos,使其难以被更专业的人员采用。

(rd) 设备是无保护的。你可以任意指定 (rd) 的基地址和长度。比如,你可以让 (rd) 从内存的 0 地址开始,那里也是中断向量表的开始。你可以让 (rd) 从某个 ROM 地址开始。你也可以让 (rd) 涵盖 32M 以内的 grub4dos 内存空间。总之,是任意的,你想让它指向哪里,它就会指向哪里。既然无保护,你也不需要释放它。甚至根本就没有 “释放它” 这样一个概念的存在。

在 grub4dos 中,这种理念很普遍。很多东西都是自由的、无保护的、没有限制的。换句话说,适合黑客使用。黑客使用这样的东西,需要自己来考虑安全问题,而不要造成内存冲突。前面已经谈过这样的话题了,所以,不再重复。

(rd) 设备的使用,与其他设备类似。比如,你可以用 cat --hex (rd)+1 来显示出 (rd) 的内容。

正如前面所说,(rd) 是未保护的,因此,它不同于 (fd126) 之类的虚拟盘。

你根本无法保护 (rd),因为 (rd) 可以设置在任何位置,具有任何长度。这种设计的目的,太自由了,使得它根本无法保护。因此,作为黑客,你就不敢随便写入 (rd),除非你事先已经知道你的 (rd) 是完全可以写入的。

(rd) 不是一个 int13 设备,而仅仅是一个 grub4dos 设备。在 grub4dos 里面,存在 (rd) 设备,但进入 DOS 以后,就没有 (rd) 设备了。

(fd126) 是一个 int13 设备,需要经过 map --hook 后才生效。生效后,它就变成一个 BIOS 设备了,因此,DOS 下也可以通过 int13 指令来获得 (fd126) 的扇区内容。

你可以这样做:

map --mem=-2880 /somefile (rd)

这并非建立了一个 (fd127) 虚拟盘,而是直接修改 (rd) 的基地址和长度,让 (rd) 指向内存顶部的 1.44M 内存空间。

虽然这个 (rd) 是没有保护的,但是,假如你后续没有建立别的虚拟内存盘,那么它还是比较安全的。由于 (rd) 设备不是一个 int13 设备,因此,你不能指望 map --hook 后,(rd) 会成为 int13 设备。

假如你真的想保护这个 (rd) 设备,目前来说,你大概只能采用某个技巧来变通,比如说这样:

map --mem=-2880 /somefile (rd)
map --mem=-2880 /somefile (fd126)
map --hook

第一条命令仅仅是让 (rd) 指向内存顶部的 1.44M。立即生效。
第二条命令是准备让 int13 的磁盘号码 126 指向内存顶部的 1.44M 空间。但还没有立即生效。
第三条命令执行后,第二条命令就开始生效了。

这样,你就知道了,(rd) 和 (fd126) 的内容是完全一样的,它们都指向内存顶部的 1.44M 空间。

所以,这样也就间接获得了 (fd126) 的基地址,它就等于 (rd) 的基地址。而 (rd) 的基地址是公开的,你可以从网上找到相关的知识。

回复

使用道具 举报

7#
 楼主| 发表于 2013-12-16 19:25:47 | 只看该作者
谢谢“不点”老大的指点,现在对内存的使用已经弄明白了,目前,为用户预留的内存空间是 0x50000-0x7FFFF,如果要使用被保护的内存空间,可以通过内存盘间接实现。(rd) 只是对内存的引用,不被保护,(rd) 很自由。
回复

使用道具 举报

8#
发表于 2013-12-16 19:58:15 | 只看该作者
很抱歉,还得补充一点。

我看到先前你在用 gfxmenu。建议你停止使用。

gfxmenu 也要使用一部分常规内存,大致也会使用 0x50000 - 0x7FFFF 空间。

因此,这有可能与用户使用的空间造成冲突。

所以,建议停止使用 gfxmenu 命令。

回复

使用道具 举报

9#
 楼主| 发表于 2013-12-17 18:15:24 | 只看该作者
嗯,知道了,不用 gfxmenu 了。
回复

使用道具 举报

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

本版积分规则

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

闽公网安备 35020302032614号

GMT+8, 2024-5-13 08:28

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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