免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5583 | 回复: 5
打印 上一主题 下一主题

[操作系统] init_arch_irq归根结底是怎样被赋值的? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-05-29 13:27 |只看该作者 |倒序浏览
在看源码的时候遇到了RT的问题。
下面是我跟踪的思路:

初始化IRQ
start_kernel  -> init_IRQ ->  init_arch_irq();

这里,这个init_arch_irq 的值由 arch/arm/kernel/setup.c文件里面 setup_arch  函数中的: init_arch_irq = mdesc->init_irq;  来给定。

那,这个mdesc 由该函数中: mdesc = setup_machine(machine_arch_type); 来给定。

而setup_machine函数又调用了: lookup_machine_type(nr);
lookup_machine_type位于:
arch/arm/kernel/head-common.c

  1. ENTRY(lookup_machine_type)
  2.     stmfd   sp!, {r4 - r6, lr}
  3.     mov r1, r0
  4.     bl  __lookup_machine_type
  5.     mov r0, r5
  6.     ldmfd   sp!, {r4 - r6, pc}
复制代码
__lookup_machine_type位于同一文件中:

  1. .type   __lookup_machine_type, %function
  2. __lookup_machine_type:
  3.     adr r3, 3b
  4.     ldmia   r3, {r4, r5, r6}
  5.     sub r3, r3, r4          @ get offset between virt&phys
  6.     add r5, r5, r3          @ convert virt addresses to
  7.     add r6, r6, r3          @ physical address space
  8. 1:  ldr r3, [r5, #MACHINFO_TYPE]    @ get machine type
  9.     teq r3, r1              @ matches loader number?
  10.     beq 2f              @ found
  11.     add r5, r5, #SIZEOF_MACHINE_DESC    @ next machine_desc
  12.     cmp r5, r6
  13.     blo 1b
  14.     mov r5, #0              @ unknown machine
  15. 2:  mov pc, lr
复制代码
到这里应该是把machine_type找到了,可是,最终init_irq是怎样被赋值的,也就是:mdesc->init_irq 在何时被赋值的?

论坛徽章:
0
2 [报告]
发表于 2010-05-29 17:06 |只看该作者
看看这篇文章你应该就明白了
http://blog.chinaunix.net/u2/76349/showart_2194431.html

论坛徽章:
0
3 [报告]
发表于 2010-05-30 08:37 |只看该作者
谢谢楼上。已经明白了。

论坛徽章:
0
4 [报告]
发表于 2011-10-20 16:01 |只看该作者
  1. 到这里应该是把machine_type找到了,可是,最终init_irq是怎样被赋值的,也就是:mdesc->init_irq 在何时被赋值的?
复制代码
朋友这到底是怎么赋值的呢? 可否道来。。。。

论坛徽章:
0
5 [报告]
发表于 2011-10-20 16:16 |只看该作者
遍历源代码。。终于我找到了这个

MACHINE_START(S3C2440, "SMDK2440"
        /* Maintainer: Ben Dooks <ben@fluff.org> */
        .phys_io        = S3C2410_PA_UART,
        .io_pg_offst        = (((u32)S3C24XX_VA_UART) >> 1 & 0xfffc,
        .boot_params        = S3C2410_SDRAM_PA + 0x100,

        .init_irq        = s3c24xx_init_irq,
        .map_io                = smdk2440_map_io,
        .init_machine        = smdk2440_machine_init,
        .timer                = &s3c24xx_timer,
MACHINE_END

但是有这样个问题,以前从没有见过
MACHINE_START(S3C2440, "SMDK2440"
。。。。。。。。。。。
MACHINE_END
这又是怎么样的一个结构呢?如何执行的呢?

论坛徽章:
0
6 [报告]
发表于 2011-10-20 16:44 |只看该作者
在友善mini2440提供的linux2.6.32.2内核中,有如下定义:
MACHINE_START(MINI2440, "FriendlyARM Mini2440 development board"
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 1 & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,

.init_irq = s3c24xx_init_irq,
.map_io = mini2440_map_io,
.init_machine = mini2440_machine_init,
.timer = &s3c24xx_timer,
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_io;
unsigned int io_pg_offst;

const char *name;
unsigned long boot_params;

unsigned int video_start;
unsigned int video_end;

unsigned int reserve_lp0 :1;
unsigned int reserve_lp1 :1;
unsigned int reserve_lp2 :1;
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;
void (*init_machine)(void);
};


按定义展开后:
static const struct machine_desc __mach_desc_MINI2440 \
__used \
__attribute__((__section__(".arch.info.init")) = {
.nr = MACH_TYPE_MINI2440,
.name = "FriendlyARM Mini2440 development board",
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 1 & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.init_irq = s3c24xx_init_irq,
.map_io = mini2440_map_io,
.init_machine = mini2440_machine_init,
.timer = &s3c24xx_timer,
};
MACH_TYPE_MINI2440 是mini2440开发板在linux中的机器号。
"FriendlyARM Mini2440 development 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_irq在start_kernel() --> init_IRQ() --> init_arch_irq()中被调用
3. .map_io 在 setup_arch() --> paging_init() --> devicemaps_init()中被调用
4. .timer是定义系统时钟,定义TIMER4为系统时钟,在arch/arm/plat-s3c/time.c中体现。在start_kernel() --> time_init()中被调用。
5. .boot_params是bootloader向内核传递的参数的位置,这要和bootloader中参数的定义要一致。

其他主要都在 setup_arch() 中用到。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP