MACHINE_START与MACHINE_END【转】

简介:

转自:http://blog.csdn.net/cxw3506/article/details/8475965

复制代码
版权声明:本文为博主原创文章,未经博主允许不得转载。

在移植Linux时,有个结构体需要填写,它以MACHINE_START开始并以MACHINE_END结束,如下mini2440开发板的移植为示例
[cpp] view plain copy

    MACHINE_START(MINI2440, "MINI2440")  
        .phys_io    = S3C2410_PA_UART,  
        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,  
        .boot_params    = S3C2410_SDRAM_PA + 0x100,  
        .map_io     = mini2440_map_io,  
        .init_machine   = mini2440_init,  
        .init_irq   = s3c24xx_init_irq,  
        .timer      = &s3c24xx_timer,  
    MACHINE_END  



其中MACHINE_START、MACHINE_END都是定义的宏,代码如下
[cpp] view plain copy

    /* 
     * Set of macros to define architecture features.  This is built into 
     * a table by the linker. 
     */  
    #define MACHINE_START(_type,_name)          \  
    static const struct machine_desc __mach_desc_##_type    \  
     __used                         \  
     __attribute__((__section__(".arch.info.init"))) = {    \  
        .nr     = MACH_TYPE_##_type,        \  
        .name       = _name,  
      
    #define MACHINE_END             \  
    };  



由上代码可知这两个宏一起定义了一个类型为struct machine_desc的变量,结构体定义如下
[cpp] view plain copy

    struct machine_desc {  
        /* 
         * Note! The first four elements are used 
         * by assembler code in head.S, head-common.S 
         */  
        unsigned int        nr;     /* architecture number  */  
        unsigned int        phys_io;    /* start of physical io */  
        unsigned int        io_pg_offst;    /* byte offset for io  
                             * page tabe entry  */  
      
        const char      *name;      /* architecture name    */  
        unsigned long       boot_params;    /* tagged list      */  
      
        unsigned int        video_start;    /* start of video RAM   */  
        unsigned int        video_end;  /* end of video RAM */  
      
        unsigned int        reserve_lp0 :1; /* never has lp0    */  
        unsigned int        reserve_lp1 :1; /* never has lp1    */  
        unsigned int        reserve_lp2 :1; /* never has lp2    */  
        unsigned int        soft_reboot :1; /* soft reboot      */  
        void            (*fixup)(struct machine_desc *,  
                         struct tag *, char **,  
                         struct meminfo *);  
        void            (*map_io)(void);/* IO mapping function  */  
        void            (*init_irq)(void);  
        struct sys_timer    *timer;     /* system tick timer    */  
        void            (*init_machine)(void);  
    };  



这个类型的变量放在内核代码段.arch.info.init中,在内核运行初期,被函数lookup_machine_type(此函数用汇编实现,在汇编文件中)取出,读取流程为

Start_kernel() -> setup_arch() -> setup_machine() -> lookup_machine_type()

在函数setup_machine()中,利用这个结构体类型的变量初始化一些全局变量,以备内核运行时使用,比如

init_arch_irq = mdesc->init_irq;

       system_timer = mdesc->timer;

       init_machine = mdesc->init_machine;

 

这个结构体中,成员init_machine保存的是开发板资源注册的初始化代码,init_irq保存的是中断初始化指针,timer保存的是一个struct sys_timer类型的指针…..如果我们要给自己的开发板定制内核,那么我们必须自己实现以上成员函数,其中函数init_machine()是我们向内核传递开发板设备信息的重要的常规途径,分析mini2440开发板内核移植代码知道,在这个函数中,注册了开发板所用到的所有设备的相关硬件信息!

