colinux-driver简单分析

 

Colinux

目录

目录 1

操作系统OS相关内核函数定义 2

启动colinux的主进程 2

用户空间统一函数 4

WINNT主进程实现 4

Windows主进程主函数 5

检查管理器状态 7

检查管理器有没有安装 9

调用winnt的服务管理器 9

安装colinux驱动 10

检查是否安装colnux的服务 11

低级安装colinux驱动 11

通过名字安装,并启动 11

低级的启动驱动 13

打开管理器 13

Colinux进程实质的主函数 14

创建daemon分配结构 16

从配置文件读取配置信息 17

开始监视器monitor-vmlinux到内存 17

打开并读取vmlinux到内存 18

读取vmlinux执行文件ELF 20

ELF的数据结构 20

监视器创建-加载vmlinux内核到symbols_import结构内存 21

加载ELFwindows的内核内存空间 26

加载ELF节到windows内核内存 27

通过驱动控制将加载的ELF节到驱动内存 28

与驱动IO交互 28

驱动的控制包装函数 29

加载linux进程启动 29

创建反应器reactor 32

打开用户监视器运行内核 33

[选择]启动网络daemon 34

创建启动进程 35

启动可执行程序 36

用户监视开始-vmlinux开始 37

用户监视开始-vmlinux运行 37

Colinuxwindows驱动包装类 37

打开驱动colinux.sys 38

关闭驱动colinux.sys 38

驱动控制 39

检查驱动 39

驱动控制命令 40

Windows驱动的监视器控制 41

操作系统OS相关内核函数定义

H:/coLinux-0.7.3/src/colinux/os/kernel

这些头文件中定义了统一的函数,具体在linux和winnt这两个OS中实现

alloc.h

内存分配

filesystem.h

文件系统

manager.h

管理器

misc.h

杂项

monitor.h

监视器

mutex.h

互斥

time.h

定时器

user.h

用户

wait.h


Linux实现上面的函数

H:/coLinux-0.7.3/src/colinux/os/linux/kernel

WINT实现上面的函数

H:/coLinux-0.7.3/src/colinux/os/winnt/kernel

启动colinux的主进程

C:/coLinux>colinux-daemon

Cooperative Linux Daemon, 0.7.3

Daemon compiled on Sat May 24 22:36:07 2008

syntax:

    colinux-daemon [-d] [-h] [k] [-t name] [-v level] [configuration and boot parameter] @params.txt

  -d             Don't launch and attach a coLinux console on startup

  -h             Show this help text

  -k             Suppress kernel messages

  -p pidfile     Write pid to file.

  -t name        When spawning a console, this is the type of console

                 (e.g, nt, fltk, etc...)

  -v level       Verbose messages, level 1 prints booting details, 2 or

                 more checks configs, 3 prints errors, default is 0 (off)

  @params.txt    Take more command line params from the given text file

                 (can be multi-line)

Configuration and boot parameters:

Params should start with kernel=vmlinux (is the kernel image file

the '@' option is not needed. Instead, you pass all configuration

via the command line, for example:

  colinux-daemon kernel=vmlinux cobd0=root_fs hda1=:cobd0 root=/dev/cobd0 eth0=slirp

Use of new aliases automatically allocates cobd(s), for example:

  colinux-daemon mem=32 kernel=vmlinux hda1=root_fs root=/dev/hda1 /

  eth0=pcap-bridge,"Local Area Connection"

Unhandled parameters are forwarded to the kernel's boot parameters string.

See README.txt for more details about command-line usage.

See colinux-daemon's documentation for more options.

The following options are specific to Windows NT/XP/2000:

      --install-service [name]     Install colinux-daemon.exe as an NT service

                                   (default service name: Cooperative Linux)

      --remove-service [name]      Remove colinux service

                                   (default service name: Cooperative Linux)

      --install-driver             Install the colinux-driver (linux.sys)

      --remove-driver              Uninstall (remove) the colinux-driver (linux.sys)

      --status-driver              Show status about the installed/running

                                   driver

启动两个进程

colinux-daemon.exe  colinux-console-fltk.exe

这些信息在这个函数定义

daemon.c (h:/coLinux-0.7.3/src/colinux/user):void co_daemon_syntax()

用户空间统一函数

H:/coLinux-0.7.3/src/colinux/user 

H:/coLinux-0.7.3/src/colinux/user/daemon.c

void co_daemon_syntax()有两个实现,一个linux,一个winnt

main.c (h:/coLinux-0.7.3/src/colinux/os/linux/user/daemon): co_daemon_syntax();

main.c (h:/coLinux-0.7.3/src/colinux/os/winnt/user/daemon): co_daemon_syntax();

WINNT主进程实现

int WINAPI WinMain(HINSTANCE hInstance, 

   HINSTANCE hPrevInstance,

   LPSTR szCmdLine,

   int iCmdShow) 

{

co_rc_t rc;

int ret;

co_current_win32_instance = hInstance;

co_debug_start();

    主函数

rc = co_winnt_main(szCmdLine);

// Translate retcode into errorlevel, for --status-driver

ret = CO_RC_GET_CODE(rc);

switch (ret) {

case CO_RC_OK: //  0: ok, no error

case CO_RC_VERSION_MISMATCHED: //  3: co_manager_status

case CO_RC_ERROR_ACCESSING_DRIVER: // 14: driver not installed

break;

default:

ret = 1;

}

co_debug ("rc=%x exit=%d/n", rc, -ret);

co_debug_end();

return -ret;

}

E:/colinux-20070714-1/src/colinux/common/lib.c 公用库函数

Windows主进程主函数

主要是解析程序运行的参数

co_rc_t co_winnt_main(LPSTR szCmdLine)

{

co_rc_t rc = CO_RC_OK;

co_winnt_parameters_t winnt_parameters;

co_start_parameters_t start_parameters;

co_command_line_params_t cmdline;

int argc = 0;

char **args = NULL;

co_memset(&start_parameters, 0, sizeof(start_parameters));

co_memset(&winnt_parameters, 0, sizeof(winnt_parameters));

co_daemon_print_header();

    //分析命令行参数,一般是配置文件

rc = co_os_parse_args(szCmdLine, &argc, &args);

if (!CO_OK(rc)) {

co_terminal_print("daemon: error parsing arguments/n");

co_winnt_help();

return rc;

}

co_winnt_change_directory_for_service(argc, args);

rc = co_cmdline_params_alloc(args, argc, &cmdline);

if (!CO_OK(rc)) {

co_terminal_print("daemon: error parsing arguments/n");

co_os_free_parsed_args(args);

return rc;

}

    主要解析带--参数

rc = co_winnt_daemon_parse_args(cmdline, &winnt_parameters);

if (!CO_OK(rc)) {

co_terminal_print("daemon: error parsing parameters/n");

co_winnt_help();

return CO_RC(ERROR);

}

    解析-的参数

rc = co_daemon_parse_args(cmdline, &start_parameters);

if (!CO_OK(rc) || start_parameters.show_help){

if (!CO_OK(rc)) {

co_terminal_print("daemon: error parsing parameters/n");

}

co_winnt_help();

return CO_RC(ERROR);

}

rc = co_cmdline_params_check_for_no_unparsed_parameters(cmdline, PFALSE);

if (!CO_OK(rc)) {

co_winnt_help();

co_terminal_print("/n");

co_cmdline_params_check_for_no_unparsed_parameters(cmdline, PTRUE);

return CO_RC(ERROR);

}

//检查colinux win32的管理器有没有安装,有则打开服务

if (winnt_parameters.status_driver) {

return co_winnt_status_driver(1); // arg 1 = View all driver details

}

    //安装colinux驱动

if (winnt_parameters.install_driver) {

rc = co_winnt_install_driver();

if (CO_OK(rc)) {

co_terminal_print("daemon: driver installed/n");

}

return rc;

}

if (winnt_parameters.install_service) {

if (!start_parameters.config_specified) {

co_terminal_print("daemon: config not specified/n");

return CO_RC(ERROR);

} //作为服务安装

return co_winnt_daemon_install_as_service(

winnt_parameters.service_name, szCmdLine);

}

if (winnt_parameters.remove_service) {

return co_winnt_daemon_remove_service(winnt_parameters.service_name);

}

if (winnt_parameters.remove_driver) {

return co_winnt_remove_driver();

}

if (winnt_parameters.run_service) {

co_running_as_service = PTRUE;

co_terminal_print("colinux: running as service '%s'/n", winnt_parameters.service_name);

if (start_parameters.launch_console)

{

co_terminal_print("colinux: not spawning a console, because we're running as service./n");

start_parameters.launch_console = PFALSE;

}

return co_winnt_daemon_initialize_service(&start_parameters);

}

if (!start_parameters.config_specified){

if (!start_parameters.cmdline_config) {

co_daemon_syntax(); //打印参数用法

co_winnt_daemon_syntax();

}

return CO_RC(ERROR);

}

    //进程实质的主函数

return co_winnt_daemon_main(&start_parameters);

}

检查管理器状态

E:/MyColinux/src/colinux/os/winnt/user/daemon/driver.c

co_rc_t co_winnt_status_driver(int verbose)

{

co_rc_t rc;

bool_t installed = PFALSE;

co_manager_handle_t handle;

co_manager_ioctl_status_t status = {0, };

if (verbose)

co_terminal_print("checking if the driver is installed/n");

    //检查colinux win32的管理器有没有安装

rc = co_win32_manager_is_installed(&installed);

if (!CO_OK(rc))

return rc;

if (!installed) {

co_terminal_print("driver not installed/n");

return CO_RC(ERROR_ACCESSING_DRIVER);

}

handle = co_os_manager_open();

if (!handle) {

co_terminal_print("couldn't get driver handle/n");

return CO_RC(ERROR_MONITOR_NOT_LOADED);

}

rc = co_manager_status(handle, &status);

if (!CO_OK(rc)) {

if (verbose)

co_terminal_print("couldn't get driver status (rc %x)/n", rc);

co_os_manager_close(handle);

return rc;

}

if (verbose) {

if (status.state >= CO_MANAGER_STATE_INITIALIZED)

co_terminal_print("current state: %d (fully initialized)/n", status.state);

else

co_terminal_print("current state: %d/n", status.state);

co_terminal_print("current number of monitors: %d/n", status.monitors_count);

co_terminal_print("current linux api version: %d/n", status.linux_api_version);

co_terminal_print("current periphery api version: %d/n", status.periphery_api_version);

}

co_os_manager_close(handle);

return rc;

}

检查管理器有没有安装

E:/MyColinux/src/colinux/os/winnt/user/  manager.c

检查colinux win32的管理器有没有安装,继续调用与操作OS相关的检查函数

static co_rc_t co_win32_manager_is_installed(bool_t *installed)

{

co_rc_t rc;

rc = co_os_manager_is_installed(installed);

if (!CO_OK(rc)) {

if (CO_RC_GET_CODE(rc) == CO_RC_ACCESS_DENIED)

co_terminal_print("access defined, not enough privileges/n");

else

co_terminal_print("error, unable to determine if driver is installed (rc %x)/n", rc);

}

return rc;

}

E:/MyColinux/src/colinux/os/winnt/user/  manager.c

co_rc_t co_os_manager_is_installed(bool_t *installed)

{

return co_winnt_check_driver(CO_DRIVER_NAME, installed);

}

调用winnt的服务管理器

E:/MyColinux/src/colinux/os/winnt/user/  manager.c

调用winnt的服务管理器,看有没有安装

co_rc_t co_winnt_check_driver(IN LPCTSTR DriverName, bool_t *installed) 

SC_HANDLE schService; 

SC_HANDLE schSCManager; 

*installed = PFALSE;

schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

if (schSCManager == NULL) {

DWORD last_error = GetLastError();

if (last_error == ERROR_ACCESS_DENIED)

return CO_RC(ACCESS_DENIED);

return CO_RC(ERROR_ACCESSING_DRIVER); 

}

schService = OpenService(schSCManager, DriverName, SERVICE_ALL_ACCESS); 

if (schService != NULL) {

CloseServiceHandle(schService); 

*installed = PTRUE;

}

CloseServiceHandle(schSCManager);

return CO_RC(OK);

}

