转自: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) >> ) & 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 :; /* never has lp0 */
unsigned int reserve_lp1 :; /* never has lp1 */
unsigned int reserve_lp2 :; /* never has lp2 */
unsigned int soft_reboot :; /* 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 = { };
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(), S3C2410_GPC0_LEND); /* Turn the backlight early on */
WARN_ON(gpio_request(S3C2410_GPG(), "backlight"));
gpio_direction_output(S3C2410_GPG(), ); /* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */
s3c_gpio_setpull(S3C2410_GPB(), S3C_GPIO_PULL_UP);
s3c2410_gpio_setpin(S3C2410_GPB(), );
s3c_gpio_cfgpin(S3C2410_GPB(), S3C2410_GPIO_INPUT); /* Make sure the D+ pullup pin is output */
WARN_ON(gpio_request(S3C2410_GPC(), "udc pup"));
gpio_direction_output(S3C2410_GPC(), ); /* mark the key as input, without pullups (there is one on the board) */
for (i = ; 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 != -) {
int li; mini2440_fb_info.displays =
&mini2440_lcd_cfg[features.lcd_index]; printk(KERN_INFO "MINI2440: LCD");
for (li = ; 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(, 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 ; } arch_initcall(customize_machine); 在MACHINE_START与MACHINE_END之间还要填写一些参数,参照结构体注释小心填写即可,最好找个例子参考参考。

MACHINE_START与MACHINE_END【转】的更多相关文章

  1. linux中MACHINE_START&END在9g10ek上实现

    在linux的板卡初始化文件中有machine的相关定义 //arch/arm/mach-at91/board-sam9261ek.c MACHINE_START(AT91SAM9G10EK, &qu ...

  2. ARM Linux 3.x的设备树(Device Tree)

    http://blog.csdn.net/21cnbao/article/details/8457546 宋宝华 Barry Song <21cnbao@gmail.com> 1.     ...

  3. ARM Linux 3.x的设备树(Device Tree)

    1. ARM Device Tree起源 Linus Torvalds在2011年3月17日的ARM Linux邮件列表宣称“this whole ARM thing is a f*cking pai ...

  4. platform_device与platform_driver

    转自:http://blog.csdn.net/zhandoushi1982/article/details/5130207 做Linux方面也有三个多月了,对代码中的有些结构一直不是很明白,比如pl ...

  5. 【转】 ARM Linux 3.x的设备树(Device Tree)

    1.    ARM Device Tree起源 http://blog.csdn.net/21cnbao/article/details/8457546 Linus Torvalds在2011年3月1 ...

  6. 基于linux2.6.38.8内核启动过程完全解析[一]

    转载: ************************************************************************************************ ...

  7. ARM-Linux S5PV210 UART驱动(6)----platform device的添加

    开发板是飞凌OK210 arch/arm/mach-s5pv210/mach-smdkc110.c 首先是UART的寄存器默认配置信息: /* Following are default values ...

  8. 【转】ARM Linux 3.x的设备树(Device Tree)

    原文网址:http://blog.csdn.net/21cnbao/article/details/8457546 1.    ARM Device Tree起源 Linus Torvalds在201 ...

  9. 移植Linux-3.4.2内核到S3C2440

    一.BootLoader引导内核过程     1.Bootloader的工作     1.1.将内核读入内存     2.2.保存内核启动参数到指定位置,内核启动时去这个位置解析参数     3.3. ...

随机推荐

  1. deep learning3

    9.3.Restricted Boltzmann Machine (RBM)受限玻尔兹曼基 假设有一个二部图,每一层的节点之间没有链接,一层是可视层,即输入数据层(v),一层是隐藏层(h),如果假设所 ...

  2. 【bzoj3036】绿豆蛙的归宿 期望dp

    题目描述 随着新版百度空间的下线,Blog宠物绿豆蛙完成了它的使命,去寻找它新的归宿. 给出一个有向无环的连通图,起点为1终点为N,每条边都有一个长度.绿豆蛙从起点出发,走向终点.到达每一个顶点时,如 ...

  3. bzoj1588 [HNOI2002]营业额统计 (treap)

    平衡树裸题 只需要求前驱后驱 treap写法 const mm=<<; maxnumber=; maxn=; var left,right,fix,key:..maxn]of longin ...

  4. 周记【距gdoi:133天】

    蔡大神坚持每天写日记记录他所剩的oi生涯. 可是我呢?自从搞完数据结构后都不知道在干什么,整天在傻叉.也许是给自己压力太大了,或许是真的自己在迷茫以及犹豫,更或者自己真的是想太多不想写题,觉得烦了,没 ...

  5. HDU4812 D tree 【点分治 + 乘法逆元】

    D树 时间限制:10000/5000 MS(Java / Others)内存限制:102400/102400 K(Java / Others) 总共提交5400个已接受的提交1144 问题描述 南京理 ...

  6. bzoj2431: [HAOI2009]逆序对数列(DP)

    f[i][j]前i个数有j个逆序对的数量 f[i][j]=sigma(f[i-1][j-k]){1<=k<=i} 维护一个前缀和即可 #include<iostream> #i ...

  7. 20181022 考试记录&高级数据结构

    题目 W神爷的题解 高级数据结构 T1: 其实是一道easy题,$O(n^3log n)$ 也是能卡过去的,本着要的70分的心态,最后尽然A了. 如果是正解则是$O(n^3)$,当确定你要选择的列时, ...

  8. GYM 101875 2018 USP-ICMC

    3月自训 (1):10/12 A: 题意:每个人可以连边,最远连到第(i+k)%n个人,边权为这个人与另一个人连边距离,求生成一颗最大生成树的权值和是多少 题解:可以证明的是,我们每一个人都向接下来的 ...

  9. 轮廓算法的结果验证工具/How to validate the outline output

    因为轮廓算法的结果通过直接观察输出很难判断结果的正确性. 但是如果把输入和输出同时绘制出来,用眼睛判别则相对简单许多. 输入建筑的文件内容格式为,粗体格式为建筑高度: 10 110 5020 60 7 ...

  10. radio is checked

    var is_rec =$("#is_rec_on").is(':checked'); if(is_rec){ $('.rec_img').css('display','block ...