Chinaunix首页 | 论坛 | 博客
  • 博客访问: 243884
  • 博文数量: 49
  • 博客积分: 1595
  • 博客等级: 上尉
  • 技术积分: 497
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-21 15:22
文章分类

全部博文(49)

文章存档

2011年(19)

2010年(30)

我的朋友

分类: LINUX

2011-04-06 16:17:01

对于那些常用的处理器,linux内核的移植工作是非常简单的。对于不太常用的处理器,我们只能自己寻求解决方法了。下面以sep4020为例,对此做一些说明。

linux/arch/arm中有很多mach-xx的文件夹,完成这里的函数编写,就是我们的主要工作,我们把mach-sep4020打开,里面最重要的是一个4020.c文件。在这个文件的最后有MACHINE_START(GFD4020, "4020 board")

       .phys_io  = 0x10000000,

       .io_pg_offst    = ((0xe0000000) >> 18) & 0xfffc,

       .boot_params  = 0x30000100,

       .fixup             = fixup_gfd4020,

       .map_io          = sep4020_map_io,

       .init_irq   =  sep4020_init_irq,

       .init_machine  = sep4020_init,

       .timer             = &sep4020_timer,

MACHINE_END

这样一段内容,MACHINE_START MACHINE_END是宏定义,在include/asm-arm/mach/arch.h中,可以找到此定义

#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 \

};

       从上面的内容,我们可以看出这段宏定义对应了一个machine_desc的结构体,这个结构体的定义如下:

 

struct machine_desc {

?? unsigned int nr; //电路板序号

?? unsigned int phys_ram; //内存起始物理地址

?? unsigned int phys_io;//io内存物理地址

?? unsigned int io_pg_offst;//io内存页表偏移值

?? const char *name;//设备名称

?? unsigned long boot_params;//bootloader传递参数首物理地址
?? unsigned int video_start;//
视频RAM起始地址
?? unsigned int video_end; //
视频RAM结束地址
?? unsigned int reserve_lp0 :1;
?? unsigned int reserve_lp1 :1;
?? unsigned int reserve_lp2 :1;//
设置的3个打印口
?? unsigned int soft_reboot :1;//
软重启
?? void (*fixup)(struct machine_desc *, struct tag *, char **,?? struct meminfo *);??

 void (*map_io)(void); //为电路板上所有平台设备建立静态映射页表和各种初始化设置
?? void (*init_irq)(void); //
中断初始化
?? struct sys_timer *timer;//
系统tick初始化
?? void (*init_machine)(void); //
设备初始化一般完成注册平台设备和LED配置以及电源初始化
};

其实我们移植的工作主要就是给上面的这个结构体初始化。我们再来看一下

MACHINE_START(GFD4020, "4020 board")

       .phys_io  = 0x10000000,

       .io_pg_offst    = ((0xe0000000) >> 18) & 0xfffc,

       .boot_params  = 0x30000100,

       .fixup             = fixup_gfd4020,

       .map_io          = sep4020_map_io,

       .init_irq   =  sep4020_init_irq,

       .init_machine  = sep4020_init,

       .timer             = &sep4020_timer,

MACHINE_END

 

GFD4020 mini2440开发板在linux中的机器号。

       "4020 board"是开发板信息,在终端输入cat /proc/cpuinfo可以查看。

MACHINE_START主要是定义了"struct machine_desc"的类型,放在 section(".arch.info.init"),是初始化数据,Kernel 起来之后将被丢弃。

其余各个成员函数在setup_arch()中被赋值到内核结构体,在不同时期被调用:

1. .init_machine arch/arm/kernel/setup.c 中被 customize_machine 调用,放在 arch_initcall() 段里面,会自动按顺序被调用。

2. .init_irqstart_kernel() --> init_IRQ() --> init_arch_irq()中被调用

3. .map_io setup_arch() --> paging_init() --> devicemaps_init()中被调用

4. .timer是定义系统时钟,在start_kernel() --> time_init()中被调用。

5. .boot_paramsbootloader向内核传递的参数的位置,这要和bootloader中参数的定义要一致。

其他主要都在 setup_arch() 中用到。

通过上面的了解,我们可以发现移植的主要工作是编写machine_desc里面的几个函数,对于sep4020我们主要编写的函数主要有fixup_gfd4020sep4020_map_iosep4020_init_irq,

sep4020_initsep4020_timer等。

阅读(1579) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~