Colinux
目录
监视器创建-加载vmlinux内核到symbols_import结构内存 21
操作系统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,
¶ms_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, ¶ms);
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,
¶ms_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, ¶ms);
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, ¶ms);
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, ¶ms);
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, ¶ms->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(¶ms->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, ¶ms);
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;