Author Archives: Robins

Source code analysis of macOS startup process

1. Sonic activation (osfmk \i386\i386_init.c)

void
vstart(vm_offset_t boot_args_start)
{
    boolean_t   is_boot_cpu = !(boot_args_start == 0);
    int     cpu;
    uint32_t    lphysfree;

    postcode(VSTART_ENTRY);

    if (is_boot_cpu) {
        /*
         * Get startup parameters.
         */
        kernelBootArgs = (boot_args *)boot_args_start;
        lphysfree = kernelBootArgs->kaddr + kernelBootArgs->ksize;
        physfree = (void *)(uintptr_t)((lphysfree + PAGE_SIZE - 1) &~ (PAGE_SIZE - 1));

#if DEVELOPMENT || DEBUG
        pal_serial_init();
#endif
        DBG("revision      0x%x\n", kernelBootArgs->Revision);
        DBG("version       0x%x\n", kernelBootArgs->Version);
        DBG("command line  %s\n", kernelBootArgs->CommandLine);
        DBG("memory map    0x%x\n", kernelBootArgs->MemoryMap);
        DBG("memory map sz 0x%x\n", kernelBootArgs->MemoryMapSize);
        DBG("kaddr         0x%x\n", kernelBootArgs->kaddr);
        DBG("ksize         0x%x\n", kernelBootArgs->ksize);
        DBG("physfree      %p\n", physfree);
        DBG("bootargs: %p, &ksize: %p &kaddr: %p\n",
            kernelBootArgs, 
            &kernelBootArgs->ksize,
            &kernelBootArgs->kaddr);
        DBG("SMBIOS mem sz 0x%llx\n", kernelBootArgs->PhysicalMemorySize);

        /*
         * Setup boot args given the physical start address.
         * Note: PE_init_platform needs to be called before Idle_PTs_init
         * because access to the DeviceTree is required to read the
         * random seed before generating a random physical map slide.
         */
        kernelBootArgs = (boot_args *)
            ml_static_ptovirt(boot_args_start);
        DBG("i386_init(0x%lx) kernelBootArgs=%p\n",
            (unsigned long)boot_args_start, kernelBootArgs);
        PE_init_platform(FALSE, kernelBootArgs);
        postcode(PE_INIT_PLATFORM_D);

        Idle_PTs_init();
        postcode(VSTART_IDLE_PTS_INIT);

        first_avail = (vm_offset_t)ID_MAP_VTOP(physfree);

        cpu = 0;
        cpu_data_alloc(TRUE);
    } else {
        /* Switch to kernel's page tables (from the Boot PTs) */
        set_cr3_raw((uintptr_t)ID_MAP_VTOP(IdlePML4));
        /* Find our logical cpu number */
        cpu = lapic_to_cpu[(LAPIC_READ(ID)>>LAPIC_ID_SHIFT) & LAPIC_ID_MASK];
        DBG("CPU: %d, GSBASE initial value: 0x%llx\n", cpu, rdmsr64(MSR_IA32_GS_BASE));
    }

    postcode(VSTART_CPU_DESC_INIT);
    if(is_boot_cpu)
        cpu_desc_init64(cpu_datap(cpu));
    cpu_desc_load64(cpu_datap(cpu));
    postcode(VSTART_CPU_MODE_INIT);
    if (is_boot_cpu)
        cpu_mode_init(current_cpu_datap()); /* cpu_mode_init() will be
                             * invoked on the APs
                             * via i386_init_slave()
                             */
    postcode(VSTART_EXIT);
    x86_init_wrapper(is_boot_cpu ?(uintptr_t) i386_init
                     : (uintptr_t) i386_init_slave,
             cpu_datap(cpu)->cpu_int_stack_top);
}

Vstart is an i386/x64 kernel initialization function that marks the conversion from assembly code to C code, and is also a special function because this function is executed on both the main CPU (boot CPU) and all slave Cpus or cores on the machine. Is_boot_cpu determines whether it is a primary or secondary CPU. The boot_args_start pointer parameter passed in from the CPU is NULL.
For the main CPU:
PE_Init_Platfrom (Platform expert) : initializes the global variable PE_state, which contains a copy of the boot parameters, the video parameters, and other parameters. In addition, there are the following functions:
Graphics Building the device tree (as described above)Parse Certain boot argumentsIdentify the machine (including processor and bus clock speeds)Initialize a “user interface” to be used in case of kernel Panics
finally through x86_init_wrapper(is_boot_cpu?(uintptr_t) i386_init : (uintptr_t) i386_init_slave, cpu_datap(cpu)-> cpu_int_stack_top); The function executes different initializers on and from the CPU, respectively.
2. Main CPU runs i386_init()(OSFMK \i386\ i386_inits.c)
The first is a bunch of initializations

    pal_i386_init();
    tsc_init();
    rtclock_early_init();   /* mach_absolute_time() now functionsl */

    kernel_debug_string_simple("i386_init");
    pstate_trace();