安装colinux驱动

E:/MyColinux/src/colinux/os/winnt/user/daemon/driver.c

co_rc_t co_winnt_install_driver(void) 

{

co_rc_t rc;

bool_t installed = PFALSE;

co_manager_handle_t handle;

rc = co_win32_manager_is_installed(&installed);

if (!CO_OK(rc)) {

return rc;

}

if (installed) {

co_terminal_print("driver already installed/n");

return CO_RC(OK);

}

rc = co_winnt_driver_install_lowlevel();

if (!CO_OK(rc)) {

co_terminal_print("cannot install (%x)/n", rc);

return CO_RC(ERROR);

}

handle = co_os_manager_open();

if (handle == NULL) {

co_terminal_print("error opening kernel driver/n");

return CO_RC(ERROR_ACCESSING_DRIVER);

}

return CO_RC(OK);

}

检查是否安装colnux的服务

static co_rc_t co_win32_manager_is_installed(bool_t *installed)

{

co_rc_t rc;

rc = co_os_manager_is_installed(installed);

if (!CO_OK(rc)) {

if (CO_RC_GET_CODE(rc) == CO_RC_ACCESS_DENIED)

co_terminal_print("access defined, not enough privileges/n");

else

co_terminal_print("error, unable to determine if driver is installed (rc %x)/n", rc);

}

return rc;

}

低级安装colinux驱动

co_rc_t co_winnt_driver_install_lowlevel(void)

{

return co_winnt_load_driver_lowlevel_by_name(CO_DRIVER_NAME, 

COLINUX_DRIVER_FILE);

}

通过名字安装,并启动

static co_rc_t co_winnt_load_driver_lowlevel_by_name(char *name, char *path) 

SC_HANDLE   schSCManager; 

char fullpath[0x100] = {0,};

char driverfullpath[0x100] = {0,};

co_rc_t rc;

GetModuleFileName(co_current_win32_instance, fullpath, sizeof(fullpath));

PathRemoveFileSpec(fullpath);

PathCombine(driverfullpath, fullpath, path);

co_terminal_print("loading %s/n", driverfullpath);

schSCManager = OpenSCManager(NULL,                 

// machine (NULL == local) 

     NULL,                 // database (NULL == default) 

     SC_MANAGER_ALL_ACCESS /* access required */ );

rc = co_winnt_install_driver_lowlevel(schSCManager, name, driverfullpath);

if (!CO_OK(rc)) {

CloseServiceHandle(schSCManager);    

return rc;

}

rc = co_winnt_start_driver_lowlevel(schSCManager, name); 

if (!CO_OK(rc)) {

co_winnt_remove_driver_lowlevel(schSCManager, name); 

CloseServiceHandle(schSCManager);    

return rc;

}

#if (0)

rc = co_os_check_device(name); 

if (!CO_OK(rc)) {

co_winnt_stop_driver_lowlevel(schSCManager, name);  

co_winnt_remove_driver_lowlevel(schSCManager, name); 

CloseServiceHandle(schSCManager);    

return rc;

}

#endif

CloseServiceHandle(schSCManager);    

return CO_RC(OK);

}

低级的启动驱动

static co_rc_t co_winnt_start_driver_lowlevel(IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName) 

SC_HANDLE  schService; 

co_rc_t   ret;

DWORD      err; 

    

schService = OpenService(SchSCManager, DriverName, SERVICE_ALL_ACCESS); 

 

if (schService == NULL) { 

return CO_RC(ERROR_ACCESSING_DRIVER); 

 

if (StartService(schService, 0, NULL)) {

ret = CO_RC(OK);

} else {

ret = CO_RC(ERROR_STARTING_DRIVER);

err = GetLastError(); 

#if 1

if (err == ERROR_SERVICE_ALREADY_RUNNING) 

co_terminal_print("failure: StartService, ERROR_SERVICE_ALREADY_RUNNING/n"); 

else 

co_terminal_print("failure: StartService (0x%02x)/n", err);

#endif

 

CloseServiceHandle(schService); 

return ret; 

}

打开管理器

co_manager_handle_t co_os_manager_open(void)

{

return co_os_manager_open_(1);

}

其实就是打开驱动文件

static co_manager_handle_t co_os_manager_open_(int verbose)

{

co_manager_handle_t handle;

handle = co_os_malloc(sizeof(*handle));

if (!handle)

return NULL;

handle->handle = CreateFile(CO_DRIVER_USER_PATH, 

    GENERIC_READ | GENERIC_WRITE, 0, NULL, 

    OPEN_EXISTING, 

    FILE_ATTRIBUTE_NORMAL  | FILE_FLAG_OVERLAPPED, NULL);

if (handle->handle == INVALID_HANDLE_VALUE) {

if (verbose)

co_terminal_print_last_error("colinux: manager open");

co_os_free(handle);

return NULL;

}

return handle;

}

Colinux进程实质的主函数

打开了驱动文件后 运行linux映象

co_rc_t co_winnt_daemon_main(co_start_parameters_t *start_parameters) 

{

co_rc_t rc = CO_RC_OK;

int ret;

if (!start_parameters->config_specified  ||  start_parameters->show_help) {

co_daemon_syntax();

co_winnt_daemon_syntax();

return CO_RC(OK);

}

co_winnt_affinity_workaround();

// Don't get aborted ;)

SetConsoleCtrlHandler( co_winnt_daemon_ctrl_handler, TRUE );

rc = co_daemon_create(start_parameters, &g_daemon);

if (!CO_OK(rc))

goto out;

rc = co_daemon_start_monitor(g_daemon);

if (!CO_OK(rc))

goto out_destroy;

rc = co_daemon_run(g_daemon);

co_daemon_end_monitor(g_daemon);

out_destroy:

co_daemon_destroy(g_daemon);

out:

if (!CO_OK(rc)) {

char buf[0x100];

switch (CO_RC_GET_CODE(rc)) {

case CO_RC_VERSION_MISMATCHED:

strcpy(buf, "error driver version, please reinstall driver!");

break;

case CO_RC_OUT_OF_PAGES:

strcpy(buf, "not enough physical memory available (try with a lower setting)");

break;

case CO_RC_ERROR_ACCESSING_DRIVER:

strcpy(buf, "can't access CoLinuxDriver, please check status driver!");

break;

default:

co_rc_format_error(rc, buf, sizeof(buf));

}

co_terminal_print("daemon: exit code %x/n", rc);

co_terminal_print("daemon: %s/n", buf);

ret = CO_RC(ERROR);

} else {

ret = CO_RC(OK);

}

SetConsoleCtrlHandler( co_winnt_daemon_ctrl_handler, FALSE );

return ret; 

}

创建daemon,分配结构内存

创建daemon主要是分配daemon结构和加载配置文件

co_rc_t co_daemon_create(co_start_parameters_t *start_parameters,

 co_daemon_t **co_daemon_out)

{

co_rc_t rc;

co_daemon_t *daemon;

init_srand();

    //分配内存

daemon = co_os_malloc(sizeof(co_daemon_t));

if (daemon == NULL) {

rc = CO_RC(OUT_OF_MEMORY);

goto out;

}

memset(daemon, 0, sizeof(*daemon));

daemon->start_parameters = start_parameters;

memcpy(daemon->config.config_path, start_parameters->config_path, 

       sizeof(start_parameters->config_path));

rc = co_load_config_file(daemon);

if (!CO_OK(rc)) {

co_debug_error("error loading configuration");

goto out_free;

}

*co_daemon_out = daemon;

return rc;

out_free:

co_os_free(daemon);

out:

return rc;

}

从配置文件读取配置信息

Daemon数据结构

typedef struct co_daemon {

co_id_t id;

co_start_parameters_t *start_parameters; 命令行

co_config_t config; 配置文件

co_elf_data_t *elf_data; 

co_user_monitor_t *monitor;

co_user_monitor_t *message_monitor;

bool_t running;

bool_t idle;

char *buf;

bool_t send_ctrl_alt_del;

co_monitor_user_kernel_shared_t *shared;

bool_t next_reboot_will_shutdown;

} co_daemon_t;

开始监视器-读vmlinux到内存

实际上是读取vmlinux获取ELF的信息,加载执行

co_rc_t co_daemon_start_monitor(co_daemon_t *daemon)

{

co_rc_t rc;

unsigned long size;

co_manager_ioctl_status_t status;

rc = co_os_file_load(daemon->config.vmlinux_path, &daemon->buf, &size, 0);

if (!CO_OK(rc)) {

co_terminal_print("error loading vmlinux file/n");

goto out;

}

rc = co_elf_image_read(&daemon->elf_data, daemon->buf, size);

if (!CO_OK(rc)) {

co_terminal_print("error reading image (%ld bytes)/n", size);

goto out_free_vmlinux; 

}

co_debug("creating monitor");

rc = co_daemon_monitor_create(daemon);

if (!CO_OK(rc)) {

co_debug_error("error initializing");

goto out_free_vmlinux;

}

// Don't start, if API_VERSION mismatch

rc = co_manager_status(daemon->monitor->handle, &status);

if (!CO_OK(rc))

goto out_destroy;

rc = co_elf_image_load(daemon);

if (!CO_OK(rc)) {

co_terminal_print("error loading image/n");

goto out_destroy;

}

return rc;

out_destroy:

co_daemon_monitor_destroy(daemon);

out_free_vmlinux:

co_os_file_free(daemon->buf);

out:

return rc;

}

打开并读取vmlinux到内存

co_rc_t co_os_file_load(co_pathname_t pathname, char **out_buf, unsigned long *out_size, unsigned long max_size)

{

HANDLE handle;

BOOL ret;

unsigned long size, size_read;

co_rc_t rc = CO_RC_OK;

char *buf;

handle = CreateFile(pathname, 

    GENERIC_READ,

    FILE_SHARE_READ,

    NULL,

    OPEN_EXISTING,

    FILE_ATTRIBUTE_NORMAL,

    NULL);

if (handle == INVALID_HANDLE_VALUE) {

co_terminal_print_last_error(pathname);

co_debug_error("Error opening file (%s)", pathname);

rc = CO_RC(ERROR);

goto out;

}

size = GetFileSize(handle, NULL);

if (max_size && size > max_size)

size = max_size;

buf = (char *)malloc(size);

if (buf == NULL)  {

rc = CO_RC(OUT_OF_MEMORY);

goto out2;

}

ret = ReadFile(handle, buf, size, &size_read, NULL);

if (size != size_read) {

co_terminal_print_last_error(pathname);

co_debug_error("Error reading file %s, %lu != %lu",

pathname, size, size_read);

free(buf);

rc = CO_RC(ERROR);

goto out2;

}

*out_buf = buf;

*out_size = size;

out2:

CloseHandle(handle);

out:

return rc;

}

读取vmlinux执行文件ELF

分配ELF结构内存,从上面读回的vmlinux到内存,获取ELF的section头,".strtab",".symtab"

co_rc_t co_elf_image_read(co_elf_data_t **pl_out, void *elf_buf, unsigned long size)

{

co_elf_data_t *pl;

pl = co_os_malloc(sizeof(co_elf_data_t));

if (!pl)

return CO_RC(OUT_OF_MEMORY);

*pl_out = pl;

pl->header = (Elf32_Ehdr *)elf_buf;

pl->buffer = elf_buf;

pl->size = size;

    

pl->section_string_table_section =/

co_get_section_header(pl, pl->header->e_shstrndx);

    

if (pl->section_string_table_section == NULL)

return CO_RC(ERROR);

pl->string_table_section = co_get_section_by_name(pl, ".strtab");

if (pl->string_table_section == NULL)

return CO_RC(ERROR);

pl->symbol_table_section = co_get_section_by_name(pl, ".symtab");

if (pl->symbol_table_section == NULL)

return CO_RC(ERROR);

    

return CO_RC(OK);

}

ELF的数据结构

struct co_elf_data {

/* ELF binary buffer */

unsigned char *buffer;

unsigned long size;

/* Elf header and seconds */

Elf32_Ehdr *header;

Elf32_Shdr *section_string_table_section;

Elf32_Shdr *string_table_section;

Elf32_Shdr *symbol_table_section;

};

监视器创建-加载vmlinux,initrd内核

读vmlinux到symbols_import结构

typedef struct {

unsigned long kernel_start;

unsigned long kernel_end;

unsigned long kernel_init_task_union;

unsigned long kernel_colinux_start;

unsigned long kernel_swapper_pg_dir;

unsigned long kernel_idt_table;

unsigned long kernel_gdt_table;

unsigned long kernel_co_arch_info;

unsigned long kernel_co_info;

} co_symbols_import_t;

加载启动内核符号symboles,放入管理器结构中并传递到驱动让驱动通过

传递进的参数来创建管理器,并返回一个驱动的内核地址

co_rc_t co_daemon_monitor_create(co_daemon_t *daemon)

{

co_manager_ioctl_create_t create_params = {0, }; 与驱动交换的参数

co_symbols_import_t *import;

co_rc_t rc;

import = &create_params.import;

rc = co_daemon_load_symbol(daemon, "_kernel_start", &import->kernel_start);

if (!CO_OK(rc)) 

goto out;

rc = co_daemon_load_symbol(daemon, "_end", &import->kernel_end);

if (!CO_OK(rc)) 

goto out;

rc = co_daemon_load_symbol(daemon, "init_thread_union", &import->kernel_init_task_union);

if (!CO_OK(rc)) {

goto out;

}

rc = co_daemon_load_symbol(daemon, "co_start", &import->kernel_colinux_start);

if (!CO_OK(rc)) 

goto out;

rc = co_daemon_load_symbol(daemon, "swapper_pg_dir", &import->kernel_swapper_pg_dir);

if (!CO_OK(rc)) 

goto out;

rc = co_daemon_load_symbol(daemon, "idt_table", &import->kernel_idt_table);

if (!CO_OK(rc)) 

goto out;

if (co_get_symbol_by_name(daemon->elf_data, "per_cpu__gdt_page"))

// >= 2.6.22

rc = co_daemon_load_symbol(daemon, "per_cpu__gdt_page", &import->kernel_gdt_table);

else

// <= 2.6.17

rc = co_daemon_load_symbol(daemon, "cpu_gdt_table", &import->kernel_gdt_table);

if (!CO_OK(rc))

goto out;

rc = co_daemon_load_symbol_and_data(daemon, "co_info", &import->kernel_co_info,

    &create_params.info, sizeof(create_params.info));

if (!CO_OK(rc)) {

goto out;

}

rc = co_daemon_load_symbol_and_data(daemon, "co_arch_info", &import->kernel_co_arch_info,

    &create_params.arch_info, sizeof(create_params.arch_info));

if (!CO_OK(rc)) {

goto out;

}

if (create_params.info.api_version != CO_LINUX_API_VERSION) {

co_terminal_print("colinux: error, expected kernel API version %d, got %ld/n",

  CO_LINUX_API_VERSION, create_params.info.api_version);

rc = CO_RC(VERSION_MISMATCHED);

goto out;

}

if (create_params.info.compiler_abi != __GXX_ABI_VERSION) {

co_terminal_print("colinux: error, expected gcc abi version %d, got %ld/n",

  __GXX_ABI_VERSION, create_params.info.compiler_abi);

co_terminal_print("colinux: Daemons gcc version %d.%d.x, "

  "incompatible to kernel gcc version %ld.%ld.x/n",

  __GNUC__, __GNUC_MINOR__,

  create_params.info.compiler_major,

  create_params.info.compiler_minor);

rc = CO_RC(COMPILER_MISMATCHED);

goto out;

}

co_daemon_prepare_net_macs(daemon);

create_params.config = daemon->config;

rc = co_user_monitor_create(&daemon->monitor, &create_params);

if (!CO_OK(rc)) {

if (CO_RC_GET_CODE(rc) == CO_RC_HOSTMEM_USE_LIMIT_REACHED) { 

memory_usage_limit_resached(&create_params);

}

goto out;

}

    驱动给内核的共享内存地址

daemon->shared = (co_monitor_user_kernel_shared_t *)create_params.shared_user_address;

if (!daemon->shared)

return CO_RC(ERROR); 

daemon->shared->userspace_msgwait_count = 0;

daemon->id = create_params.id;

    加载内核初始化initrd影像

rc = co_load_initrd(daemon);

out:

return rc;

}

这里使用到一个与驱动交换的创建管理器的结构定义,它会传递到colinux驱动里

typedef struct {

co_rc_t rc;

co_symbols_import_t import;

co_config_t config;

co_info_t info;

co_arch_info_t arch_info;

unsigned long actual_memsize_used;

void *shared_user_address;

co_id_t id;

} co_manager_ioctl_create_t;

通知驱动创建管理器

co_rc_t co_user_monitor_create(co_user_monitor_t **out_mon, co_manager_ioctl_create_t *params)

{

co_manager_handle_t handle;

co_user_monitor_t *mon;

co_rc_t rc;

mon = co_os_malloc(sizeof(*mon));

if (!mon)

return CO_RC(OUT_OF_MEMORY);

memset(mon, 0, sizeof(*mon));

handle = co_os_manager_open();

if (!handle) {

co_os_free(mon);

return CO_RC(ERROR_ACCESSING_DRIVER);

}

rc = co_os_manager_ioctl(handle, CO_MANAGER_IOCTL_CREATE,

 params, sizeof(*params), params, sizeof(*params), NULL);

if (!CO_OK(rc)) {

co_os_free(mon);

co_os_manager_close(handle);

return rc;

}

if (!CO_OK(params->rc)) {

co_os_free(mon);

co_os_manager_close(handle);

return params->rc;

}

mon->handle = handle;

*out_mon = mon;

return CO_RC(OK);

}

加载initrd,将initrd文件打开读取到内存

co_rc_t co_load_initrd(co_daemon_t *daemon)

{

co_rc_t rc;

char *initrd;

unsigned long initrd_size; 

if (!daemon->config.initrd_enabled)

return CO_RC(OK);

co_debug("reading initrd from (%s)", daemon->config.initrd_path);

rc = co_os_file_load(daemon->config.initrd_path, &initrd, &initrd_size, 0);

if (!CO_OK(rc)) {

co_terminal_print("error loading initrd file/n");

return rc;

}

co_debug("initrd size: %ld bytes", initrd_size);

rc = co_user_monitor_load_initrd(daemon->monitor, initrd, initrd_size);

co_os_free(initrd);

return rc;

}

将读initrd的内存传递到windows驱动里,并让驱动去加载

co_rc_t co_user_monitor_load_initrd(co_user_monitor_t *umon, 

    void *initrd, unsigned long initrd_size)

{

co_monitor_ioctl_load_initrd_t *params_copy = NULL;

unsigned long alloc_size = 0;

co_rc_t rc;

alloc_size = sizeof(*params_copy) + initrd_size;

    

params_copy = co_os_malloc(alloc_size);

if (!params_copy)

return CO_RC(OUT_OF_MEMORY);

params_copy->size = initrd_size;

memcpy(params_copy->buf, initrd, initrd_size);

    让驱动加载初始化initrd

rc = co_manager_io_monitor_unisize(umon->handle, 

   CO_MONITOR_IOCTL_LOAD_INITRD, 

   &params_copy->pc, alloc_size);

co_os_free(params_copy);

return rc;

}

加载ELF到windows的内核内存空间

/*

 * Load all ELF sections to host OS kernel memory.

 */

co_rc_t co_elf_image_load(co_daemon_t *daemon)

{

unsigned long index;

unsigned long sections;

co_rc_t rc;

sections = co_get_section_count(daemon->elf_data);

for (index=1; index < sections; index++) {

rc = co_section_load(daemon, index);

if (!CO_OK(rc))

return rc;

}

return CO_RC(OK);

}

加载ELF节到windows内核内存

co_rc_t co_section_load(co_daemon_t *daemon, unsigned long index)

{

Elf32_Shdr *section;

co_monitor_ioctl_load_section_t params;

co_rc_t rc;

section = co_get_section_header(daemon->elf_data, index);

if (section->sh_flags & SHF_ALLOC) {

if (section->sh_type == SHT_NOBITS)

params.user_ptr = NULL;

else

params.user_ptr = co_get_at_offset(daemon->elf_data, section, 0);

params.address = section->sh_addr;

params.size = section->sh_size;

params.index = index;

/*

 * Load each ELF section to kernel space separately.

 */

rc = co_user_monitor_load_section(daemon->monitor, &params);

if (!CO_OK(rc))

return rc;

}

return CO_RC(OK);

}

通过驱动控制将加载的ELF节到驱动内存

co_rc_t co_user_monitor_load_section(co_user_monitor_t *umon, 

     co_monitor_ioctl_load_section_t *params)

{

co_monitor_ioctl_load_section_t *params_copy = NULL;

unsigned long alloc_size = 0;

co_rc_t rc;

alloc_size = sizeof(*params);

if (params->user_ptr) 

alloc_size += params->size;

    

params_copy = co_os_malloc(alloc_size);

if (!params_copy)

return CO_RC(OUT_OF_MEMORY);

*params_copy = *params;

if (params->user_ptr) 

memcpy((unsigned char *)params_copy + sizeof(*params),

       params->user_ptr, params->size);

rc = co_manager_io_monitor_unisize(umon->handle, 

   CO_MONITOR_IOCTL_LOAD_SECTION, 

   &params_copy->pc, alloc_size);

co_os_free(params_copy);

return rc;

}

与驱动IO交互

co_rc_t co_manager_io_monitor_unisize(co_manager_handle_t handle,

      co_monitor_ioctl_op_t op,

      co_manager_ioctl_monitor_t *ioctl,

      unsigned long size)

{

return co_manager_io_monitor(handle, op, ioctl, size, size);

}

驱动的控制包装函数

co_rc_t co_manager_io_monitor(co_manager_handle_t handle, 

       co_monitor_ioctl_op_t op,

       co_manager_ioctl_monitor_t *ioctl,

       unsigned long in_size,

       unsigned long out_size)

{

unsigned long returned = 0;

co_rc_t rc;

ioctl->op = op;

ioctl->rc = CO_RC_OK;

rc = co_os_manager_ioctl(handle, CO_MANAGER_IOCTL_MONITOR,

 ioctl, in_size, ioctl, out_size, &returned);

if (!CO_OK(rc))

return rc;

return ioctl->rc;

}

加载linux进程启动

E:/MyColinux/src/colinux/user/ daemon.c

加载linux进程开始

co_rc_t co_daemon_run(co_daemon_t *daemon)

{

co_rc_t rc;

co_reactor_t reactor;

co_module_t modules[] = {CO_MODULE_PRINTK, };

bool_t restarting = PFALSE;

    //创建反应器

rc = co_reactor_create(&reactor);

if (!CO_OK(rc))

return rc;

co_terminal_print("PID: %d/n", daemon->id);

    //打开监视器

rc = co_user_monitor_open(reactor, message_receive,

  daemon->id, modules, sizeof(modules)/sizeof(co_module_t),

  &daemon->message_monitor);

if (!CO_OK(rc))

goto out;

daemon->message_monitor->reactor_user->private_data = (void *)daemon;

    //启动colinux-console-fltk进程

if (daemon->start_parameters->launch_console) {

co_terminal_print("colinux: launching console/n");

rc = co_launch_process(NULL, "colinux-console-%s -a %d", 

daemon->start_parameters->console, daemon->id);

if (!CO_OK(rc)) {

co_terminal_print("error launching console/n");

goto out;

}

}

rc = co_daemon_launch_net_daemons(daemon);

if (!CO_OK(rc)) {

co_terminal_print("error launching network daemons/n");

goto out;

}

rc = co_daemon_launch_serial_daemons(daemon);

if (!CO_OK(rc))

goto out;

    //启动可执行程序

rc = co_daemon_launch_executes(daemon);

if (!CO_OK(rc))

goto out;

co_terminal_print("colinux: booting/n");

daemon->next_reboot_will_shutdown = PFALSE;

do {

restarting = PFALSE;

rc = co_user_monitor_start(daemon->monitor);

if (!CO_OK(rc))

goto out;

daemon->running = PTRUE;

while (daemon->running) {

co_monitor_ioctl_run_t params;

rc = co_user_monitor_run(daemon->monitor, &params);

if (!CO_OK(rc))

break;

co_reactor_select(reactor, 0);

}

if (CO_RC_GET_CODE(rc) == CO_RC_INSTANCE_TERMINATED) {

co_monitor_ioctl_get_state_t params;

co_termination_reason_t reason;

co_terminal_print("colinux: Linux VM terminated/n");

rc = co_user_monitor_get_state(daemon->monitor, &params);

if (!CO_OK(rc)) {

co_terminal_print("colinux: unable to get reason for termination (bug?), aborting/n");

break;

}

reason = params.termination_reason;

switch (reason) {

case CO_TERMINATE_REBOOT:

if (daemon->next_reboot_will_shutdown) {

co_terminal_print("colinux: shutting down after reboot./n");

break;

}

co_terminal_print("colinux: rebooted./n");

rc = co_daemon_restart(daemon);

if (CO_OK(rc))

restarting = PTRUE;

break;

case CO_TERMINATE_POWEROFF:

co_terminal_print("colinux: powered off, exiting./n");

break;

case CO_TERMINATE_HALT:

co_terminal_print("colinux: halted, exiting./n");

break;

case CO_TERMINATE_BUG:

co_terminal_print("colinux: BUG at %s:%d/n", params.bug_info.file, params.bug_info.line);

break;

default:

co_terminal_print("colinux: terminated with code %d - abnormal exit, aborting/n", reason);

break;

}

}

} while (restarting);

co_daemon_kill_executes(daemon);

co_user_monitor_close(daemon->message_monitor);

out:

co_reactor_destroy(reactor);

return rc;

}

创建反应器reactor

分配reactor结构内存,初始化反应器user

co_rc_t co_reactor_create(co_reactor_t *out_handle)

{

co_reactor_t reactor;

reactor = co_os_malloc(sizeof(*reactor));

if (!reactor)

return CO_RC(OUT_OF_MEMORY);

co_memset(reactor, 0, sizeof(*reactor));

co_list_init(&reactor->users);

*out_handle = reactor;

return CO_RC(OK);

}

打开用户监视器运行内核

分配监视器结构内存,然后打开,连接,reactor和mornitor一起建立

co_rc_t co_user_monitor_open(co_reactor_t reactor, co_reactor_user_receive_func_t receive,

     co_id_t id, co_module_t *modules, int num_modules, 

     co_user_monitor_t **out_mon)

{

co_user_monitor_t *mon;

co_manager_handle_t handle;

co_manager_ioctl_attach_t params;

co_rc_t rc;

int modules_copied = 0;

    //分配一个监视器的结构内存 -->malloc(size);

mon = co_os_malloc(sizeof(*mon));

if (!mon)

return CO_RC(OUT_OF_MEMORY);

memset(mon, 0, sizeof(*mon));

    //打开管理器,其实是打开windows的colinux.sys驱动

handle = co_os_manager_open();

if (!handle) {

co_os_free(mon);

return CO_RC(ERROR_ACCESSING_DRIVER);

}

params.id = id;

for (modules_copied=0; 

     modules_copied < num_modules  &&  modules_copied < CO_MANAGER_ATTACH_MAX_MODULES; 

     modules_copied++) 

{

params.modules[modules_copied] = modules[modules_copied];

}

params.num_modules = num_modules;

    //管理器绑定

rc = co_manager_attach(handle, &params);

if (!CO_OK(rc)) {

co_os_manager_close(handle);

co_os_free(mon);

return rc;

}

rc = co_os_reactor_monitor_create(

reactor, handle,

receive, &mon->reactor_user);

if (!CO_OK(rc)) {

co_os_manager_close(handle);

co_os_free(mon);

return rc;

}

mon->monitor_id = id;

mon->handle = handle;

*out_mon = mon;

return rc;

}

[选择]启动网络daemon

遍历有所有配置的网卡,判断网卡模式类型,形式创建进程的参数然后创建进程

co_rc_t co_daemon_launch_net_daemons(co_daemon_t *daemon)

{

int i;

co_rc_t rc;

for (i=0; i < CO_MODULE_MAX_CONET; i++) { 

co_netdev_desc_t *net_dev;

char interface_name[CO_NETDEV_DESC_STR_SIZE + 0x10] = {0, };

net_dev = &daemon->config.net_devs[i];

if (net_dev->enabled == PFALSE)

continue;

co_debug("launching daemon for conet%d", i);

if (*net_dev->desc != 0)

co_snprintf(interface_name, sizeof(interface_name), "-n /"%s/"", net_dev->desc);

switch (net_dev->type) 

{

case CO_NETDEV_TYPE_BRIDGED_PCAP: {

char mac_address[18];

            建立mac地址

co_build_mac_address(mac_address, sizeof(mac_address), net_dev->mac_address);

rc = co_launch_process(NULL, "colinux-bridged-net-daemon -i %d -u %d %s -mac %s -p %d",

daemon->id, i, interface_name, mac_address, net_dev->promisc_mode);

break;

}

case CO_NETDEV_TYPE_TAP: {

rc = co_launch_process(NULL, "colinux-net-daemon -i %d -u %d %s", daemon->id, i, interface_name);

break;

}

case CO_NETDEV_TYPE_SLIRP: {

rc = co_launch_process(NULL, "colinux-slirp-net-daemon -i %d -u %d%s%s",

daemon->id, i, (*net_dev->redir)?" -r ":"", net_dev->redir);

break;

}

default:

rc = CO_RC(ERROR);

break;

}

if (!CO_OK(rc))

co_terminal_print("WARNING: error launching network daemon!/n");

}

return CO_RC(OK);

}

创建启动进程

就是调用window的createprocess函数根基参数创建进程

co_rc_t co_launch_process(int *pid, char *command_line, ...)

{

BOOL ret;

char buf[0x200];

va_list ap;

STARTUPINFO si;

PROCESS_INFORMATION pi;

memset(&si, 0, sizeof(si));

si.cb = sizeof(si);

memset(π, 0, sizeof(pi));

va_start(ap, command_line);

vsnprintf(buf, sizeof(buf), command_line, ap);

va_end(ap);

co_debug("executing: %s", buf);

    //Window下的创建进程函数

ret = CreateProcess(NULL,

    buf,              // Command line. 

    NULL,             // Process handle not inheritable. 

    NULL,             // Thread handle not inheritable. 

    FALSE,            // Set handle inheritance to FALSE. 

    0,                // No creation flags. 

    NULL,             // Use parent's environment block. 

    NULL,             // Use parent's starting directory. 

    &si,              // Pointer to STARTUPINFO structure.

    π);             // Pointer to PROCESS_INFORMATION structure.

if (!ret) {

co_terminal_print("error 0x%lx in execution/n", GetLastError());

return CO_RC(ERROR);

}

if (pid)

*pid = pi.dwProcessId;

CloseHandle(pi.hProcess);

CloseHandle(pi.hThread);

return CO_RC(OK);

}

启动可执行程序

static co_rc_t co_daemon_launch_executes(co_daemon_t *daemon)

{

int i;

co_rc_t rc;

co_execute_desc_t *execute;

for (i = 0, execute = daemon->config.executes; i < CO_MODULE_MAX_EXECUTE; i++, execute++) {

if (execute->enabled == PFALSE)

continue;

co_debug("launching exec%d", i);

rc = co_launch_process(&execute->pid,

(execute->args) ? "%s %s" : "%s",

execute->prog, execute->args);

if (!CO_OK(rc))

co_terminal_print("WARNING: error launching exec%d '%s'!/n", i, execute->prog);

}

return CO_RC(OK);

}

用户监视开始-vmlinux开始

co_rc_t co_user_monitor_start(co_user_monitor_t *umon)

{

return co_manager_io_monitor_simple(umon->handle,  CO_MONITOR_IOCTL_START);

}

用户监视开始-vmlinux运行

co_rc_t co_user_monitor_run(co_user_monitor_t *umon, co_monitor_ioctl_run_t *params)

{

return co_manager_io_monitor(umon->handle,

     CO_MONITOR_IOCTL_RUN, &params->pc,

     sizeof(*params), sizeof(*params));

}

驱动中的启动

static co_rc_t start(co_monitor_t *cmon)

{

co_rc_t rc;

co_boot_params_t *params;

if (cmon->state != CO_MONITOR_STATE_INITIALIZED) {

co_debug_error("invalid state");

return CO_RC(ERROR);

}

rc = guest_address_space_init(cmon);

if (!CO_OK(rc)) {

co_debug_error("error %08x initializing coLinux context", (int)rc);

return rc;

}

co_os_get_timestamp_freq(&cmon->timestamp, &cmon->timestamp_freq);

co_os_timer_activate(cmon->timer);

co_passage_page->operation = CO_OPERATION_START;

params = (co_boot_params_t *)co_passage_page->params;

params->co_core_end = cmon->core_end;

params->co_memory_size = cmon->memory_size;

params->co_initrd  = (void *)cmon->initrd_address;

params->co_initrd_size = cmon->initrd_size;

params->co_cpu_khz = co_os_get_cpu_khz();

co_memcpy(&params->co_boot_parameters,

cmon->config.boot_parameters_line,

sizeof(cmon->config.boot_parameters_line));

cmon->state = CO_MONITOR_STATE_STARTED;

return CO_RC(OK);

}

驱动中的运行

static co_rc_t run(co_monitor_t *cmon,

   co_monitor_ioctl_run_t *params,

   unsigned long out_size,

   unsigned long *return_size)

{

*return_size = sizeof(*params);

if (cmon->state == CO_MONITOR_STATE_RUNNING) {

bool_t ret;

do {

ret = iteration(cmon);

} while (ret);

return CO_RC(OK);

} else if (cmon->state == CO_MONITOR_STATE_STARTED) {

cmon->state = CO_MONITOR_STATE_RUNNING;

iteration(cmon);

return CO_RC(OK);

}

if (cmon->state == CO_MONITOR_STATE_TERMINATED)

return CO_RC(INSTANCE_TERMINATED);

return CO_RC(ERROR);

}

驱动中IDLE函数,等待中睡眠

static bool_t co_idle(co_monitor_t *cmon)

{

bool_t next_iter = PTRUE;

co_queue_t *queue;

co_os_wait_sleep(cmon->idle_wait);

queue = &cmon->linux_message_queue;

if (co_queue_size(queue) == 0)

next_iter = PFALSE;

return next_iter;

}

等待驱动中的内核事件

void co_os_wait_sleep(co_os_wait_t wait)

{

NTSTATUS status;

status = KeWaitForSingleObject(&wait->event, UserRequest, UserMode, TRUE, NULL);

}

唤醒等待内核事件

void co_os_wait_wakeup(co_os_wait_t wait)

{

KeSetEvent(&wait->event, 1, PFALSE);

}

唤醒事件由内核定时器

static void timer_callback(void *data)

{

    co_monitor_t *cmon = (co_monitor_t *)data;

    cmon->timer_interrupt = PTRUE;

   co_os_wait_wakeup(cmon->idle_wait);

}

Colinux的windows驱动包装类

E:/coLinux-0.7.2/src/colinux/os/winnt/user/Manager.c

打开驱动colinux.sys

其实是简单调用windows打开文件操作

co_manager_handle_t co_os_manager_open(void)

{

return co_os_manager_open_(1);

}

static co_manager_handle_t co_os_manager_open_(int verbose)

{

co_manager_handle_t handle;

handle = co_os_malloc(sizeof(*handle));

if (!handle)

return NULL;

handle->handle = CreateFile(CO_DRIVER_USER_PATH, 

    GENERIC_READ | GENERIC_WRITE, 0, NULL, 

    OPEN_EXISTING, 

    FILE_ATTRIBUTE_NORMAL  | FILE_FLAG_OVERLAPPED, NULL);

if (handle->handle == INVALID_HANDLE_VALUE) {

if (verbose)

co_terminal_print_last_error("colinux: manager open");

co_os_free(handle);

return NULL;

}

return handle;

}

关闭驱动colinux.sys

void co_os_manager_close(co_manager_handle_t handle)

{

CloseHandle(handle->handle);

co_os_free(handle);

}

驱动控制

简单包装了windows的DeviceIoctrl函数

co_rc_t co_os_manager_ioctl(

co_manager_handle_t kernel_device,

unsigned long code,

void *input_buffer,

unsigned long input_buffer_size,

void *output_buffer,

unsigned long output_buffer_size,

unsigned long *output_returned)

{

DWORD   BytesReturned = 0;

BOOL    rc;

if (output_returned == NULL)

output_returned = &BytesReturned;

code = CO_WINNT_IOCTL(code);

rc = DeviceIoControl(kernel_device->handle, code,

     input_buffer, input_buffer_size, 

     output_buffer, output_buffer_size, 

     output_returned, NULL);

if (rc == FALSE) {

return CO_RC(ERROR);

}

return CO_RC(OK);

}

检查驱动

通过windows的服务管理函数打开,判断返回的句柄时候有效,并试图启动驱动服务

co_rc_t co_winnt_check_driver(IN LPCTSTR DriverName, bool_t *installed) 

SC_HANDLE schService; 

SC_HANDLE schSCManager; 

*installed = PFALSE;

schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

if (schSCManager == NULL) {

DWORD last_error = GetLastError();

if (last_error == ERROR_ACCESS_DENIED)

return CO_RC(ACCESS_DENIED);

return CO_RC(ERROR_ACCESSING_DRIVER); 

}

schService = OpenService(schSCManager, DriverName, SERVICE_ALL_ACCESS); 

if (schService != NULL) {

CloseServiceHandle(schService); 

*installed = PTRUE;

}

CloseServiceHandle(schSCManager);

return CO_RC(OK);

}

