准备工具:
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
代码:
#define BX_SUPPORT_VMX 1 或者 #define BX_SUPPORT_VMX 2
解决方法:
将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”
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; void* p_cls_our; #endif #if USE_RAW_SERIAL serial_raw* raw; #endif
代码:
略… 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 { 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{ 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)); } } 略…
代码:
略… #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; } if (BX_SER_THIS s[port].p_cls_our){ chbuf = ((serial_pipe*)(BX_SER_THIS s[port].p_cls_our))->receive(); data_ready = 1; } #endif 略…
代码:
略… #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); } 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); } #endif 略…
代码:
#if USE_PIPE_SERIAL #include "serial_pipe.h" #endif
代码:
#define USE_PIPE_SERIAL 1
7, 修改bochs配置文件:
代码:
com1: enabled=1, mode=pipe, dev="pipe\bochs"

这是啥?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 */ BX_CPU_THIS_PTR msr.ia32_feature_ctrl = BX_IA32_FEATURE_CONTROL_LOCK_BIT | BX_IA32_FEATURE_CONTROL_VMX_ENABLE_BIT;


这又是啥??
PS:bochs的时钟频率很快,所以其串口速度也非常快.比VirtualKD都看.至于你你信不信,反正我是信了.
修改过的代码:
bochs-pipe-serial.rar
doc文档:
Bochs调试VT代码.doc