#if CONFIG_MCA
    /* Initialize machine-check handling */
    mca_cpu_init();
#endif

    master_cpu = 0;
    cpu_init();

    postcode(CPU_INIT_D);

    printf_init();          /* Init this in case we need debugger */
    panic_init();           /* Init this in case we need debugger */

Pal_i386_init: call Platfrom Abstraction, is a simple call to initialize the EFI lock
(2) PE_Init_Platfrom: initialize the global variable PE_state, including the copy of boot parameters, video parameters and other parameters. This function call pe_identify_platform() sets gPEClockFrequency
(3) kernel_early_bootstrap: Lck_mod_init () and timer_call_initialize(), which are used for timer calls
(4) cpu_init to set the current CPU clock timer dealIne to “EndOfAllTime” (end of all times), and after the clock is set to run forever, cpu_init() calls i386_active_cpu()
(5) printf_init: to call for the debugger. If the debugger is connected. The message entered by the kernel call printf() is redirected to the debugger
(6) panic_init: the call initializes the kernel crash redirect so that the sending of the kernel crash can be intercepted by the connected debugger
(7) PE_init_kprintf: the call makes kprintf() output to the console
(8) check serial console: check the “serial” boot parameters. If it’s set. The switch_to_serial_console()
(9) PE_Init_printf: call enables kprintf() to be printed out to the console
(10) 64-bit processor check: if the cpu-supported feature includes the CPUID_EXTFEATURE_EM64T flag, then enable this feature unless the “-legal” parameter
(11) i386_vm_init: Take over virtual memory management from EFI. Call pmap_bootstrap to initialize kernel physical memory map
last call

    /*   
     * VM initialization, after this we're using page tables...
     * Thn maximum number of cpus must be set beforehand.
     */
    kernel_debug_string_simple("i386_vm_init");
    i386_vm_init(maxmemtouse, IA32e, kernelBootArgs);

    /* create the console for verbose or pretty mode */
    /* Note: doing this prior to tsc_init() allows for graceful panic! */
    PE_init_platform(TRUE, kernelBootArgs);
    PE_create_console();

    kernel_debug_string_simple("power_management_init");
    power_management_init();
    processor_bootstrap();
    thread_bootstrap();

    pstate_trace();
    kernel_debug_string_simple("machine_startup");
    machine_startup();
    pstate_trace();

where the function of power_management_init() is to initialize a function in the structure cstateInit:

/* * dispatch table function that gets the power on installation
* Manage KEXT load.
*
* pmDispatch_t is a tool that the kernel can use to send the
* A set of functions called to the power management KEXT.
*
* pmCallBacks_t is the power management kext.
* A set of functions that can be called to obtain a specific kernel function.
* /

Translated with www.DeepL.com/Translator (free version)

typedef struct
{
    kern_return_t   (*pmCPUStateInit)(void);
    void        (*cstateInit)(void);
    uint64_t        (*MachineIdle)(uint64_t maxIdleDuration);
    uint64_t        (*GetDeadline)(x86_lcpu_t *lcpu);
    uint64_t        (*SetDeadline)(x86_lcpu_t *lcpu, uint64_t);
    void        (*Deadline)(x86_lcpu_t *lcpu);
    boolean_t       (*exitIdle)(x86_lcpu_t *lcpu);
    void        (*markCPURunning)(x86_lcpu_t *lcpu);
    int         (*pmCPUControl)(uint32_t cmd, void *datap);
    void        (*pmCPUHalt)(void);
    uint64_t        (*getMaxSnoop)(void);
    void        (*setMaxBusDelay)(uint64_t time);
    uint64_t        (*getMaxBusDelay)(void);
    void        (*setMaxIntDelay)(uint64_t time);
    uint64_t        (*getMaxIntDelay)(void);
    void        (*pmCPUSafeMode)(x86_lcpu_t *lcpu, uint32_t flags);
    void        (*pmTimerStateSave)(void);
    void        (*pmTimerStateRestore)(void);
    kern_return_t   (*exitHalt)(x86_lcpu_t *lcpu);
    kern_return_t   (*exitHaltToOff)(x86_lcpu_t *lcpu);
    void        (*markAllCPUsOff)(void);
    void        (*pmSetRunCount)(uint32_t count);
    boolean_t       (*pmIsCPUUnAvailable)(x86_lcpu_t *lcpu);
    int         (*pmChooseCPU)(int startCPU, int endCPU, int preferredCPU);
    int         (*pmIPIHandler)(void *state);
    void        (*pmThreadTellUrgency)(int urgency, uint64_t rt_period, uint64_t rt_deadline);
    void        (*pmActiveRTThreads)(boolean_t active);
    boolean_t           (*pmInterruptPrewakeApplicable)(void);
} pmDispatch_t;

(15) Processor_bootstrap: Initializes the Processor subsystem for Mach. This function initializes three queues: Task, terminated, and threads, creates master_processor objects, calls processor_init(), processor_init(), sets the field values in the processor data structure, and adds itself to the default processor group, pset0.
(16) thread_bootstrap: sets the template for the Mach thread object. The Mach thread structure has a number of fields. This function fills in the default values for these fields, then sets the first system thread, init_thread, which integrates all the values from the template, and then calls machine_set_current_thread() to flag the thread as active on the current CPU.
(17) machine_startup: initializes the next stage, never returning.
3. machine_startup()(osfmk\i386\at386\Model_dep.c)

void
machine_startup(void)
{
    int boot_arg;

#if 0
    if( PE_get_hotkey( kPEControlKey ))
            halt_in_debugger = halt_in_debugger ?0 : 1;
#endif

    if (PE_parse_boot_argn("debug", &debug_boot_arg, sizeof (debug_boot_arg))) {
        panicDebugging = TRUE;
#if DEVELOPMENT || DEBUG
        if (debug_boot_arg & DB_HALT) halt_in_debugger=1;
#endif
        if (debug_boot_arg & DB_PRT) disable_debug_output=FALSE; 
        if (debug_boot_arg & DB_SLOG) systemLogDiags=TRUE; 
        if (debug_boot_arg & DB_LOG_PI_SCRN) logPanicDataToScreen=TRUE;
#if KDEBUG_MOJO_TRACE
        if (debug_boot_arg & DB_PRT_KDEBUG) {
            kdebug_serial = TRUE;
            disable_debug_output = FALSE;
        }
#endif
    } else {
        debug_boot_arg = 0;
    }

    if (!PE_parse_boot_argn("nvram_paniclog", &commit_paniclog_to_nvram, sizeof (commit_paniclog_to_nvram)))
        commit_paniclog_to_nvram = 1;

    /*
     * Entering the debugger will put the CPUs into a "safe"
     * power mode.
     */
    if (PE_parse_boot_argn("pmsafe_debug", &boot_arg, sizeof (boot_arg)))
        pmsafe_debug = boot_arg;