驱动控制命令

typedef enum {

CO_MANAGER_IOCTL_BASE=0x10,

CO_MANAGER_IOCTL_CREATE,

CO_MANAGER_IOCTL_MONITOR,

CO_MANAGER_IOCTL_STATUS,

CO_MANAGER_IOCTL_DEBUG,

CO_MANAGER_IOCTL_DEBUG_READER,

CO_MANAGER_IOCTL_DEBUG_LEVELS,

CO_MANAGER_IOCTL_INFO,

CO_MANAGER_IOCTL_ATTACH,

CO_MANAGER_IOCTL_MONITOR_LIST,

} co_manager_ioctl_t;

typedef enum {

CO_MONITOR_IOCTL_CLOSE,

CO_MONITOR_IOCTL_LOAD_SECTION, 

CO_MONITOR_IOCTL_START,

CO_MONITOR_IOCTL_RUN,

CO_MONITOR_IOCTL_STATUS,

CO_MONITOR_IOCTL_LOAD_INITRD, 

CO_MONITOR_IOCTL_GET_CONSOLE,

CO_MONITOR_IOCTL_GET_STATE,

CO_MONITOR_IOCTL_RESET,

} co_monitor_ioctl_op_t;

Windows驱动的监视器控制

E:/coLinux-0.7.2/src/colinux/kernel/monitor.c

