实习笔记一----Mac os 和ios内核学习笔记(mach exception相关)

实习笔记一—-学习Mac OS内核中对mach端口相关知识进行的整理总结


Mach是mac os运行在xnu内核的一个模块,包括了IPC,虚拟内存,调度器等组件。Mach层可以被视为内核的核心,将低层次的服务呈现给更高层次的组件,例如BSD层和I/O Kit等。Mach负责对硬件层进行抽象,抹去PowerPC架构和Inter X86或者Intel X86-64架构的差异,包括处理traps和中断,以及内存管理。这套设计使得内核可以很容易地被移植到新的硬件上,例如iOS的ARM处理器。

Mach的异常处理是在Mach IPC模块下的。Mach的IPC实现了server/client通过端口的通信,单个端口是单向的,因此双向通信需要两个端口。

异常是CPU在特定事件下发送的特定中断信号,会导致线程执行的中断,而操作系统(Mach)会处理这个异常。在中断后,任务或许仍然可以继续执行,这取决于异常的类型。通常导致异常的原因包括试图获取不存在的内存,执行错误的的CPU命令,传递错误的参数,或者以0为除数。这些异常会导致线程的中断,不过也有些异常不会导致错误(例如调试程序时打的断点)。

当异常发生时,内核将会挂起导致异常的线程,并对线程的异常处理端口发送一条IPC消息。如果线程不能处理异常,那么消息会被转发给此task的异常处理端口,最终会发送至系统的异常端口。下面的结构体可以包括线程,task,或者操作系统的异常端口。

struct exception_action {
    struct ipc_port* port;           /* exception port */
    thread_stsate_flavor_t flavor;   /* state flavor to send */
    exception_behaviour_t behavior;  /* exception type to raise */
    boolean_t privileged;            /* survives ipc_task_reset */
};

每个线程,task,以及操作系统拥有一个数组的结构体exception_action,明确了异常的行为,一个结构体被定义为一种异常类型。flavor和behaviour字段明确了将要发送的异常信息中的类型信息,例如某些状态,特定的CPU寄存器,或者将要执行的处理句柄。句柄可以是catch_mach_exception_raise,catch_mach_exception_raise_state,或者catch_mach_exception_raise_state_identify.当异常被发送出去后,内核将会等待回复以决定接下来的行为。如果返回KERN_SUCCESS意味着异常被处理,线程被允许继续执行。

一个线程的异常端口默认为PORT_NULL,除非被显式地分配。父进程fork出的子进程会继承父进程的异常端口。Unix的信号机制事实上就是基于Mach异常机制实现的。

最后,mac下获取某个进程的内存地址的命令是vmmap,输入参数是pid。