#if NOTYET
    hw_lock_init(&debugger_lock);   /* initialize debugger lock */
#endif
    hw_lock_init(&pbtlock);     /* initialize print backtrace lock */

    if (PE_parse_boot_argn("preempt", &boot_arg, sizeof (boot_arg))) {
        default_preemption_rate = boot_arg;
    }
    if (PE_parse_boot_argn("unsafe", &boot_arg, sizeof (boot_arg))) {
        max_unsafe_quanta = boot_arg;
    }
    if (PE_parse_boot_argn("poll", &boot_arg, sizeof (boot_arg))) {
        max_poll_quanta = boot_arg;
    }
    if (PE_parse_boot_argn("yield", &boot_arg, sizeof (boot_arg))) {
        sched_poll_yield_shift = boot_arg;
    }
/* The I/O port to issue a read from, in the event of a panic. Useful for
 * triggering logic analyzers.
 */
    if (PE_parse_boot_argn("panic_io_port", &boot_arg, sizeof (boot_arg))) {
        /*I/O ports range from 0 through 0xFFFF */
        panic_io_port = boot_arg & 0xffff;
    }

    machine_conf();

    panic_hooks_init();

    /*
     * Start the system.
     */
    kernel_bootstrap();
    /*NOTREACHED*/
}

This function is primarily responsible for parsing the command-line arguments (the PE_parse_boot_argn function provided through Platform Expert), most of which are the boot-arg for debugging to control the debugging at boot time.
4.kernel_bootstrap()(osfmk\kern\Startup.c)