co_rc_t co_monitor_ioctl(co_monitor_t *cmon, co_manager_ioctl_monitor_t *io_buffer,

 unsigned long in_size, unsigned long out_size, 

 unsigned long *return_size, co_manager_open_desc_t opened_manager)

{

co_rc_t rc = CO_RC_ERROR;

switch (io_buffer->op) {

case CO_MONITOR_IOCTL_CLOSE: {

co_monitor_refdown(cmon, PTRUE, opened_manager->monitor_owner);

opened_manager->monitor = NULL;

opened_manager->monitor_owner = PFALSE;

return CO_RC_OK;

}

case CO_MONITOR_IOCTL_GET_CONSOLE: {

co_monitor_ioctl_get_console_t *params;

*return_size = sizeof(*params);

params = (typeof(params))(io_buffer);

return co_monitor_user_get_console(cmon, params);

}

default:

break;

}

if (!opened_manager->monitor_owner)

return rc;

switch (io_buffer->op) {

case CO_MONITOR_IOCTL_GET_STATE: {

co_monitor_ioctl_get_state_t *params;

*return_size = sizeof(*params);

params = (typeof(params))(io_buffer);

return co_monitor_user_get_state(cmon, params);

}

case CO_MONITOR_IOCTL_RESET: {

return co_monitor_user_reset(cmon);

}

case CO_MONITOR_IOCTL_LOAD_SECTION: {

return load_section(cmon, (co_monitor_ioctl_load_section_t *)io_buffer);

}

case CO_MONITOR_IOCTL_LOAD_INITRD: {

return load_initrd(cmon, (co_monitor_ioctl_load_initrd_t *)io_buffer);

}

case CO_MONITOR_IOCTL_START: {

return start(cmon);

}

case CO_MONITOR_IOCTL_RUN: {

return run(cmon, (co_monitor_ioctl_run_t *)io_buffer, out_size, return_size);

}

default:

return rc;

}

return rc;

}

驱动的控制

static NTSTATUS manager_dispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)

{

PIO_STACK_LOCATION  irpStack;

PVOID               ioBuffer;

ULONG               inputBufferLength;

ULONG               outputBufferLength;

ULONG               ioControlCode;

NTSTATUS            ntStatus = STATUS_SUCCESS;

co_manager_t        *manager;

co_rc_t             rc;

co_manager_ioctl_t  ioctl;

co_manager_open_desc_t opened = NULL;

Irp->IoStatus.Status = ntStatus;

Irp->IoStatus.Information = 0;

irpStack = IoGetCurrentIrpStackLocation(Irp);

manager = (co_manager_t *)DeviceObject->DeviceExtension;

if (!manager) {

ntStatus = STATUS_NO_SUCH_DEVICE;

goto complete;

}

......

ioctl = (co_manager_ioctl_t)(CO_GET_IOCTL_METHOD(ioControlCode));

co_manager_ioctl(manager, ioctl, ioBuffer用户到内核的内存缓冲

 inputBufferLength,

 outputBufferLength,

 &Irp->IoStatus.Information,

 opened);

/* Intrinsic Success / Failure indictation is returned per ioctl. */

ntStatus = STATUS_SUCCESS;

break;

}

}

complete:

Irp->IoStatus.Status = ntStatus;

