您的位置:首页 > 运维架构 > Linux

[转载] linux启动流程分析(4)---汇编部分(3)

2010-01-02 09:45 453 查看
原文地址:http://www.eetop.cn/blog/html/45/11145-1512.html

================================

Author: taoyuetao

Email:tao_yuetao@yahoo.com.cn

Blog:http://www.eetop.cn/blog/?11145

2007-03-08

================================

前一篇介绍了汇编函数__lookup_processor_type,这一篇介绍__lookup_architecture_type函数

函数__lookup_architecture_type介绍:

每个机器(一般指的是某一个电路板)都有自己的特殊结构,如物理内存地址,物理I/O地址,显存起始地址等等,

这个结构为struct machine_desc,定义在asm-arm/mach/arch.h中:

struct machine_desc {

/*

* Note! The first four elements are used

* by assembler code in head-armv.S

*/

unsigned intnr;/* architecture number*/

unsigned intphys_ram;/* start of physical ram */

unsigned intphys_io;/* start of physical io*/

unsigned intio_pg_offst;/* byte offset for io page table entry*/

const char*name;/* architecture name*/

unsigned intparam_offset;/* parameter page*/

unsigned intvideo_start;/* start of video RAM*/

unsigned intvideo_end;/* end of video RAM*/

unsigned intreserve_lp0 :1;/* never has lp0*/,

unsigned intreserve_lp1 :1;/* never has lp1*/

unsigned intreserve_lp2 :1;/* never has lp2*/

unsigned intsoft_reboot :1;/* soft reboot*/

void(*fixup)(struct machine_desc *,

struct param_struct *, char **,

struct meminfo *);

void(*map_io)(void);/* IO mapping function*/

void(*init_irq)(void);

};

这个结构一般都定义在(以arm平台为例)kernel/arch/arm/mach-xxx/xxx.c中,是用宏来定义的,以mainstone的开发板为例:

定义在kernel/arch/arm/mach-pxa/mainstone.c文件中,如下所示:

MACHINE_START(MAINSTONE, "Intel DBBVA0 Development Platform")

MAINTAINER("MontaVista Software Inc.")

BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))

FIXUP(fixup_mainstone)

MAPIO(mainstone_map_io)

INITIRQ(mainstone_init_irq)

MACHINE_END

这些宏也定义在kernel/include/asm-arm/mach/arch.h中,以MACHINE_START为例:

#define MACHINE_START(_type,_name) /

const struct machine_desc __mach_desc_##_type /

__attribute__((__section__(".arch.info"))) = { /

.nr = MACH_TYPE_##_type, /

.name = _name,

展开之后结构的是:

__mach_desc_MAINSTONE = {

.nr = MACH_TYPE_MAINSTIONE,

.name = "Intel DBBVA0 Development Platform",

中间的1行__attribute__((__section__(".arch.info"))) = {说明将这个结构放到指定的段.arch.info中,这和前面的

.proc.info是一个意思,__attribute__((__section__的含义参考GNU

手册。后面的宏都是类似的含义,这里就不再一一

介绍。下面开始说明源码:

第1行实现r4指向2b的地址,2b如__lookup_processor_type介绍的第19行,将machine_desc结构中的数据存放到r2, r3, r5, r6, r7。

读取__mach_desc_MAINSTONE结构中的nr参数到r5中,如第7行,比较r5和r1中的机器编号是否相同,如第8行,

r5中的nr值MACH_TYPE_MAINSTONE定义在kernel/include/asm-arm/mach-types.h中:

#define MACH_TYPE_MAINSTONE 303

r1中的值是由bootloader

传递过来的,这在<<linux启动流程分析(1)---bootloader启动内核过程>>中有说明,

如果机器编号相同,跳到15行执行,r5=intphys_ram,r6=intphys_io,r7=intio_pg_offst,并返回。如果

不同则将地址指针增加,在跳到7行继续查找,如10--12行的代码,如果检索完所有的machine_desc仍然没

有找到则将r7清零并返回。

/*

* Lookup machine architecture in the linker-build list of architectures.

* Note that we can't use the absolute addresses for the __arch_info

* lists since we aren't running with the MMU on (and therefore, we are

* not in the correct address space). We have to calculate the offset.

*

* r1 = machine architecture number

* Returns:

* r2, r3, r4 corrupted

* r5 = physical start address of RAM

* r6 = physical address of IO

* r7 = byte offset into page tables for IO

*/

1 __lookup_architecture_type:

2 adr r4, 2b

3 ldmia r4, {r2, r3, r5, r6, r7} @ throw away r2, r3

4 sub r5, r4, r5 @ convert addresses

5 add r4, r6, r5 @ to our address space

6 add r7, r7, r5

7 1: ldr r5, [r4] @ get machine type

8 teq r5, r1

9 beq 2f

10 add r4, r4, #SIZEOF_MACHINE_DESC

11 cmp r4, r7

12 blt 1b

13 mov r7, #0 @ unknown architecture

14 mov pc, lr

15 2: ldmib r4, {r5, r6, r7} @ found, get results

16 mov pc, lr
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: