Magenta源代码笔记(4) —— Dispatcher(以进程为例)

来源:互联网 发布:178刷微店软件安全吗 编辑:程序博客网 时间:2024/05/18 07:13

在继续往下分析代码之前首先要引入一个Magenta内核中的概念Dispatcher。

而Dispatcher这个与Magenta内核提供的系统调用有着十分紧密的联系,所以顺便把系统调用实现的方法也分析下。

相对于lk内核,Dispatcher是Magenta中新增加的部分,它的目的在我的理解中是为了更好的管理内核对象。

Magenta在用户态提供的是句柄的操作方式,这样使在用户态中通过间接方式操作内核对象。

而Magenta中的Dispatcher便是与提供给用户态的句柄相对应的一个管理结构。

Dispatcher具有引用计数的功能,可以更好地管理内核对象,而且通过系统调用进入内核态之后第一个调用的便是Dispatcher对象。


Magenta内核中进程的实现便是以Dispatcher为基础,以下分析进程的实现。

Dispatcher相关的代码全部位于目录kernel/lib/magenta目录中。

kernel/lib/magenta/include/magenta/dispatcher.h

// Dispatcher父类class Dispatcher : public utils::RefCounted<Dispatcher> {public:    Dispatcher();    virtual ~Dispatcher() {}    mx_koid_t get_koid() const { return koid_; }    // 增加引用计数    void add_handle();    // 减少引用计数    void remove_handle();    virtual mx_obj_type_t GetType() const = 0;    // 引用为0时的回调接口    virtual void on_zero_handles() { }    virtual mx_koid_t get_inner_koid() const {        return 0ULL;    }    // Note that |set_mask| and |clear_mask| are *not* previously validated. Also note that they may    // "overlap", and that |clear_mask| should be cleared and then |set_mask| set.    virtual status_t UserSignal(uint32_t clear_mask, uint32_t set_mask) {        return ERR_NOT_SUPPORTED;    }    // 以下为各子类对应实现的接口    virtual StateTracker* get_state_tracker() {        return nullptr;    }    virtual InterruptDispatcher* get_interrupt_dispatcher() {        return nullptr;    }    virtual MessagePipeDispatcher* get_message_pipe_dispatcher() {        return nullptr;    }    virtual ProcessDispatcher* get_process_dispatcher() {        return nullptr;    }    virtual ThreadDispatcher* get_thread_dispatcher() {        return nullptr;    }    virtual VmObjectDispatcher* get_vm_object_dispatcher() {        return nullptr;    }    virtual PciDeviceDispatcher* get_pci_device_dispatcher() {        return nullptr;    }    virtual PciInterruptDispatcher* get_pci_interrupt_dispatcher() {        return nullptr;    }    virtual IoMappingDispatcher* get_io_mapping_dispatcher() {        return nullptr;    }    virtual LogDispatcher* get_log_dispatcher() {        return nullptr;    }    virtual IOPortDispatcher* get_io_port_dispatcher() {        return nullptr;    }    virtual DataPipeProducerDispatcher* get_data_pipe_producer_dispatcher() {        return nullptr;    }    virtual DataPipeConsumerDispatcher* get_data_pipe_consumer_dispatcher() {        return nullptr;    }    virtual WaitSetDispatcher* get_wait_set_dispatcher() {        return nullptr;    }    virtual SocketDispatcher* get_socket_dispatcher() {        return nullptr;    }    virtual ResourceDispatcher* get_resource_dispatcher() {        return nullptr;    }protected:    static mx_koid_t GenerateKernelObjectId();private:    const mx_koid_t koid_;    // 引用数    int handle_count_;};
进程的实现

进程的Dispatcher定义中主要包括了以下的结构和代码

1、静态进程列表(包括了当前所有的进程)以及对应操作(添加、删除等)的静态方法

2、进程生命周期的相关函数(包括了创建、初始化、退出等)

3、引用计数的相关操作

4、进程内的线程相关操作(添加、删除等)

下面分析下其中几个函数:

创建进程

kernel/lib/magenta/process_dispatcher.cpp

// 在内核中创建进程mx_status_t ProcessDispatcher::Create(utils::StringPiece name,                                      utils::RefPtr<Dispatcher>* dispatcher,                                      mx_rights_t* rights, uint32_t flags) {    // 新建一个进程Dispatcher    AllocChecker ac;    auto process = new (&ac) ProcessDispatcher(name, flags);    if (!ac.check())        return ERR_NO_MEMORY;    // 初始化    status_t result = process->Initialize();    if (result != NO_ERROR)        return result;    // 返回权限    *rights = kDefaultProcessRights;    // 返回指针    *dispatcher = utils::AdoptRef<Dispatcher>(process);    return NO_ERROR;}...ProcessDispatcher::ProcessDispatcher(utils::StringPiece name, uint32_t flags)    : state_tracker_(true, mx_signals_state_t{0u, MX_SIGNAL_SIGNALED}) {    LTRACE_ENTRY_OBJ;    // Add ourself to the global process list, generating an ID at the same time.    // 把新建的进程加入进程列表    AddProcess(this);    // Generate handle XOR mask with top bit and bottom two bits cleared    // 通过随机数生成进程句柄    uint32_t secret;    auto prng = crypto::GlobalPRNG::GetInstance();    prng->Draw(&secret, sizeof(secret));    // Handle values cannot be negative values, so we mask the high bit.    handle_rand_ = (secret << 2) & INT_MAX;    //设置进程名    if (name.length() > 0 && (name.length() < sizeof(name_)))        strlcpy(name_, name.data(), sizeof(name_));}...status_t ProcessDispatcher::Initialize() {    LTRACE_ENTRY_OBJ;    AutoLock lock(state_lock_);    DEBUG_ASSERT(state_ == State::INITIAL);    // create an address space for this process.    // 为新建的进程创建虚拟地址空间    // 进程具有独立的虚拟地址空间    aspace_ = VmAspace::Create(0, nullptr);    if (!aspace_) {        TRACEF("error creating address space\n");        return ERR_NO_MEMORY;    }    return NO_ERROR;}


运行进程

kernel/lib/magenta/process_dispatcher.cpp

status_t ProcessDispatcher::Start(ThreadDispatcher *thread, uintptr_t pc,                                  uintptr_t sp, uintptr_t arg1, uintptr_t arg2) {    LTRACEF("process %p thread %p, entry %#" PRIxPTR ", sp %#" PRIxPTR            ", arg1 %#" PRIxPTR ", arg2 %#" PRIxPTR "\n",            this, thread, pc, sp, arg1, arg2);    // grab and hold the state lock across this entire routine, since we're    // effectively transitioning from INITIAL to RUNNING    // 上锁    AutoLock lock(state_lock_);    // make sure we're in the right state    if (state_ != State::INITIAL)        return ERR_BAD_STATE;    // start the initial thread    // 运行传入的主线程的Dispatcher    LTRACEF("starting main thread\n");    auto status = thread->Start(pc, sp, arg1, arg2);    if (status < 0)        return status;    // 设置为运行状态    SetState(State::RUNNING);    return NO_ERROR;}


0 1
原创粉丝点击