CORESRV

Presentation
Coresrv is the main and central service of LSE/OS. It manages:

  • Memory
  • Tasks
  • Signals
  • Ioport access
  • Credentials

    Note the following particularities of LSE/OS:

  • Task creation and destruction is managed outside Coresrv: Only the binding between the TCB and the memory that has been allocated for it is done in coresrv.
  • Address space creation and destruction is managed outside Coresrv; Coresrv only manages the page directory coherence.

    LSE/OS only manages elementary task and memory operations and guarantee the security for it.

    The Task Control Block
    The TCB is the structure that represent a task. It is not only a logical view of the reality but a hardware view: if you pay attention to the t_tcb_export strcture, you notice that the t_tss structure is defined first because it is a requirement for calling a taskgate. The iomapbase field is the offset to the optional t_iomap that defines ISA ioport permissions.

    The TCB and related structures (Software View)
    ClassDescription
    t_ucredStore credentials of the process
    t_ustatStore statistics of the process
    t_tcb_exportThe portable portion of the TCB
    t_tssThe HW structure of a taskgate context
    t_sigctxThe context binded to a signal handler
    t_usigThe optional structure needed by a signalable task
    iomapThe optional HW IO map of authorized ioports for the task
    t_tcb_fullThe TCB as it is viewed in coresrv, especially it contains fields for storing the task in the linked lists of the system
    FieldDescription
    sizepgThe size of TCB in pages
    paThe physical pages of the TCB
    kaThe kernel pages of the TCB

    Hardware View of the Reality

    Address Spaces
    An address space is a virtual memory set (t_area_set). For each address space there is a page directory and some page tables according to the x86 requirements. Altough tasks need at least one address space as a support for execution, address spaces are managed totaly separately from tasks. Many tasks can share the same address space and one task can use have many address spaces.

    Address_Space and related structures
    ClassDescription
    t_aspace_exportThe portable portion of the address space
    FieldDescription
    refcntThe number of tasks actually using aspace
    t_aspace_fullThe address space structure that is viewed inside coresrv: especially it contains the fields required for beeing stored in the linked lists of the system, etc
    FieldDescription
    paThe physical page of the aspace
    kaThe kernel page of the aspace
    pgdirThe physical page of the page directory of the aspace
    t_area_setDescribed in the memory management section.

    Address spaces and area sets in the system
    ItemDescription
    sys0_setPhysical pages < pstart
    sys1_setPhysical pages > 0xd0000000 (memory mapped registers)
    phys_setPhysical pages (RAM) excepted sys0 and sys1
    kern_setKernel virtual pages
    asn_setArea sets of address spaces. Note they all contains kernel page tables

    Please have a look in x86 manual for understanding page directory mechanism.

    Dynamic View

    The following diagram illustrates task creation as it is done in LSE/OS programs (the address space represented by 'asid' has been previously created and contains a binary executable):

    Task creation by another task
    StepDescription
    1The creator queries the size (in page) requested for the specic options it needs for the new task: especially the TCB size may vary if the task is signalable: signal context (t_sigctx) structures are present in the TCB, or the task accesses ioports so it must contains a iomap in it.
    2The creator allocates the needed physical pages for the TCB
    3Since the TCB virtual pages must be kernel addresses, the creator allocates kernel pages for it. It is easy to implement a quota mechanism for a user to allocate only a limited number of kernel pages.
    4The creator make the kernel pages mapping on the previously allocated pages.
    5The creator registers the newly created TCB and gets a 64bit pid
    6The creator binds the task to the address space.
    7The creator loads the name of the new task
    8The creator loads the class of the new task (TCBC_UNDEF, TCBC_SCHED, TCBC_SERVICE, TCBC_REALTIME, TCBC_KERNEL)
    9The creator loads the registers of the new tasks: the full set with ltss() and only the entry points with lep()
    10The creator sets the task in run queue. The task could then be scheduled.

    The following diagram illustrates the 3 use cases actions that have to be managed by the context switcher:

  • A task is to be elected
  • An address space is to be destroyed
  • A TCB is to be destroyed

    Interaction between context switcher and Coresrv
    StepDescription
    1Cswitch calls runq() to get the next action to perform
    Use Case 1A Task is beeing elected
    2Cswitch restores the FPU state of the task (because it is not done automatically)
    3Cswitch unlocks the task in the GDT: It can be called then in assembly
    4Cswitch calls the taskgate in assembly
    5Cswitch locks the task again: it cannot be called by anybody
    6Cswitch saves the FPU context of the task
    Use Case 2An address space has to be destroyed: an aspace is destroyed when no more task use it (refcnt)
    7Cswitch needs the full definition of the address space
    8Cswitch releases the address space: asrele() is not a syscall but a convenience function that retrieves all the memory areas used by the address space with memdef() and call prele(), krele() and vrele() according to the type of each area.
    9Cswitch unregisters the address space: it removes it from the hash table
    10Cswitch unmap the aspace page from the TLB
    11Cswitch removes all the pages tables from the page directory corresponding to the address space
    12Flush of the TLB cache to update the processor
    13Free the page directory of the address space
    14Free the physical page of the address space
    15Free the kernel page of the address space
    Use Case 3A TCB is beeing destroyed
    16Cswitch get the full definition of the TCB
    17Cswitch unregisters the TCB: remove task from hash table and process list
    18Cswitch unmaps the TCB from TLB
    19Cswitch releases the physical pages of the TCB
    20Cswitch releases the kernel pages of the TCB

    Coresrv API overview
    Links refer to Doxygen generated prototypes of functions:

    SyscallDescriptionDebug
    __sfullas()Get the full definition of the address space (kernel dependent)
    __sfulllink()Get the full definition of the caller task (kernel dependent)
    __sfulltcb2()Get the full definition of a task (kernel dependent)
    aggdef()Get the definition of some physical pages marked as non coalescible
    ascopy()Copy memory from an address space to one another
    asop()Perform some address space operations (address space switching, etc)
    aspgdir()Get the page directory of the specified address space
    asreg()Register an address space
    assert()Declare one assertion (for kernel only)Yes
    asunreg()Unregister an address space
    check()Launch a sanity checkYes
    clearbsy()Clear the BSY bit of a task in GDT (unlock the task from processor)
    collect()Collect information on dead tasks
    copy()Copy memory from one task to one another
    dump()Dumps some debug information of the systemYes
    dwrite()Prints a message on console
    _exit()Kill current task with an error code
    getegid()Get the effective group id of the task
    geteuid()Get the effective uid of the task
    getgid()Get the group id of the task
    getgroups()Get all the groups of the task
    getsel()Get the selector associated to a pid
    getuid()Get current uid of the task
    ioacquire()Acquire the rights on a ioport
    iorele()Release the rights on a ioport
    kdef()Get information on kernel pages
    kill()Send a signal to a task
    krele()Release kernel pages
    krsv()Reserve kernel pages
    lasep()Load entry points of an address space (if it is an executable)
    lasprotect()Protect the current address space
    lclass()Modify the class of a task
    lep()Load entry points of the task
    lfpu()Load the FPU state into the task
    _lidt()Store records to IDT
    llinkret()Modify the return codes of a task
    lname()Change the name of a task
    lstatus()Change the status of a task (TCBS_IDLE, TCBS_RUN, TCBS_SLEEP, TCBS_STOP, TCBS_ZOMBIE, TCBS_STOP)
    ltrace()Trace a process (syscalls, traps, pgflts, etc) and print debug message on consoleYes
    ltss()Load the TSS (task x86 registers) into a task
    memdef()Get information on physical, kernel and user pages of an address space id
    memdump()Dump address spaces informations on consoleYes
    nicepid()Change the priority of the task
    notify()Declare the task as the notify manager
    paggregate()Mark physical pages as non coalescible
    pdef()Get information on physical pages
    pgive()Give some physical pages to an another address space
    prele()Release physical pages
    procdef()Get information on tasks in the system
    prsv()Reserve physical pages
    pshare()Mark physical pages as shareable
    ptrace()Like the Unix equivalent, cause the task to be stopped when it has to be signaled, the parent process receives a SIGCHLD
    _rcr3()Get the current page directory of the task
    reboot()Reboot the system
    remrunq()Remove a task from run queue
    remrunq2()Remove a task from run queue (by pid)
    reparent()More generic form of yield() that allows to yield in another context
    runq()Get the next task to run according to a round robin algorithm and if signals have to be posted
    sas()Get an address space record
    sasid()Get the current address space id
    sclass()Get the class of the task
    scred()Get the credentials of a task
    secmgr()Declare current task as security manager
    setasuid()Set the owner of the address space
    setbsy()Set the BSY bit of a task in GDT
    setegid()Set the effective group id of the task
    seteuid()Set the effective uid of the task
    setgid()Set the group id of the task
    setgroups()Set all the groups of the task
    setpgid()Set process group id
    setrunq()Set a task in run queue (by pid)
    setrunq2()Set a task in run queue
    setuid()Set the uid of the task
    sfpu()Get the FPU state of a task
    _sgdt()Get records from GDT (Global Descriptor Table)
    _sidt()Get records from IDT (Interrupt Descriptor Table)
    sigaction2More generic form of the sigaction() unix call
    sigprocmask()Same as in Unix
    sigreturn()Return from a signal handler
    sigsuspend()Same as in Unix
    sinfo()Get system info such as GDT address and limit
    slink()Get the tcb of caller (e.g. for syscalls)
    spgid()Get the process group id of a task
    spgid2()Get the process group of the task (by pid)
    spid()Get the current pid (64bits)
    sppid()Get the parent process id of a task
    sppid2()Get the parent process id of task (by pid)
    sq_gate()To be documented
    ssig()Get info for pending signals of a task
    stcb()Get properties of a task (Task Control Block)
    stcb2()Same as stcb() but take a pid instead of a selector in parameter
    tcbreg()Register a new TCB
    tcbsizepg()Get the size in page needed by a tcb according to task options
    tcbunreg()Unregister a TCB
    vdef()Get information on virtual pages
    vm86()Perform a VM86 call
    vmap()Map virtual pages to physical pages
    vrele()Release virtual pages
    vrsv()Reserve virtual pages in an address space
    vunmap()Unmap virtual pages from physical pages
    wait4()Same as in Unix
    wire()Wire pages into physical TLB