void
kernel_bootstrap(void)
{
    kern_return_t   result;
    thread_t    thread;
    char        namep[16];

    printf("%s\n", version); /* log kernel version */

    if (PE_parse_boot_argn("-l", namep, sizeof (namep))) /* leaks logging */
        turn_on_log_leaks = 1;

    PE_parse_boot_argn("trace", &new_nkdbufs, sizeof (new_nkdbufs));
    PE_parse_boot_argn("trace_wake", &wake_nkdbufs, sizeof (wake_nkdbufs));
    PE_parse_boot_argn("trace_panic", &write_trace_on_panic, sizeof(write_trace_on_panic));
    PE_parse_boot_argn("trace_typefilter", &trace_typefilter, sizeof(trace_typefilter));

    scale_setup();

    kernel_bootstrap_log("vm_mem_bootstrap");
    vm_mem_bootstrap();

    kernel_bootstrap_log("cs_init");
    cs_init();

    kernel_bootstrap_log("vm_mem_init");
    vm_mem_init();

    machine_info.memory_size = (uint32_t)mem_size;
    machine_info.max_mem = max_mem;
    machine_info.major_version = version_major;
    machine_info.minor_version = version_minor;


#if CONFIG_TELEMETRY
    kernel_bootstrap_log("telemetry_init");
    telemetry_init();
#endif

#if CONFIG_CSR
    kernel_bootstrap_log("csr_init");
    csr_init();
#endif

    if (PE_i_can_has_debugger(NULL) &&
        PE_parse_boot_argn("-show_pointers", &namep, sizeof (namep))) {
        doprnt_hide_pointers = FALSE;
    }

    kernel_bootstrap_log("console_init");
    console_init();

    kernel_bootstrap_log("stackshot_lock_init");    
    stackshot_lock_init();

    kernel_bootstrap_log("sched_init");
    sched_init();

    kernel_bootstrap_log("waitq_bootstrap");
    waitq_bootstrap();

    kernel_bootstrap_log("ipc_bootstrap");
    ipc_bootstrap();

#if CONFIG_MACF
    kernel_bootstrap_log("mac_policy_init");
    mac_policy_init();
#endif

    kernel_bootstrap_log("ipc_init");
    ipc_init();

    /*
     * As soon as the virtual memory system is up, we record
     * that this CPU is using the kernel pmap.
     */
    kernel_bootstrap_log("PMAP_ACTIVATE_KERNEL");
    PMAP_ACTIVATE_KERNEL(master_cpu);

    kernel_bootstrap_log("mapping_free_prime");
    mapping_free_prime();                       /* Load up with temporary mapping blocks */

    kernel_bootstrap_log("machine_init");
    machine_init();

    kernel_bootstrap_log("clock_init");
    clock_init();

    ledger_init();

    /*
     *  Initialize the IPC, task, and thread subsystems.
     */
#if CONFIG_COALITIONS
    kernel_bootstrap_log("coalitions_init");
    coalitions_init();
#endif

    kernel_bootstrap_log("task_init");
    task_init();

    kernel_bootstrap_log("thread_init");
    thread_init();

#if CONFIG_ATM
    /* Initialize the Activity Trace Resource Manager. */
    kernel_bootstrap_log("atm_init");
    atm_init();
#endif

#if CONFIG_BANK
    /* Initialize the BANK Manager. */
    kernel_bootstrap_log("bank_init");
    bank_init();
#endif

    /* initialize the corpse config based on boot-args */
    corpses_init();

    /*
     *  Create a kernel thread to execute the kernel bootstrap.
     */
    kernel_bootstrap_log("kernel_thread_create");
    result = kernel_thread_create((thread_continue_t)kernel_bootstrap_thread, NULL, MAXPRI_KERNEL, &thread);

    if (result != KERN_SUCCESS) panic("kernel_bootstrap: result = %08X\n", result);

    thread->state = TH_RUN;
    thread->last_made_runnable_time = mach_absolute_time();
    thread_deallocate(thread);

    kernel_bootstrap_log("load_context - done");
    load_context(thread);
    /*NOTREACHED*/
}

The kernel_bootstrap function continues to set and initialize the various core subsystems of the Mach kernel, establishing the necessary infrastructure on which BSD depends. In addition to virtual memory, kernel_bootstrap also initializes some key Mach abstractions:
IPC: IPC(interprocess communication) was the foundation of the Mach build, and IPC required some important resources, such as memory, synchronization objects, and the Mach Interface Generator (MIG)
clock: alarm (system alarm) and time (” calendar “)
thread: the thread was the actual unit of execution. A task is nothing more than a resource container, a thread that is actually scheduled and executed.
kernel_bootstrap function does not return. Kernel_bootstrap finally loads the context of the kernel_bootstrap_thread thread, which is the first active thread of the system. This thread will take over the initialization and handle more complex subsystems.
5.kernel_bootstrap_thread(void)(osfmk\kern\Startup.c)

/*
 * Now running in a thread.  Kick off other services,
 * invoke user bootstrap, enter pageout loop.
 */