[cpp] view plain copy

    static void __init mini2440_init(void)  
    {  
        struct mini2440_features_t features = { 0 };  
        int i;  
      
        printk(KERN_INFO "MINI2440: Option string mini2440=%s\n",  
                mini2440_features_str);  
      
        /* Parse the feature string */  
        mini2440_parse_features(&features, mini2440_features_str);  
      
        /* turn LCD on */  
        s3c_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);  
      
        /* Turn the backlight early on */  
        WARN_ON(gpio_request(S3C2410_GPG(4), "backlight"));  
        gpio_direction_output(S3C2410_GPG(4), 1);  
      
        /* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */  
        s3c_gpio_setpull(S3C2410_GPB(1), S3C_GPIO_PULL_UP);  
        s3c2410_gpio_setpin(S3C2410_GPB(1), 0);  
        s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT);  
      
        /* Make sure the D+ pullup pin is output */  
        WARN_ON(gpio_request(S3C2410_GPC(5), "udc pup"));  
        gpio_direction_output(S3C2410_GPC(5), 0);  
      
        /* mark the key as input, without pullups (there is one on the board) */  
        for (i = 0; i < ARRAY_SIZE(mini2440_buttons); i++) {  
            s3c_gpio_setpull(mini2440_buttons[i].gpio, S3C_GPIO_PULL_UP);  
            s3c_gpio_cfgpin(mini2440_buttons[i].gpio, S3C2410_GPIO_INPUT);  
        }  
        if (features.lcd_index != -1) {  
            int li;  
      
            mini2440_fb_info.displays =  
                &mini2440_lcd_cfg[features.lcd_index];  
      
            printk(KERN_INFO "MINI2440: LCD");  
            for (li = 0; li < ARRAY_SIZE(mini2440_lcd_cfg); li++)  
                if (li == features.lcd_index)  
                    printk(" [%d:%dx%d]", li,  
                        mini2440_lcd_cfg[li].width,  
                        mini2440_lcd_cfg[li].height);  
                else  
                    printk(" %d:%dx%d", li,  
                        mini2440_lcd_cfg[li].width,  
                        mini2440_lcd_cfg[li].height);  
            printk("\n");  
            s3c24xx_fb_set_platdata(&mini2440_fb_info);  
        }  
      
        s3c24xx_udc_set_platdata(&mini2440_udc_cfg);  
        s3c24xx_mci_set_platdata(&mini2440_mmc_cfg);  
        s3c_nand_set_platdata(&mini2440_nand_info);  
        s3c_i2c0_set_platdata(NULL);  
      
        i2c_register_board_info(0, mini2440_i2c_devs,  
                    ARRAY_SIZE(mini2440_i2c_devs));  
      
        platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));  
      
        if (features.count) /* the optional features */  
            platform_add_devices(features.optional, features.count);  
      
    }  



那么成员函数init_machine什么时候被调用呢?

在函数setup_machine()中有一条语句init_machine = mdesc->init_machine;其中init_machine为全局函数指针变量,此变量在函数customize_machine()中被调用,代码如下所示:
[cpp] view plain copy

    static int __init customize_machine(void)  
      
    {  
      
           /* customizes platform devices, or adds new ones */  
      
           if (init_machine)  
      
                  init_machine();  
      
           return 0;  
      
    }  
      
    arch_initcall(customize_machine);  




在MACHINE_START与MACHINE_END之间还要填写一些参数,参照结构体注释小心填写即可,最好找个例子参考参考。
复制代码

 






本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sky-heaven/p/7229288.html,如需转载请自行联系原作者

相关文章
|
2天前
|
弹性计算 人工智能 安全
云上十五年——「弹性计算十五周年」系列客户故事(第二期)
阿里云弹性计算十五年深耕,以第九代ECS g9i实例引领算力革新。携手海尔三翼鸟、小鹏汽车、微帧科技等企业,实现性能跃升与成本优化,赋能AI、物联网、智能驾驶等前沿场景,共绘云端增长新图景。
|
8天前
|
存储 弹性计算 人工智能
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
2025年9月24日,阿里云弹性计算团队多位产品、技术专家及服务器团队技术专家共同在【2025云栖大会】现场带来了《通用计算产品发布与行业实践》的专场论坛,本论坛聚焦弹性计算多款通用算力产品发布。同时,ECS云服务器安全能力、资源售卖模式、计算AI助手等用户体验关键环节也宣布升级,让用云更简单、更智能。海尔三翼鸟云服务负责人刘建锋先生作为特邀嘉宾,莅临现场分享了关于阿里云ECS g9i推动AIoT平台的场景落地实践。
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
|
7天前
|
人工智能 自然语言处理 自动驾驶
关于举办首届全国大学生“启真问智”人工智能模型&智能体大赛决赛的通知
关于举办首届全国大学生“启真问智”人工智能模型&智能体大赛决赛的通知
|
7天前
|
云安全 人工智能 自然语言处理
阿里云x硅基流动:AI安全护栏助力构建可信模型生态
阿里云AI安全护栏:大模型的“智能过滤系统”。
|
8天前
|
编解码 自然语言处理 文字识别
Qwen3-VL再添丁!4B/8B Dense模型开源,更轻量,仍强大
凌晨,Qwen3-VL系列再添新成员——Dense架构的Qwen3-VL-8B、Qwen3-VL-4B 模型,本地部署友好,并完整保留了Qwen3-VL的全部表现,评测指标表现优秀。
628 7
Qwen3-VL再添丁!4B/8B Dense模型开源,更轻量,仍强大
|
10天前
|
存储 机器学习/深度学习 人工智能
大模型微调技术:LoRA原理与实践
本文深入解析大语言模型微调中的关键技术——低秩自适应(LoRA)。通过分析全参数微调的计算瓶颈,详细阐述LoRA的数学原理、实现机制和优势特点。文章包含完整的PyTorch实现代码、性能对比实验以及实际应用场景,为开发者提供高效微调大模型的实践指南。
754 2