IoCompleteRequest(Irp, IO_NO_INCREMENT);

return ntStatus;

}

涉及的管理器打开控制描述结构

typedef struct co_manager_open_desc {

co_list_t node;

bool_t active;

int ref_count;

co_os_mutex_t lock;

bool_t monitor_owner;

struct co_monitor *monitor; 监视器成员

co_queue_t out_queue;

co_manager_open_desc_os_t os;

co_debug_section_t *debug_section;

} *co_manager_open_desc_t;

co_rc_t co_manager_ioctl(co_manager_t *manager, unsigned long ioctl, 

 void *io_buffer, unsigned long in_size,

 unsigned long out_size, unsigned long *return_size,

 co_manager_open_desc_t opened)

{

co_rc_t rc = CO_RC_OK;

co_monitor_t *cmon = NULL;

*return_size = 0;

    .........

case CO_MANAGER_IOCTL_MONITOR: {

co_manager_ioctl_monitor_t *params = (typeof(params))(io_buffer);

*return_size = sizeof(*params);

if (in_size < sizeof(*params)) {

co_debug_error("monitor ioctl too small! (%ld < %d)", in_size, sizeof(*params));

params->rc = CO_RC(MONITOR_NOT_LOADED);

break;

}

if (!opened->monitor) {

params->rc = CO_RC(MONITOR_NOT_LOADED);

break;

}

in_size -= sizeof(*params);

params->rc = co_monitor_ioctl(opened->monitor, params, in_size, 

      out_size, return_size, opened);

break;

}

default:

return CO_RC(ERROR);

}