static void
kernel_bootstrap_thread(void)
{
    processor_t     processor = current_processor();

#define kernel_bootstrap_thread_kprintf(x...) /* kprintf("kernel_bootstrap_thread: " x) */
    kernel_bootstrap_thread_log("idle_thread_create");
    /*
     * Create the idle processor thread.
     */
    idle_thread_create(processor);

    /*
     * N.B. Do not stick anything else
     * before this point.
     *
     * Start up the scheduler services.
     */
    kernel_bootstrap_thread_log("sched_startup");
    sched_startup();

    /*
     * Thread lifecycle maintenance (teardown, stack allocation)
     */
    kernel_bootstrap_thread_log("thread_daemon_init");
    thread_daemon_init();

    /* Create kernel map entry reserve */
    vm_kernel_reserved_entry_init();

    /*
     * Thread callout service.
     */
    kernel_bootstrap_thread_log("thread_call_initialize");
    thread_call_initialize();

    /*
     * Remain on current processor as
     * additional processors come online.
     */
    kernel_bootstrap_thread_log("thread_bind");
    thread_bind(processor);

    /*
     * Initialize ipc thread call support.
     */
    kernel_bootstrap_thread_log("ipc_thread_call_init");
    ipc_thread_call_init();

    /*
     * Kick off memory mapping adjustments.
     */
    kernel_bootstrap_thread_log("mapping_adjust");
    mapping_adjust();

    /*
     *  Create the clock service.
     */
    kernel_bootstrap_thread_log("clock_service_create");
    clock_service_create();

    /*
     *  Create the device service.
     */
    device_service_create();

    kth_started = 1;

#if (defined(__i386__) || defined(__x86_64__)) && NCOPY_WINDOWS > 0
    /*
     * Create and initialize the physical copy window for processor 0
     * This is required before starting kicking off  IOKit.
     */
    cpu_physwindow_init(0);
#endif



#if MACH_KDP 
    kernel_bootstrap_log("kdp_init");
    kdp_init();
#endif

#if ALTERNATE_DEBUGGER
    alternate_debugger_init();
#endif

#if KPC
    kpc_init();
#endif

#if CONFIG_ECC_LOGGING
    ecc_log_init();
#endif 

#if KPERF
    kperf_bootstrap();
#endif

#if HYPERVISOR
    hv_support_init();
#endif

#if CONFIG_TELEMETRY
    kernel_bootstrap_log("bootprofile_init");
    bootprofile_init();
#endif

#if (defined(__i386__) || defined(__x86_64__)) && CONFIG_VMX
    vmx_init();
#endif

#if (defined(__i386__) || defined(__x86_64__))
    if (kdebug_serial) {
        new_nkdbufs = 1;
        if (trace_typefilter == 0)
            trace_typefilter = 1;
    }
    if (turn_on_log_leaks && !new_nkdbufs)
        new_nkdbufs = 200000;
    if (trace_typefilter)
        start_kern_tracing_with_typefilter(new_nkdbufs,
                           FALSE,
                           trace_typefilter);
    else
        start_kern_tracing(new_nkdbufs, FALSE);
    if (turn_on_log_leaks)
        log_leaks = 1;

#endif

    kernel_bootstrap_log("prng_init");
    prng_cpu_init(master_cpu);

#ifdef  IOKIT
    PE_init_iokit();
#endif

    assert(ml_get_interrupts_enabled() == FALSE);
    (void) spllo();     /* Allow interruptions */

#if (defined(__i386__) || defined(__x86_64__)) && NCOPY_WINDOWS > 0
    /*
     * Create and initialize the copy window for processor 0
     * This also allocates window space for all other processors.
     * However, this is dependent on the number of processors - so this call
     * must be after IOKit has been started because IOKit performs processor
     * discovery.
     */
    cpu_userwindow_init(0);
#endif

#if (!defined(__i386__) && !defined(__x86_64__))
    if (turn_on_log_leaks && !new_nkdbufs)
        new_nkdbufs = 200000;
    if (trace_typefilter)
        start_kern_tracing_with_typefilter(new_nkdbufs, FALSE, trace_typefilter);
    else
        start_kern_tracing(new_nkdbufs, FALSE);
    if (turn_on_log_leaks)
        log_leaks = 1;
#endif

    /*
     *  Initialize the shared region module.
     */
    vm_shared_region_init();
    vm_commpage_init();
    vm_commpage_text_init();

#if CONFIG_MACF
    kernel_bootstrap_log("mac_policy_initmach");
    mac_policy_initmach();
#endif


#if CONFIG_SCHED_SFI
    kernel_bootstrap_log("sfi_init");
    sfi_init();
#endif

    /*
     * Initialize the globals used for permuting kernel
     * addresses that may be exported to userland as tokens
     * using VM_KERNEL_ADDRPERM()/VM_KERNEL_ADDRPERM_EXTERNAL().
     * Force the random number to be odd to avoid mapping a non-zero
     * word-aligned address to zero via addition.
     * Note: at this stage we can use the cryptographically secure PRNG
     * rather than early_random().
     */
    read_random(&vm_kernel_addrperm, sizeof(vm_kernel_addrperm));
    vm_kernel_addrperm |= 1;
    read_random(&buf_kernel_addrperm, sizeof(buf_kernel_addrperm));
    buf_kernel_addrperm |= 1;
    read_random(&vm_kernel_addrperm_ext, sizeof(vm_kernel_addrperm_ext));
    vm_kernel_addrperm_ext |= 1;

    vm_set_restrictions();



    /*
     *  Start the user bootstrap.
     */
#ifdef  MACH_BSD
    bsd_init();
#endif

    /*
     * Get rid of segments used to bootstrap kext loading. This removes
     * the KLD, PRELINK symtab, LINKEDIT, and symtab segments/load commands.
     */
    OSKextRemoveKextBootstrap();

    serial_keyboard_init();     /* Start serial keyboard if wanted */

    vm_page_init_local_q();

    thread_bind(PROCESSOR_NULL);

    /*
     *  Become the pageout daemon.
     */
    vm_pageout();
    /*NOTREACHED*/
}

The main thread starts running as the kernel_bootstrap_thread thread, whose job is still to initialize the various subsystems.
6.bsd_init()(bsd\kern\Bsd_init.c)


    /* Initialize signal state for process 0. */
    bsd_init_kprintf("calling siginit\n");
    siginit(kernproc);

    bsd_init_kprintf("calling bsd_utaskbootstrap\n");
    bsd_utaskbootstrap();

