@@ -23,34 +23,34 @@ ChCore的IPC接口不是传统的send/recv接口。其更像客户端/服务器
2323
2424为了实现ChCore IPC的功能,首先需要在Client与Server端创建起一个一对一的IPC Connection。该Connection保存了IPC Server的服务线程(即上图中IPC handler Thread)、Client与Server的共享内存(用于存放IPC通信的内容)。同一时刻,一个Connection只能有一个Client接入,并使用该Connection切换到Server的处理流程。ChCore提供了一系列机制,用于创建Connection以及创建每个Connection对应的服务线程。下面将以具体的IPC注册到调用的流程,详细介绍ChCore的IPC机制:
2525
26- 1 . IPC服务器的主线程调用: ` ipc_register_server ` (` user/chcore-libc /musl-libc/src/chcore-port/ipc.c` 中)来声明自己为IPC的服务器端。
26+ 1 . IPC服务器的主线程调用: ` ipc_register_server ` (` ../Thirdparty /musl-libc/src/chcore-port/ipc.c` 中)来声明自己为IPC的服务器端。
2727
2828 * 参数包括server_handler和client_register_handler,其中server_handler为服务端用于提供服务的回调函数(比如上图中IPC handler Thread的入口函数` ipc_dispatcher ` );client_register_handler为服务端提供的用于注册的回调函数,该函数会创建一个注册回调线程。
2929
3030 * 随后调用ChCore提供的的系统调用:` sys_register_server ` 。该系统调用实现在` kernel/ipc/connection.c ` 当中,该系统调用会分配并初始化一个` struct ipc_server_config ` 和一个` struct ipc_server_register_cb_config ` 。之后将调用者线程(即主线程)的general_ipc_config字段设置为创建的` struct ipc_server_config ` ,其中记录了注册回调线程和IPC服务线程的入口函数(即图中的` ipc_dispatcher ` )。将注册回调线程的general_ipc_config字段设置为创建的` struct ipc_server_register_cb_config ` ,其中记录了注册回调线程的入口函数和用户态栈地址等信息。
3131
32- 2 . IPC客户端线程调用` ipc_register_client ` (定义在` user/chcore-libc /musl-libc/src/chcore-port/ipc.c` 中)来申请建立IPC连接。
32+ 2 . IPC客户端线程调用` ipc_register_client ` (定义在` ../Thirdparty /musl-libc/src/chcore-port/ipc.c` 中)来申请建立IPC连接。
3333
3434 * 该函数仅有一个参数,即IPC服务器的主线程在客户端进程cap_group中的capability。该函数会首先通过系统调用申请一块物理内存作为和服务器的共享内存(即图中的Shared Memory)。
3535
3636 * 随后调用` sys_register_client ` 系统调用。该系统调用实现在` kernel/ipc/connection.c ` 当中,该系统调用会将刚才申请的物理内存映射到客户端的虚拟地址空间中,然后调用` create_connection ` 创建并初始化一个` struct ipc_connection ` 类型的内核对象,该内核对象中的shm字段会记录共享内存相关的信息(包括大小,分别在客户端进程和服务器进程当中的虚拟地址和capability)。
3737
3838 * 之后会设置注册回调线程的栈地址、入口地址和第一个参数,并切换到注册回调线程运行。
39- 3 . 注册回调线程运行的入口函数为主线程调用` ipc_register_server ` 是提供的client_register_handler参数,一般会使用默认的` DEFAULT_CLIENT_REGISTER_HANDLER ` 宏定义的入口函数,即定义在` user/chcore-libc /musl-libc/src/chcore-port/ipc.c` 中的` register_cb ` 。
39+ 3 . 注册回调线程运行的入口函数为主线程调用` ipc_register_server ` 是提供的client_register_handler参数,一般会使用默认的` DEFAULT_CLIENT_REGISTER_HANDLER ` 宏定义的入口函数,即定义在` ../Thirdparty /musl-libc/src/chcore-port/ipc.c` 中的` register_cb ` 。
4040
4141 * 该函数首先分配一个用来映射共享内存的虚拟地址,随后创建一个服务线程。
4242
4343 * 随后调用` sys_ipc_register_cb_return ` 系统调用进入内核,该系统调用将共享内存映射到刚才分配的虚拟地址上,补全` struct ipc_connection ` 内核对象中的一些元数据之后切换回客户端线程继续运行,客户端线程从` ipc_register_client ` 返回,完成IPC建立连接的过程。
4444
45- 4 . IPC客户端线程调用` ipc_create_msg ` 和` ipc_set_msg_data ` 向IPC共享内存中填充数据,然后调用` ipc_call ` (` user/chcore-libc /musl-libc/src/chcore-port/ipc.c` 中)发起IPC请求。
45+ 4 . IPC客户端线程调用` ipc_create_msg ` 和` ipc_set_msg_data ` 向IPC共享内存中填充数据,然后调用` ipc_call ` (` ../Thirdparty /musl-libc/src/chcore-port/ipc.c` 中)发起IPC请求。
4646
4747 * ` ipc_call ` 中会发起` sys_ipc_call ` 系统调用(定义在` kernel/ipc/connection.c ` 中),该系统调用将设置服务器端的服务线程的栈地址、入口地址、各个参数,然后迁移到该服务器端服务线程继续运行。由于当前的客户端线程需要等待服务器端的服务线程处理完毕,因此需要更新其状态为TS_WAITING,且不要加入等待队列。
4848
49495 . IPC服务器端的服务线程在处理完IPC请求之后使用` ipc_return ` 返回。
5050 * ` ipc_return ` 会发起` sys_ipc_return ` 系统调用,该系统调用会迁移回到IPC客户端线程继续运行,IPC客户端线程从` ipc_call ` 中返回。
5151
5252> [ !CODING] 练习题 7
53- > 在` user/chcore-libc /musl-libc/src/chcore-port/ipc.c与kernel/ipc/connection.c` 中实现了大多数IPC相关的代码,请根据注释补全` kernel/ipc/connection.c ` 中的代码。之后运行ChCore可以看到 “[ TEST] Test IPC finished!” 输出,你可以通过 Test IPC 测试点。
53+ > 在` ../Thirdparty /musl-libc/src/chcore-port/ipc.c与kernel/ipc/connection.c` 中实现了大多数IPC相关的代码,请根据注释补全` kernel/ipc/connection.c ` 中的代码。之后运行ChCore可以看到 “[ TEST] Test IPC finished!” 输出,你可以通过 Test IPC 测试点。
5454
5555> [ !WARNING]
5656> 由于用户文件系统管理器(FSM) 与 服务管理器 (Procmgr) 需要通过IPC来进行数据传输,故如果IPC链路实现错误则无法运行` test_ipc.bin ` 以及` Chcore_Shell `
0 commit comments