return CO_RC(OK);

}

涉及的管理器打开控制描述结构

typedef struct co_manager_open_desc {

co_list_t node;

bool_t active;

int ref_count;

co_os_mutex_t lock;

bool_t monitor_owner;

struct co_monitor *monitor; 监视器成员

co_queue_t out_queue;

co_manager_open_desc_os_t os;

co_debug_section_t *debug_section;

} *co_manager_open_desc_t;

co_rc_t co_monitor_ioctl(co_monitor_t *cmon, co_manager_ioctl_monitor_t *io_buffer,

 unsigned long in_size, unsigned long out_size, 

 unsigned long *return_size, co_manager_open_desc_t opened_manager)

{

co_rc_t rc = CO_RC_ERROR;

switch (io_buffer->op) {

case CO_MONITOR_IOCTL_CLOSE: {

co_monitor_refdown(cmon, PTRUE, opened_manager->monitor_owner);

opened_manager->monitor = NULL;

opened_manager->monitor_owner = PFALSE;

return CO_RC_OK;

}

case CO_MONITOR_IOCTL_GET_CONSOLE: {

co_monitor_ioctl_get_console_t *params;

*return_size = sizeof(*params);

params = (typeof(params))(io_buffer);

return co_monitor_user_get_console(cmon, params);

}

default:

break;

}

if (!opened_manager->monitor_owner)

return rc;

switch (io_buffer->op) {

case CO_MONITOR_IOCTL_GET_STATE: {

co_monitor_ioctl_get_state_t *params;

*return_size = sizeof(*params);

params = (typeof(params))(io_buffer);

return co_monitor_user_get_state(cmon, params);

}

case CO_MONITOR_IOCTL_RESET: {

return co_monitor_user_reset(cmon);

}

    用户空间传入内存缓冲转换成结构

case CO_MONITOR_IOCTL_LOAD_SECTION: {

return load_section(cmon, (co_monitor_ioctl_load_section_t *)io_buffer);

}

case CO_MONITOR_IOCTL_LOAD_INITRD: {

return load_initrd(cmon, (co_monitor_ioctl_load_initrd_t *)io_buffer);

}

case CO_MONITOR_IOCTL_START: {

return start(cmon);

}

case CO_MONITOR_IOCTL_RUN: {

return run(cmon, (co_monitor_ioctl_run_t *)io_buffer, out_size, return_size);

}

default:

return rc;

}

return rc;

}

typedef struct {

co_manager_ioctl_monitor_t pc;

char *user_ptr;

unsigned long address;

unsigned long size;

unsigned long index;

unsigned char buf[0];

} co_monitor_ioctl_load_section_t;

用户空间的加载vmlinux的各个节section函数

co_rc_t co_section_load(co_daemon_t *daemon, unsigned long index)

{

Elf32_Shdr *section;

co_monitor_ioctl_load_section_t params;

co_rc_t rc;

section = co_get_section_header(daemon->elf_data, index);

if (section->sh_flags & SHF_ALLOC) {

if (section->sh_type == SHT_NOBITS)

params.user_ptr = NULL;

else

params.user_ptr = co_get_at_offset(daemon->elf_data, section, 0);

params.address = section->sh_addr; 地址

params.size = section->sh_size; 

params.index = index;

/*

 * Load each ELF section to kernel space separately.

 */

rc = co_user_monitor_load_section(daemon->monitor, &params);

if (!CO_OK(rc))

return rc;

}

return CO_RC(OK);

}

驱动加载vmlinux的各个节的函数

static co_rc_t load_section(co_monitor_t *cmon, co_monitor_ioctl_load_section_t *params)

{

co_rc_t rc = CO_RC(OK);

if (cmon->state != CO_MONITOR_STATE_INITIALIZED)

return CO_RC(ERROR);

if (params->user_ptr) {

co_debug("loading section at 0x%lx (0x%lx bytes)", params->address, params->size);

rc = co_monitor_copy_region(cmon, params->address, params->size, params->buf);

} else {

rc = co_monitor_copy_region(cmon, params->address, params->size, NULL);

}

return rc;

}

监视器的结构

typedef struct co_monitor {

/*

 * Pointer back to the manager.

 */

struct co_manager *manager; 

int refcount;

bool_t listed_in_manager;

co_list_t node;

co_id_t id;

/*

 * OS-dependant data:

 */

struct co_monitor_osdep *osdep; 

/*

 * State of monitor.

 */ 

co_monitor_state_t state;

co_termination_reason_t termination_reason;

co_monitor_linux_bug_invocation_t bug_info;

/*

 * Configuration data.

 */

co_config_t config;

 

/*

 * The passage page

 */

struct co_arch_passage_page *passage_page;  /* The virtual address of the 

       PP in the host */

vm_ptr_t passage_page_vaddr;                /* The virtual address of the 

       PP in Linux */

struct co_archdep_monitor *archdep;         /* Architecture dependent data */

/*

 * Core stuff (Linux kernel image) 

 */

vm_ptr_t core_vaddr;             /* Where the core sits (the famous C0100000) */

vm_ptr_t core_end;               /* Where the core ends */

unsigned long core_pages;        /* number of pages our core takes */    

co_symbols_import_t import;      /* Addresse of symbols in the kernel */

/*

 * Pseudo physical RAM

 */

unsigned long memory_size;      /* The size of Linux's pseudo physical RAM */

unsigned long physical_frames;  /* The number of pages in that RAM */

unsigned long end_physical;     /* In what virtual address the map of the 

   pseudo physical RAM ends */

co_pfn_t **pp_pfns;

/* 

 * Dynamic allocations in the host

 */

unsigned long blocks_allocated;

/*

 * Page global directory

 */

linux_pgd_t pgd;             /* Pointer to the physical address PGD of 

Linux (to be put in CR3 eventually */

co_pfn_t **pgd_pfns;

/*

 * Devices

 */

co_monitor_device_t devices[CO_DEVICES_TOTAL];

bool_t timer_interrupt;

        /*

         * Timer

         */

        co_os_timer_t timer;

co_timestamp_t timestamp;

co_timestamp_t timestamp_freq;

unsigned long long timestamp_reminder;

co_os_wait_t idle_wait;

/* 

 * Block devices

 */

struct co_block_dev *block_devs[CO_MODULE_MAX_COBD];

/*

 * File Systems

 */

struct co_filesystem *filesystems[CO_MODULE_MAX_COFS];

/*

 * Message passing stuff

 */ 

co_queue_t linux_message_queue;

co_os_mutex_t linux_message_queue_mutex;

co_io_buffer_t *io_buffer;

co_monitor_user_kernel_shared_t *shared;

void *shared_user_address;

void *shared_handle;

struct co_manager_open_desc *connected_modules[CO_MONITOR_MODULES_COUNT];

co_os_mutex_t connected_modules_write_lock;

co_console_t *console;

        /*

 * initrd

 */

unsigned long initrd_address;

unsigned long initrd_size;

/*

 * Structures copied directly from the vmlinux file before it

 * is loaded in order to get kernel-specific info (such as 

 * segment registers) and API version.

 */

co_info_t info;

co_arch_info_t arch_info;

} co_monitor_t;

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值