#if defined(__LP64__)
    kernproc->p_flag |= P_LP64;
#endif

The entire BSD layer of XNU is initialized by a function called bSD_init (). A lot of work is done in this function. The function’s job is to initialize each subsystem at once.
7.bsd_utaskbootstrap()(bsd\kern\Bsd_init.c)

void
bsd_utaskbootstrap(void)
{
    thread_t thread;
    struct uthread *ut;

    /*
     * Clone the bootstrap process from the kernel process, without
     * inheriting either task characteristics or memory from the kernel;
     */
    thread = cloneproc(TASK_NULL, COALITION_NULL, kernproc, FALSE, TRUE);

    /* Hold the reference as it will be dropped during shutdown */
    initproc = proc_find(1);                
#if __PROC_INTERNAL_DEBUG
    if (initproc == PROC_NULL)
        panic("bsd_utaskbootstrap: initproc not set\n");
#endif
    /*
     * Since we aren't going back out the normal way to our parent,
     * we have to drop the transition locks explicitly.
     */
    proc_signalend(initproc, 0);
    proc_transend(initproc, 0);

    ut = (struct uthread *)get_bsdthread_info(thread);
    ut->uu_sigmask = 0;
    act_set_astbsd(thread);
    proc_clear_return_wait(initproc, thread);
}

This function is responsible for indirectly starting PID 1, the first process to enter user mode. To do this, bSD_utaskBootstrap () first calls CloneProc (), creating a new Mach task. To actually create a new task, utaskbootstrap() calls act_set_astbsd() to the created thread, generates an asynchronous system trap(AST), then calls thread_resume(), and utaskbootstrap() returns to bsd_init().
8. i386_astintr()(osfmk\i386\Trap.c)

/*
 * Handle AST traps for i386.
 */

extern void     log_thread_action (thread_t, char *);

void
i386_astintr(int preemption)
{
    ast_t       mask = AST_ALL;
    spl_t       s;

    if (preemption)
            mask = AST_PREEMPTION;

    s = splsched();

    ast_taken(mask, s);

    splx(s);
}

Ast_taken () function :(osfmk\kern\ ast.c)

        /*
         * The kernel preempt traps
         * skip all other ASTs.
         */
        if (!preempt_trap) {
            ml_set_interrupts_enabled(enable);

#ifdef  MACH_BSD
            /*
             * Handle BSD hook.
             */
            if (reasons & AST_BSD) {
                thread_ast_clear(thread, AST_BSD);
                bsd_ast(thread);
            }
#endif
#if CONFIG_MACF
            /*
             * Handle MACF hook.
             */
            if (reasons & AST_MACF) {
                thread_ast_clear(thread, AST_MACF);
                mac_thread_userret(thread);
            }
#endif

Bsd_ast () function (OSFMK \kern\ kern_sig.c)

    if (!bsd_init_done) {
        bsd_init_done = 1;
        bsdinit_task();
    }

9. bsdinit_task()(bsd\kern\Bsd_init.c)

void
bsdinit_task(void)
{
    proc_t p = current_proc();
    struct uthread *ut;
    thread_t thread;

    process_name("init", p);

    ux_handler_init();

    thread = current_thread();
    (void) host_set_exception_ports(host_priv_self(),
                    EXC_MASK_ALL & ~(EXC_MASK_RPC_ALERT),//pilotfish (shark) needs this port
                    (mach_port_t) ux_exception_port,
                    EXCEPTION_DEFAULT| MACH_EXCEPTION_CODES,
                    0);

    ut = (uthread_t)get_bsdthread_info(thread);

    bsd_init_task = get_threadtask(thread);
    init_task_died = FALSE;

#if CONFIG_MACF
    mac_cred_label_associate_user(p->p_ucred);
#endif
    load_init_program(p);
    lock_trace = 1;
}

The name of the initial process is set to init, followed by a call to un_handler_init(), which creates a separate kernel thread, un_handler, that handles UNIX exceptions. Finally, load_init_program() is called. Load_init_program () is responsible for turning a process with PID 1 into what is known as Launchd. The flow of this thread is now fully in user mode.
10. load_init_program()(bsd\kern\Kern_exec.c)

/*
 * load_init_program
 *
 * Description: Load the "init" program; in most cases, this will be "launchd"
 *
 * Parameters:  p           Process to call execve() to create
 *                  the "init" program
 *
 * Returns: (void)
 *
 * Notes:   The process that is passed in is the first manufactured
 *      process on the system, and gets here via bsd_ast() firing
 *      for the first time.  This is done to ensure that bsd_init()
 *      has run to completion.
 *
 *      In DEBUG & DEVELOPMENT builds, the launchdsuffix boot-arg
 *      may be used to select a specific launchd executable. As with
 *      the kcsuffix boot-arg, setting launchdsuffix to "" or "release"
 *      will force /sbin/launchd to be selected.
 *
 *      The DEBUG kernel will continue to check for a .development
 *      version until <rdar://problem/17931977> is fixed.
 *
 *              Search order by build:
 *
 * DEBUG    DEVELOPMENT RELEASE     PATH
 * ----------------------------------------------------------------------------------
 * 1        1       NA      /usr/local/sbin/launchd.$LAUNCHDSUFFIX
 * 2        NA      NA      /usr/local/sbin/launchd.debug
 * 3        2       NA      /usr/local/sbin/launchd.development
 * 4        3       1       /sbin/launchd
 */
void
load_init_program(proc_t p)
{
    uint32_t i;
    int error;
    vm_offset_t scratch_addr = VM_MIN_ADDRESS;

    (void) vm_allocate(current_map(), &scratch_addr, PAGE_SIZE, VM_FLAGS_ANYWHERE);
#if CONFIG_MEMORYSTATUS && CONFIG_JETSAM
    (void) memorystatus_init_at_boot_snapshot();
#endif /* CONFIG_MEMORYSTATUS && CONFIG_JETSAM */

#if DEBUG || DEVELOPMENT
    /* Check for boot-arg suffix first */
    char launchd_suffix[64];
    if (PE_parse_boot_argn("launchdsuffix", launchd_suffix, sizeof(launchd_suffix))) {
        char launchd_path[128];
        boolean_t is_release_suffix = ((launchd_suffix[0] == 0) ||
                           (strcmp(launchd_suffix, "release") == 0));

        if (is_release_suffix) {
            error = load_init_program_at_path(p, CAST_USER_ADDR_T(scratch_addr), "/sbin/launchd");
            if (!error)
                return;

            panic("Process 1 exec of launchd.release failed, errno %d", error);
        } else {
            strlcpy(launchd_path, "/usr/local/sbin/launchd.", sizeof(launchd_path));
            strlcat(launchd_path, launchd_suffix, sizeof(launchd_path));

            /* All the error data is lost in the loop below, don't
             * attempt to save it. */
            if (!load_init_program_at_path(p, CAST_USER_ADDR_T(scratch_addr), launchd_path)) {
                return;
            }
        }
    }
#endif

    error = ENOENT;
    for (i = 0; i < sizeof(init_programs)/sizeof(init_programs[0]); i++) {
        error = load_init_program_at_path(p, CAST_USER_ADDR_T(scratch_addr), init_programs[i]);
        if (!error)
            return;
    }

    panic("Process 1 exec of %s failed, errno %d", ((i == 0) ?"<null>" : init_programs[i-1]), error);
}

Start these programs:

static const char * init_programs[] = {
#if DEBUG
    "/usr/local/sbin/launchd.debug",
#endif
#if DEVELOPMENT || DEBUG
    /* Remove DEBUG conditional when <rdar://problem/17931977> is fixed */
    "/usr/local/sbin/launchd.development",
#endif
    "/sbin/launchd",
};

Also:
XNU has many boot parameters, and there are usually two ways to pass parameters to the kernel
Through the NVRAM, use the boot – args parameter passing (parameters can be set by a command NVRAM)
through/Library/Prefrences/SystemConfihguration/com. Apple. The boot. The file. This is a standard property list file where parameters can be specified in the kernel_flags element

How to Fix yum Install Error Loaded plugins: fastestmirror, refresh-packagekit, security

[root@db yum.repos.d]# yum makecache

Loaded plugins: fastestmirror, refresh-packagekit, security

Loading mirror speeds from cached hostfile

Error: Cannot find a valid baseurl for repo: elasticsearch-6.x

[root@db yum.repos.d]# vim /etc/yum/pluginconf.d/fastestmirror.conf

Change 1 to 0

Then go to the yum source and configure

If there are plugins=1 then change it to 0, not adding them.

Apache2 cannot be started and an error is reported for apache2.service failed because the control process exited with error code.

Today, when I was preparing to use Kali to build a website, The Apache server could not run normally. After patiently understanding the error code and Baidu finally solved the problem.
1. Error problem:
When you started apache2, the following error occurred. At first I thought it was not root, but switching to root still reported an error.

root@kali:/root# service apache2 start
Job for apache2.service failed because the control process exited with error code.
See "systemctl  status apache2.service" and "journalctl  -xe" for details.

At that time, I felt that KALI had not been used for a long time, because the software package was too old, so I updated it first.

root@kali:~# apt-get update

But the same error is reported, so you view the error message through the apache2 –help command.

apache2 --help
[Mon Apr 13 23:45:17.772837 2020] [core:warn] [pid 24587] AH00111: Config variable ${APACHE_RUN_DIR} is not defined
apache2: Syntax error on line 80 of /etc/apache2/apache2.conf: DefaultRuntimeDir must be a valid directory, absolute or relative to ServerRoot

No new Apache environment variables were imported due to a change in the Apache configuration file after the upgrade. Solutions:

source /etc/apache2/envvars

Update later and still report an error, but the error message is different. The reasons for the error are:

root@kali:/root# apache2 --help
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
(98)Address already in use: AH00072: make_sock: could not bind to address [::]:80
(98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80
no listening sockets available, shutting down
AH00015: Unable to open logs

2. Solution:
Through the error code, we can know that it should not be able to bind to port 80, because the default port of Apache is 80. Of course, now there are two choices, one is to kill the process occupying the port, and the other is the better default port of Apache. I choose the first one.
First look at what process is occupying the port.

root@kali:/root# netstat -lnp|grep 80
tcp        0      0 127.0.0.1:80            0.0.0.0:*               LISTEN      18594/gsad          
unix  2      [ ACC ]     STREAM     LISTENING     18198    808/VGAuthService    /var/run/vmware/guestServicePipe

Then kill the process.

root@kali:/root# kill -9 18594

Finally, apache2 was successfully restarted.

root@kali:/root# /etc/init.d/apache2 start
[ ok ] Starting apache2 (via systemctl): apache2.service.

You can also change the default port for apache2, as shown in the response on StackOverflow.

gradle sync failed CreateProcess error=267 directory is invalid

Gradle Sync Failed CreateProcess Error =267 directory invalid
There was no problem with the import of the company’s project at the beginning, but it was turned off. After starting up the next day, an error was reported:

CreateProcess Error =267 directory name invalid

After searching on Bing for a long time, I couldn’t find a corresponding solution, so I asked for help from my predecessors.
The elder say: you see, somebody said the directory name is invalid, so you just change the directory (project) name.
There is an & AMP in the project name; The sign, I’ll just change it to _.

a& B – & gt; a_b

Delete the.imL file in the project with the same name as the project name and reimport it. Problem solving.

A&amp was deleted from the project; B.i ml file.

 

Error encountered when running WCF

HTTP could not register URL http://+:3723/CalulatorService/.
Your process does not have access rights to this namespace (see http://go.microsoft.com/fwlink/?LinkId=70353 for details).

The reason for this problem is a lack of permissions.
This doesn’t happen if you’re just logged in as a standalone system administrator, it does happen when you log in with a domain user,
Open program -> attachment -> Command Prompt
Enter the following statement to register.
Netsh HTTP add urlacl url=http://+:3723/CalulatorService/ user= domain name/user name

Just run it again.
If you report this error:
Create SDDL failed, Error: 1332 The parameter is incorrect.
You change the port number.

OpenCV3.1 + Python2.7 error “DLL load failed: The specified module could not be found”

According to the web site [http://docs.opencv.org/3.1.0/d5/de5/tutorial_py_setup_in_windows.html] method 2 manual compiled OpenCV3.1.0 and install python.
but error “DLL load failed: The specified module could not be found” appears when importing cv2.
I looked for the following reasons online, the possible reason is that
1) opencv and python corresponding versions are different, such as one is 32bit and one is 64bit. Pyd
2) did not add cv2.pyd to C:/Python27/lib/site-packages
3) system environment variable could not be found cv2.pyd
the final solution to my computer problem was:
add [C:\ opencv-3.1.0 \build\bin\Release] to system environment variable.

How to Fix Failed to add the host to the list of known hosts

The first mistake you encounter might be

    Macintosh:Permissions 0755 for '/User/xxxx/.ssh/id_rsa' are too open.
    Linux:Permissions 0755 for '/home/xxxx/.ssh/id_rsa' are too open.

This means that your private key permissions are too large, so only you need to operate

    sudo chmod 600 ~/.ssh/id_rsa sudo chmod 600 ~/.ssh/id_rsa.pub

The known_hosts file has a problem with permissions when you encounter the following situation

    Are you sure you want to continue connecting (yes/no)?yes Failed to add the host to the list of known hosts

Execute this command

    sudo chmod 644 ~/.ssh/known_hosts

Finally, to get your.ssh folder permissions right, execute the following command

    sudo chmod 755 ~/.ssh

Then your.ssh folder and the private and public key permissions within it are resolved!

Build LNMPR Error — php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution

background
After installing Ubuntu subsystem in Win10 system, L(Linux)N(Nginx)M(mysql)P(PHP)R(Redis) environment was set up.
The error message
php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution
The screening process

    check whether the services of nginx, php-fpm and redis-server are started normally; sudo /etc/init.d/nginx status check whether win10 can ping the ubuntu subsystem; Check if Redis configuration is correct; Check that Hosts is configured correctly;
is finally determined that DNS cannot be resolved normally, and DNS configuration

needs to be modified
The solution
Gateway configuration:
, 1 sudo vi/etc/resolvconf resolv. Conf., d/base

# 添加下面网关(223.5.5.5 和 223.6.6.6 是阿里的网关)

nameserver 223.5.5.5
nameserver 223.6.6.6

2, sudo resolvconf-u will synchronize the configured DNS to /etc/resolv.conf
3, check vi /etc/resolv.conf whether there is a newly configured DNS
4. Restart PHP sudo /etc/init.d/php-fpm restart