准备工具:
Windbg 6.12
bochs-2.4.6-msvc-src(http://sourceforge.net/projects/bochs/files/bochs/2.4.6/)
vmware.
Securable (检查是否开启VT的)
VC 2008.
Intel vt技术十分诱人,但是如何调试vt程序却是让人头疼, 我们经常使用的vmware貌似不支持cpu vt技术的模拟,貌似只有bochs支持cpu vt技术的模拟。
看了下qemu的代码发现其feature里有支持VT特性的,不过试了它提供的几个cpu,发现只有qemu64(cpu 名称)支持VT.
步骤:
1, 修改config.h中的
#define BX_SUPPORT_VMX 0
改成
[COLOR="Red"]#define BX_SUPPORT_VMX 1
或者
#define BX_SUPPORT_VMX 2[/COLOR]
2, 编译.你会发现bx_cpu_c::init_VMCS(), vmcs_field_offset()等link error!
解决方法:
将cpu\vmcs.cc加进工程就可以了
3, 到现在bochs已经编译出来了,接下来就是安装系统.bochs太慢,使用vmware装把.
具体步骤参考三寸法师的文章(http://bbs.pediy.com/showthread.php?p=964315).
装完后用Securable检测下看是否支持vt.再加上调试模式(修改boot.ini...不多说,不知道的可以搜一下vmware+debug调试)
发现绿色的YES,好了支持了,不过还有问题,见下文.
4, bochs 支持串口, 用Windbg连接bochs进行源码调试吧.在bochs的配置文件中加一句
com1: enabled=1, mode=pipe_server, dev=”\\.\pipe\bochs”
然后运行虚拟机,会发现bochs会一直在等待,这时打开windbg连接\\.\pipe\bochs .嗯,bochs开始运行了.选择调试模式,好吧.windbg直接退了.有木有.有木有.如果是windbg 6.09你就发现他不会退出而是没啥反应.
5, 看了下bochs中串口的实现,是同步的(难道是因为这个退出的?),翻了下virtualbox的串口的代码发现确实异步,开了读写线程。好吧,看到网上有用bochs调试wrk的一篇文章<wrk源码分析之WinDbg+Bochs调试>,里面给出了段代码(注:这个代码我改了下发现这段代码在想串口写数据的时候锁死了, 修改及其原版代码见附件)用这个试试.
将其代码加到项目文件中.然后在serial.h中的bx_serial_t定义中添加一变量(红色字体部分):
int io_mode;
int tty_id;
SOCKET socket_id;
FILE *output;
#ifdef WIN32
HANDLE pipe;
[COLOR="Red"]void* p_cls_our;[/COLOR]
#endif
#if USE_RAW_SERIAL
serial_raw* raw;
#endif
然后在serial .cc文件中的bx_serial_c::init(void)添加(红色部分) 这里我们添加了一个模式”pipe”具体设置见后面:
略…
if (server) {
pipe = CreateNamedPipe( dev,
PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
1, 4096, 4096, 0, NULL);
if (pipe == INVALID_HANDLE_VALUE)
BX_PANIC(("com%d: CreateNamedPipe(%s) failed", i+1, dev));
BX_INFO(("com%d: waiting for client to connect to %s", i+1, dev));
if (!ConnectNamedPipe(pipe, NULL) && GetLastError() != ERROR_PIPE_CONNECTED)
{
CloseHandle(pipe);
pipe = INVALID_HANDLE_VALUE;
BX_PANIC(("com%d: ConnectNamedPipe(%s) failed", i+1, dev));
}
}
// client mode
else {
[COLOR="Red"] if ( strcmp(mode, "pipe") == 0 ){
BX_INFO(("!!!!!!into our code!!!!!!!"));
serial_pipe* our_serial = new serial_pipe(dev);
BX_SER_THIS s[i].p_cls_our = our_serial;
}else{[/COLOR]
pipe = CreateFile( dev,
GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
if (pipe == INVALID_HANDLE_VALUE)
BX_INFO(("com%d: failed to open pipe %s", i+1, dev));
[COLOR="Red"]}[/COLOR]
}
略…
在serial .cc文件中void bx_serial_c::rx_timer(void)函数添加(红色部分):
略…
#ifdef WIN32
DWORD avail = 0;
if (BX_SER_THIS s[port].pipe &&
PeekNamedPipe(BX_SER_THIS s[port].pipe, NULL, 0, NULL, &avail, NULL) &&
avail > 0) {
ReadFile(BX_SER_THIS s[port].pipe, &chbuf, 1, &avail, NULL);
data_ready = 1;
}
[COLOR="Red"] if (BX_SER_THIS s[port].p_cls_our){
chbuf = ((serial_pipe*)(BX_SER_THIS s[port].p_cls_our))->receive();
data_ready = 1;
}[/COLOR]
#endif
略…
再在serial .cc文件中void bx_serial_c::tx_timer(void)函数添加(红色部分):
略…
#ifdef WIN32
if (BX_SER_THIS s[port].pipe) {
DWORD written;
WriteFile(BX_SER_THIS s[port].pipe, (bx_ptr_t)& BX_SER_THIS s[port].tsrbuffer, 1, &written, NULL);
}
[COLOR="Red"] if (BX_SER_THIS s[port].p_cls_our) {
serial_pipe* p_serial = (serial_pipe*)(BX_SER_THIS s[port].p_cls_our);
p_serial->transmit(BX_SER_THIS s[port].tsrbuffer);
}[/COLOR]
#endif
略…
再在头部添加新添文件的头文件:
[COLOR="Red"]#if USE_PIPE_SERIAL
#include "serial_pipe.h"
#endif[/COLOR]
好吧还得在config.h中添加:
[COLOR="Red"]#define USE_PIPE_SERIAL 1[/COLOR]
6, 大功告成,编译.好!成功.
7, 修改bochs配置文件:
[COLOR="Red"]com1: enabled=1, mode=pipe, dev="pipe\bochs"[/COLOR]
8, 发现windbg连上了,并且可以源码调试了.如图:
这是啥?newbluepill???
9,到这就完了嘛?no..windbg 输入g enter.. 草..蓝了,断在vmx_on指令上..不支持?
发现bochs后台输出了句: #GP: VMXON is not allowed !.
抬头对天大喊一声,草!!.明明是支持的呀!
跟了下发现是:
!(BX_CPU_THIS_PTR msr.ia32_feature_ctrl & BX_IA32_FEATURE_CONTROL_LOCK_BIT)
引起的.查找了下BX_IA32_FEATURE_CONTROL_LOCK_BIT的引用.发现:
/* enable VMX, should be done in BIOS instead */
BX_CPU_THIS_PTR msr.ia32_feature_ctrl =
/*BX_IA32_FEATURE_CONTROL_LOCK_BIT|*/ BX_IA32_FEATURE_CONTROL_VMX_ENABLE_BIT;
哦.知道了原来在bios里设置.可是bochs那丑陋的bios根本就不能设置,只能设置从哪启动,一不做二不休,干脆把注释去掉:
/* enable VMX, should be done in BIOS instead */
[COLOR="Red"]BX_CPU_THIS_PTR msr.ia32_feature_ctrl =
BX_IA32_FEATURE_CONTROL_LOCK_BIT | BX_IA32_FEATURE_CONTROL_VMX_ENABLE_BIT;[/COLOR]
再跑ok了.可以运行了.如图:
这又是啥??
PS:bochs的时钟频率很快,所以其串口速度也非常快.比VirtualKD都看.至于你你信不信,反正我是信了.
修改过的代码:
bochs-pipe-serial.rar
doc文档:
Bochs调试VT代码.doc
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课