환경

Kernel 사용하면서 발생하는 이슈와 그에 대한 해결방법을 이 페이지에 기록한다

분석

#define MACHINE_START(_type,_name)          \\
static const struct machine_desc __mach_desc_##_type    \\
 __used                         \\
 __section(".arch.info.init") = {           \\
    .nr     = MACH_TYPE_##_type,        \\
    .name       = _name,

#define MACHINE_END             \\
};

#define DT_MACHINE_START(_name, _namestr)       \\
static const struct machine_desc __mach_desc_##_name    \\
 __used                         \\
 __section(".arch.info.init") = {           \\
    .nr     = ~0,               \\
    .name       = _namestr,
#endif
struct machine_desc {
    unsigned int         nr ;              /* architecture number    */
    const char         * name ;            /* architecture name      */
    unsigned long        atag_offset ;     /* tagged list (relative) */
    const char * const * dt_compat ;       /* array of device tree 
                                            * 'compatible' strings   */

    unsigned int         nr_irqs ;         /* number of IRQs         */

#ifdef CONFIG_ZONE_DMA
    phys_addr_t          dma_zone_size ;   /* size of DMA-able area  */
#endif

    unsigned int         video_start ;     /* start of video RAM     */
    unsigned int         video_end ;       /* end of video RAM       */

    unsigned char        reserve_lp0 : 1 ; /* never has lp0          */
    unsigned char        reserve_lp1 : 1 ; /* never has lp1          */
    unsigned char        reserve_lp2 : 1 ; /* never has lp2          */
    enum reboot_mode     reboot_mode ;     /* default restart mode   */
    unsigned             l2c_aux_val ;     /* L2 cache aux value     */
    unsigned             l2c_aux_mask ;    /* L2 cache aux mask      */

    void             ( * l2c_write_sec )( unsigned long , unsigned ) ;

    const struct smp_operations * smp ;    /* SMP operations         */

    bool             ( * smp_init     )( void ) ;
    void             ( * fixup        )( struct tag * , char ** ) ;
    void             ( * dt_fixup     )( void ) ;
    long long        ( * pv_fixup     )( void ) ;
    void             ( * reserve      )( void ) ; /* reserve mem blocks   */
    void             ( * map_io       )( void ) ; /* IO mapping function  */
    void             ( * init_early   )( void ) ;
    void             ( * init_irq     )( void ) ;
    void             ( * init_time    )( void ) ;
    void             ( * init_machine )( void ) ;
    void             ( * init_late    )( void ) ;
    void             ( * restart      )( enum reboot_mode , const char * ) ; 
} ;

# poweroff 는 struct machine_desc에 존재하지 않음

/**
 *  do_kernel_power_off - Execute kernel power-off handler call chain
 *
 *  Expected to be called as last step of the power-off sequence.
 *
 *  Powers off the system immediately if a power-off handler function has
 *  been registered. Otherwise does nothing.
 */
void do_kernel_power_off( void )
{
    struct sys_off_handler * sys_off = NULL ;

    /*   
     * Register sys-off handlers for legacy PM callback. This allows
     * legacy PM callbacks temporary co-exist with the new sys-off API.
     *
     * TODO: Remove legacy handlers once all legacy PM users will be
     *       switched to the sys-off based APIs.
     */
    if( pm_power_off )
        sys_off = register_sys_off_handler( SYS_OFF_MODE_POWER_OFF ,
                           SYS_OFF_PRIO_DEFAULT ,
                           legacy_pm_power_off  , NULL ) ;

    atomic_notifier_call_chain( & power_off_handler_list , 0 , NULL ) ;

    unregister_sys_off_handler( sys_off ) ;
}