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

首先是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(7);    /* RWX */note PT_NOTE FLAGS(4);    /* R__ */
}#ifdef CONFIG_32BIT#ifdef CONFIG_CPU_LITTLE_ENDIANjiffies     = jiffies_64;#elsejiffies     = jiffies_64 + 4;#endif
#elsejiffies     = jiffies_64;
#endifSECTIONS
{...

表明入口地址为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, 16, sp)            # kernel entry pointkernel_entry_setup            # cpu specific setupsetup_c0_status_pri/* We might not get launched at the address the kernel is linked to,so we jump there.  */PTR_LA    t0, 0fjr    t0
0:#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_TCCONTEXTmfc0    t0, CP0_STATUSori    t0, t0, 0xff1fxori    t0, t0, 0x001emtc0    t0, CP0_STATUS
#endif /* CONFIG_MIPS_MT_SMTC */PTR_LA        t0, __bss_start        # clear .bssLONG_S        zero, (t0)PTR_LA        t1, __bss_stop - LONGSIZE
1:PTR_ADDIU    t0, LONGSIZELONG_S        zero, (t0)bne        t0, t1, 1bLONG_S        a0, fw_arg0        # firmware argumentsLONG_S        a1, fw_arg1LONG_S        a2, fw_arg2LONG_S        a3, fw_arg3MTC0        zero, CP0_CONTEXT    # clear context registerPTR_LA        $28, init_thread_union/* Set the SP after an empty pt_regs.  */PTR_LI        sp, _THREAD_SIZE - 32 - PT_SIZEPTR_ADDU    sp, $28back_to_back_c0_hazardset_saved_sp    sp, t0, t1PTR_SUBU    sp, 4 * SZREG        # init stack pointerj        start_kernelEND(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,-1, -1, &unknown_bootoption);jump_label_init();/** These use large bootmem allocations and must precede* kmem_cache_init()*/setup_log_buf(0);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_INITRDif (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 = 0;}
#endifpage_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_X86if (efi_enabled(EFI_RUNTIME_SERVICES))efi_enter_virtual_mode();
#endifthread_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_FSproc_root_init();
#endifcgroup_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 = 0; 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_KGDBif (kgdb_early_setup)return;
#endiffor (i = 0; i < NR_IRQS; i++)irq_set_noprobe(i);arch_init_irq();#ifdef CONFIG_KGDBif (!kgdb_early_setup)kgdb_early_setup = 1;
#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(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);__raw_writel(0, 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;elseBUG();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(6), 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(5);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 + 2; 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 + 2; i < irq_base + 8; i++)irq_set_chip_and_handler(i, &mips_cpu_irq_controller,handle_percpu_irq);
}

转载于:https://www.cnblogs.com/tfanalysis/p/4210061.html

AR9331中Linux内核启动中与IRQ中断相关的文件相关推荐

  1. c++ map 初始化_如何调整Linux内核启动中的驱动初始化顺序?

    如何调整Linux内核启动中的驱动初始化顺序?[问题] 此处我要实现的是将芯片的ID用于网卡MAC地址,网卡驱动是enc28j60_init. 但是,读取芯片ID的函数,在as352x_afe_ini ...

  2. 如何调整Linux内核启动中的驱动初始化顺序

    [问题] 此处我要实现的是将芯片的ID用于网卡MAC地址,网卡驱动是enc28j60_init. 但是,读取芯片ID的函数,在as352x_afe_init模块中,所以要先初始化as352x_afe_ ...

  3. 内核logo 前闪 linux,Linux内核启动中显示的logo的修改

    1.配置内核 使内核启动时加载logo,在源代码的主目录下make menuconfig Device Drivers  ---> Graphics support  ---> 选上 并 ...

  4. linux内核中启动页面,Linux内核启动过程分析

    下面给出内核映像完整的启动过程: arch/x86/boot/header.S: --->header第一部分(以前的bootsector.S):  载入bootloader到0x7c00处,设 ...

  5. Linux内核defconfig在哪,Linux内核根目录中的配置文件.config中包含了许多宏定义,...

    满意答案 大大bigone 推荐于 2017.11.22 采纳率:52%    等级:9 已帮助:813人 一.Linux内核的配置系统由三个部分组成,分别是: 1.Makefile:分布在 Linu ...

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

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

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

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

  8. linux内核参数分析,linux内核启动第一阶段分析

    linux内核启动第一阶段分析 http://blog.csdn.net/aaronychen/article/details/2838341 本文的很多内容是参考了网上某位大侠的文章写的<&l ...

  9. Linux内核启动流程(待完善)

    文章目录 一.Linux内核自解压过程 二.Linux内核启动第二阶段stage1 2.1.linux系统启动入口函数(stext) 2.2.内核初始化阶段(start_kernel) 2.3.2 r ...

最新文章

  1. Java 开源分布式缓存框架Ehcache
  2. Qt工程生成xcode工程文件
  3. 百度地图动态插入标注
  4. 2019 年百度之星·程序设计大赛 - 初赛一
  5. LeetCode 1024. 视频拼接(动态规划/贪心)
  6. DesignPattern_Java:Adapter Pattern
  7. leetcode - Search in Rotated Sorted Array II
  8. Atitit.jdk java8的语法特性详解 attilax 总结
  9. 电脑有网络,但所有浏览器网页都打不开,是怎么回事?
  10. 关于被隐藏的文件夹无法去掉隐藏的属性
  11. 合作、竞争、猜忌……车联网江湖的“战国时代”
  12. 产品经理必备原型工具Axure RP 8自定义元件库
  13. 如何提高团队开发质量
  14. 如何double你的能力
  15. 浅谈“Robots文件信息泄露”
  16. 抛出异常关键字throw与定义异常关键字throws
  17. 【场景削减】拉丁超立方抽样方法场景削减(Matlab代码实现)
  18. 长沙云栖谷交通事故_长沙含浦片区自发成立抗洪救灾志愿者服务队转移被困群众(组图)...
  19. ctf中常见的编码和密码收集
  20. n元齐次线性方程组Ax =0解

热门文章

  1. 让StringGrid控件显示下拉菜单
  2. java 蓝桥杯算法训练 P0501
  3. python 根据索引取值_Python基础知识2
  4. 带你了解PCIE通信原理
  5. 漫谈Windows共享内存
  6. Akka之actor模型
  7. wifi信号衰减与距离关系_有线网络PK无线WiFi,孰胜孰负?
  8. (3)PCIE中断简介(学无止境)
  9. 本科生 计算机图形学试卷,湖南工程学院《计算机图形学》毕业补考试卷及答案...
  10. mysql多张表join_mysql 连接查询(多表查询)+子查询-初学教程 3【重点】