先列出框架,具体后继再来分析。

首先是lds文件,该文件设置了各个section在FLASH或RAM中的先后顺序。

位于~/openwrt1407/build_dir/target-mips_34kc_uClibc-0.9.33.2/linux-ar71xx_generic/linux-3.10.49/arch/mips/kernel/vmlinux.lds

另外一个名字相似的,~/openwrt1407/build_dir/target-mips_34kc_uClibc-0.9.33.2/linux-ar71xx_generic/linux-3.10.49/arch/mips/kernel/vmlinux.lds.S

...
#undef mips
#define mips mips
OUTPUT_ARCH(mips)
ENTRY(kernel_entry)
PHDRS {
text PT_LOAD FLAGS(); /* RWX */
note PT_NOTE FLAGS(); /* R__ */
} #ifdef CONFIG_32BIT
#ifdef CONFIG_CPU_LITTLE_ENDIAN
jiffies = jiffies_64;
#else
jiffies = jiffies_64 + ;
#endif
#else
jiffies = jiffies_64;
#endif SECTIONS
{
...

表明入口地址为kernel_entry,该符号在:~/openwrt1407/build_dir/target-mips_34kc_uClibc-0.9.33.2/linux-ar71xx_generic/linux-3.10.49/arch/mips/kernel/head.S中定义

...
NESTED(kernel_entry, , sp) # kernel entry point kernel_entry_setup # cpu specific setup setup_c0_status_pri /* We might not get launched at the address the kernel is linked to,
so we jump there. */
PTR_LA t0, 0f
jr t0
: #ifdef CONFIG_MIPS_MT_SMTC
/*
* In SMTC kernel, "CLI" is thread-specific, in TCStatus.
* We still need to enable interrupts globally in Status,
* and clear EXL/ERL.
*
* TCContext is used to track interrupt levels under
* service in SMTC kernel. Clear for boot TC before
* allowing any interrupts.
*/
mtc0 zero, CP0_TCCONTEXT mfc0 t0, CP0_STATUS
ori t0, t0, 0xff1f
xori t0, t0, 0x001e
mtc0 t0, CP0_STATUS
#endif /* CONFIG_MIPS_MT_SMTC */ PTR_LA t0, __bss_start # clear .bss
LONG_S zero, (t0)
PTR_LA t1, __bss_stop - LONGSIZE
:
PTR_ADDIU t0, LONGSIZE
LONG_S zero, (t0)
bne t0, t1, 1b LONG_S a0, fw_arg0 # firmware arguments
LONG_S a1, fw_arg1
LONG_S a2, fw_arg2
LONG_S a3, fw_arg3 MTC0 zero, CP0_CONTEXT # clear context register
PTR_LA $, init_thread_union
/* Set the SP after an empty pt_regs. */
PTR_LI sp, _THREAD_SIZE - - PT_SIZE
PTR_ADDU sp, $
back_to_back_c0_hazard
set_saved_sp sp, t0, t1
PTR_SUBU sp, * SZREG # init stack pointer j start_kernel
END(kernel_entry)
...

最终跳到kernel_entry中,该函数在~/openwrt1407/build_dir/target-mips_34kc_uClibc-0.9.33.2/linux-ar71xx_generic/linux-3.10.49/init/main.c中定义:

asmlinkage void __init start_kernel(void)
{
char * command_line;
extern const struct kernel_param __start___param[], __stop___param[]; /*
* Need to run as early as possible, to initialize the
* lockdep hash:
*/
lockdep_init();
smp_setup_processor_id();
debug_objects_early_init(); /*
* Set up the the initial canary ASAP:
*/
boot_init_stack_canary(); cgroup_init_early(); local_irq_disable();
early_boot_irqs_disabled = true; /*
* Interrupts are still disabled. Do necessary setups, then
* enable them
*/
boot_cpu_init();
page_address_init();
pr_notice("%s", linux_banner);
setup_arch(&command_line);
mm_init_owner(&init_mm, &init_task);
mm_init_cpumask(&init_mm);
setup_command_line(command_line);
setup_nr_cpu_ids();
setup_per_cpu_areas();
smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ build_all_zonelists(NULL, NULL);
page_alloc_init(); pr_notice("Kernel command line: %s\n", boot_command_line);
parse_early_param();
parse_args("Booting kernel", static_command_line, __start___param,
__stop___param - __start___param,
-, -, &unknown_bootoption); jump_label_init(); /*
* These use large bootmem allocations and must precede
* kmem_cache_init()
*/
setup_log_buf();
pidhash_init();
vfs_caches_init_early();
sort_main_extable();
trap_init();
mm_init(); /*
* Set up the scheduler prior starting any interrupts (such as the
* timer interrupt). Full topology setup happens at smp_init()
* time - but meanwhile we still have a functioning scheduler.
*/
sched_init();
/*
* Disable preemption - early bootup scheduling is extremely
* fragile until we cpu_idle() for the first time.
*/
preempt_disable();
if (WARN(!irqs_disabled(), "Interrupts were enabled *very* early, fixing it\n"))
local_irq_disable();
idr_init_cache();
perf_event_init();
rcu_init();
tick_nohz_init();
radix_tree_init();
/* init some links before init_ISA_irqs() */
early_irq_init
();
init_IRQ();
tick_init();
init_timers();
hrtimers_init();
softirq_init();
timekeeping_init();
time_init();
profile_init();
call_function_init();
WARN(!irqs_disabled(), "Interrupts were enabled early\n");
early_boot_irqs_disabled = false;
local_irq_enable(); kmem_cache_init_late(); /*
* HACK ALERT! This is early. We're enabling the console before
* we've done PCI setups etc, and console_init() must be aware of
* this. But we do want output early, in case something goes wrong.
*/
console_init();
if (panic_later)
panic(panic_later, panic_param); lockdep_info(); /*
* Need to run this when irqs are enabled, because it wants
* to self-test [hard/soft]-irqs on/off lock inversion bugs
* too:
*/
locking_selftest(); #ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start && !initrd_below_start_ok &&
page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {
pr_crit("initrd overwritten (0x%08lx < 0x%08lx) - disabling it.\n",
page_to_pfn(virt_to_page((void *)initrd_start)),
min_low_pfn);
initrd_start = ;
}
#endif
page_cgroup_init();
debug_objects_mem_init();
kmemleak_init();
setup_per_cpu_pageset();
numa_policy_init();
if (late_time_init)
late_time_init();
sched_clock_init();
calibrate_delay();
pidmap_init();
anon_vma_init();
#ifdef CONFIG_X86
if (efi_enabled(EFI_RUNTIME_SERVICES))
efi_enter_virtual_mode();
#endif
thread_info_cache_init();
cred_init();
fork_init(totalram_pages);
proc_caches_init();
buffer_init();
key_init();
security_init();
dbg_late_init();
vfs_caches_init(totalram_pages);
signals_init();
/* rootfs populating might need page-writeback */
page_writeback_init();
#ifdef CONFIG_PROC_FS
proc_root_init();
#endif
cgroup_init();
cpuset_init();
taskstats_init_early();
delayacct_init(); check_bugs(); acpi_early_init(); /* before LAPIC and SMP init */
sfi_init_late(); if (efi_enabled(EFI_RUNTIME_SERVICES)) {
efi_late_init();
efi_free_boot_services();
} ftrace_init(); /* Do the rest non-__init'ed, we're now alive */
rest_init();
}

上面调用了两个IRQ初始化函数early_irq_init和init_IRQ,分别在~/openwrt1407/build_dir/target-mips_34kc_uClibc-0.9.33.2/linux-ar71xx_generic/linux-3.10.49/kernel/irq/irqdesc.c和~/openwrt1407/build_dir/target-mips_34kc_uClibc-0.9.33.2/linux-ar71xx_generic/linux-3.10.49/arch/mips/kernel/irq.c中。

early_irq_init函数

int __init early_irq_init(void)
{
int i, initcnt, node = first_online_node;
struct irq_desc *desc; init_irq_default_affinity(); /* Let arch update nr_irqs and return the nr of preallocated irqs */
initcnt = arch_probe_nr_irqs();
printk(KERN_INFO "NR_IRQS:%d nr_irqs:%d %d\n", NR_IRQS, nr_irqs, initcnt); if (WARN_ON(nr_irqs > IRQ_BITMAP_BITS))
nr_irqs = IRQ_BITMAP_BITS; if (WARN_ON(initcnt > IRQ_BITMAP_BITS))
initcnt = IRQ_BITMAP_BITS; if (initcnt > nr_irqs)
nr_irqs = initcnt; for (i = ; i < initcnt; i++) {
desc = alloc_desc(i, node, NULL);
set_bit(i, allocated_irqs);
irq_insert_desc(i, desc);
}
return arch_early_irq_init();
}

init_IRQ函数

void __init init_IRQ(void)
{
int i; #ifdef CONFIG_KGDB
if (kgdb_early_setup)
return;
#endif for (i = ; i < NR_IRQS; i++)
irq_set_noprobe(i); arch_init_irq(); #ifdef CONFIG_KGDB
if (!kgdb_early_setup)
kgdb_early_setup = ;
#endif
}

上面调用的arch_init_irq函数位于~/openwrt1407/build_dir/target-mips_34kc_uClibc-0.9.33.2/linux-ar71xx_generic/linux-3.10.49/arch/mips/ath79/irq.c中

arch_init_irq函数

static void __init ath79_misc_irq_init(void)
{
void __iomem *base = ath79_reset_base;
int i; __raw_writel(, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
__raw_writel(, base + AR71XX_RESET_REG_MISC_INT_STATUS); if (soc_is_ar71xx() || soc_is_ar913x())
ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
else if (soc_is_ar724x() ||
soc_is_ar933x() ||
soc_is_ar934x() ||
soc_is_qca953x() ||
soc_is_qca955x())
ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
else
BUG(); for (i = ATH79_MISC_IRQ_BASE;
i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) {
irq_set_chip_and_handler(i, &ath79_misc_irq_chip,
handle_level_irq);
} irq_set_chained_handler(ATH79_CPU_IRQ(), ath79_misc_irq_handler);
}

...
void __init arch_init_irq(void)
{
if (soc_is_ar71xx()) {
ath79_ip2_handler = ar71xx_ip2_handler;
ath79_ip3_handler = ar71xx_ip3_handler;
} else if (soc_is_ar724x()) {
ath79_ip2_handler = ar724x_ip2_handler;
ath79_ip3_handler = ar724x_ip3_handler;
} else if (soc_is_ar913x()) {
ath79_ip2_handler = ar913x_ip2_handler;
ath79_ip3_handler = ar913x_ip3_handler;
} else if (soc_is_ar933x()) {
ath79_ip2_handler = ar933x_ip2_handler;
ath79_ip3_handler = ar933x_ip3_handler;
} else if (soc_is_ar934x()) {
ath79_ip2_handler = ath79_default_ip2_handler;
ath79_ip3_handler = ar934x_ip3_handler;
} else if (soc_is_qca953x()) {
ath79_ip2_handler = ath79_default_ip2_handler;
ath79_ip3_handler = ath79_default_ip3_handler;
} else if (soc_is_qca955x()) {
ath79_ip2_handler = ath79_default_ip2_handler;
ath79_ip3_handler = ath79_default_ip3_handler;
} else {
BUG();
} cp0_perfcount_irq = ATH79_MISC_IRQ();
mips_cpu_irq_init();
ath79_misc_irq_init(); if (soc_is_ar934x())
ar934x_ip2_irq_init();
else if (soc_is_qca955x())
qca955x_irq_init();
}

mips_cpu_irq_init函数位于~/openwrt1407/build_dir/target-mips_34kc_uClibc-0.9.33.2/linux-ar71xx_generic/linux-3.10.49/arch/mips/kernel/irq_cpu.c中,ath79_misc_irq_init同在irq.c文件中。

void __init mips_cpu_irq_init(void)
{
int irq_base = MIPS_CPU_IRQ_BASE;
int i; /* Mask interrupts. */
clear_c0_status(ST0_IM);
clear_c0_cause(CAUSEF_IP); /* Software interrupts are used for MT/CMT IPI */
for (i = irq_base; i < irq_base + ; i++)
irq_set_chip_and_handler(i, cpu_has_mipsmt ?
&mips_mt_cpu_irq_controller :
&mips_cpu_irq_controller,
handle_percpu_irq); for (i = irq_base + ; i < irq_base + ; i++)
irq_set_chip_and_handler(i, &mips_cpu_irq_controller,
handle_percpu_irq);
}

AR9331中Linux内核启动中与IRQ中断相关的文件的更多相关文章

  1. 如何调整Linux内核启动中的驱动初始化顺序-驱动加载优先级

    Linux内核为不同驱动的加载顺序对应不同的优先级,定义了一些宏: include\linux\init.h #define pure_initcall(fn) __define_initcall(& ...

  2. TCP/IP协议栈源码图解分析系列10:linux内核协议栈中对于socket相关API的实现

    题记:本系列文章的目的是抛开书本从Linux内核源代码的角度详细分析TCP/IP协议栈内核相关技术 轻松搞定TCP/IP协议栈,原创文章欢迎交流, byhankswang@gmail.com linu ...

  3. 嵌入式C语言自我修养 02:Linux 内核驱动中的指定初始化

    2.1 什么是指定初始化 在标准 C 中,当我们定义并初始化一个数组时,常用方法如下: ] = {,,,,,,,,}; 按照这种固定的顺序,我们可以依次给 a[0] 和 a[8] 赋值.因为没有对 a ...

  4. linux内核启动参数

    Linux内核启动参数   Console Options                         参数 说明 选项 内核配置/文件   console=Options 用于说明输出设备 tt ...

  5. Linux内核启动代码分析二之开发板相关驱动程序加载分析

    Linux内核启动代码分析二之开发板相关驱动程序加载分析 1 从linux开始启动的函数start_kernel开始分析,该函数位于linux-2.6.22/init/main.c  start_ke ...

  6. 【内核】linux内核启动流程详细分析

    Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件,包括内核入口ENTRY(stext)到start_kernel间的初始化代码, 主要作用 ...

  7. 【内核】linux内核启动流程详细分析【转】

    转自:http://www.cnblogs.com/lcw/p/3337937.html Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件 ...

  8. Linux内核启动过程概述

    版权声明:本文原创,转载需声明作者ID和原文链接地址. Hi!大家好,我是CrazyCatJack.今天给大家带来的是Linux内核启动过程概述.希望能够帮助大家更好的理解Linux内核的启动,并且创 ...

  9. linux内核启动以及文件系统的加载过程

    Linux 内核启动及文件系统加载过程 当u-boot 开始执行 bootcmd 命令,就进入 Linux 内核启动阶段.普通 Linux 内核的启动过程也可以分为两个阶段.本文以项目中使用的 lin ...

随机推荐

  1. MemberwishClone学习

    /* * Created by SharpDevelop. * User: My little flower basket * Date: 2013/7/12 * Time: 9:37 * * To ...

  2. href=&quot;javascript:void(0);&quot;与#差异

    将<a>标签设置为空链接有两种方式.第一个是href="#",第二个是href="javascript:void(0);". 两种方式都设置了标签为 ...

  3. eclipse android ndk 提示Type 'JNIEnv' could not be resolved 等信息解决办法

    新配置完eclipse c++ android ndk 环境后,导入项目提示以下信息 是由于没有将jni.h导入的缘故,而这个文件在ndk的目录下面.所以,参照以下步骤:Project Propert ...

  4. hadoop工作平台梳理

    文章 http://blog.csdn.net/lili72/article/details/41130743 lili72 数据平台: 一.  hadoop平台:Hbase.hive,storm,s ...

  5. 3D空间中的AABB(轴向平行包围盒, Aixe align bounding box)的求法

    引言 在前面的一篇文章中讲述了怎样通过模型的顶点来求的模型的包围球,而且还讲述了基本包围体除了包围球之外,还有AABB包围盒.在这一章,将讲述怎样依据模型的坐标求得它的AABB盒. 表示方法 AABB ...

  6. Intent常用使用汇总

    方法一:调用默认的短信程序Intent intent = new Intent(Intent.ACTION_VIEW);intent.setType("vnd.android-dir/mms ...

  7. Redis源代码分析(十)--- testhelp.h小测试框架和redis-check-aof.c 日志检测

    周期分析struct结构体redis代码.最后,越多越发现很多的代码其实大同小异.于struct有袋1,2不分析文件,关于set集合的一些东西,就放在下次分析好了,在选择下个分析的对象时,我考虑了一下 ...

  8. B/S 类项目改善

    B/S 类项目改善的一些建议   要分享的议题 性能提升:在访问量逐渐增大的同时,如何增大单台服务器的 PV2 上限,增加 TPS3 ? RESTful:相较于传统的 SOAP1,RESTful 风格 ...

  9. 编写WCF服务时右击配置文件无“Edit WCF Configuration”(编辑 WCF 配置)远程的解决办法

    原文:编写WCF服务时右击配置文件无“Edit WCF Configuration”远程的解决办法 今天在看<WCF揭秘>书中看到作者提出可以在一个WCF Host应用程序的App.Con ...

  10. jaxb和dozer简介

    一.jaxb是什么     JAXB是Java Architecture for XML Binding的缩写.可以将一个Java对象转变成为XML格式,反之亦然.     我们把对象与关系数据库之间 ...