前言
上一篇文章我们来一起简单分析了bochs的物理内存初始化这一过程,现在引出一个问题:我们编写的代码是如何被bochs读取并映射到物理内存中的呢。要回答这个问题,我们必须来分析bochs中的软盘编写过程。
Bochs的设备链概念
Bochs的各种设备初始化是由一个"PLUG_load_plugin(xx,xx)"宏来完成的,当物理内存初始化完成,其调用一个宏“DEV_init_devices()”,该函数就是来初始化各种设备。函数中有一个是初始化软盘的,我们先不管其他的,仅针对它来分析
PLUG_load_plugin(floppy, PLUGTYPE_CORE);
这里先给出函数的调用堆栈,免得忘记自己走过的路(这里先不画图了)。
> bochs.exe!bx_devices_c::init(BX_MEM_C * newmem) Line 221 C++
bochs.exe!bx_init_hardware() Line 1378 C++
bochs.exe!bx_begin_simulation(int argc, char * * argv) Line 1027 C++
bochs.exe!bx_real_sim_c::begin_simulation(int argc, char * * argv) Line 907 C++
bochs.exe!win32_ci_callback(void * userdata, ci_command_t command) Line 679 C++
bochs.exe!bx_real_sim_c::configuration_interface(....)
bochs.exe!bxmain() Line 341 C++
bochs.exe!main(int argc, char * * argv) Line 557 C++
初始化软盘设备的函数如下,可以看到其操作比较简单,先是创建了一个软盘设备对象"theFloppyController",然后将设备对象赋值给"bx_devices.pluginFloppyDevice",我们很容易推测出"bx_devices"是管理bochs的全部设备的。然后调用一个函数,该函数通过函数名可以知道是"注册设备模型”。(这里我其实拿不准,在Windows内核中有设备链这一概念,比如我们想拦截Windows中的键盘消息,我们应该先通过设备链来搜索出键盘这个设备对象模型,然后对其IRP消息进行过滤拦截。我们用这种模型来尝试套在bochs上。)
int CDECL libfloppy_LTX_plugin_init(plugin_t *plugin, plugintype_t type)
{
if (type == PLUGTYPE_CORE) {
theFloppyController = new bx_floppy_ctrl_c();
bx_devices.pluginFloppyDevice = theFloppyController;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theFloppyController, BX_PLUGIN_FLOPPY);
return 0; // Success
} else {
return -1;
}
}
void pluginRegisterDeviceDevmodel(...)函数分析
该函数比较少,很明显就是链表操作,我们直接画出数据结构图,代码就不必分析了。
typedef struct _device_t
{
const char *name; // 设备名称
plugin_t *plugin; // 插件? 此时为NULL,不需要分析
plugintype_t plugtype; // 类型,由该值决定不同的链表
class bx_devmodel_c *devmodel; // 设备模型
struct _device_t *next; // 链表中的下一个设备
} device_t;