AR9331中Linux内核启动中与IRQ中断相关的文件
先列出框架,具体后继再来分析。
首先是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中断相关的文件相关推荐
- c++ map 初始化_如何调整Linux内核启动中的驱动初始化顺序?
如何调整Linux内核启动中的驱动初始化顺序?[问题] 此处我要实现的是将芯片的ID用于网卡MAC地址,网卡驱动是enc28j60_init. 但是,读取芯片ID的函数,在as352x_afe_ini ...
- 如何调整Linux内核启动中的驱动初始化顺序
[问题] 此处我要实现的是将芯片的ID用于网卡MAC地址,网卡驱动是enc28j60_init. 但是,读取芯片ID的函数,在as352x_afe_init模块中,所以要先初始化as352x_afe_ ...
- 内核logo 前闪 linux,Linux内核启动中显示的logo的修改
1.配置内核 使内核启动时加载logo,在源代码的主目录下make menuconfig Device Drivers ---> Graphics support ---> 选上 并 ...
- linux内核中启动页面,Linux内核启动过程分析
下面给出内核映像完整的启动过程: arch/x86/boot/header.S: --->header第一部分(以前的bootsector.S): 载入bootloader到0x7c00处,设 ...
- Linux内核defconfig在哪,Linux内核根目录中的配置文件.config中包含了许多宏定义,...
满意答案 大大bigone 推荐于 2017.11.22 采纳率:52% 等级:9 已帮助:813人 一.Linux内核的配置系统由三个部分组成,分别是: 1.Makefile:分布在 Linu ...
- 【内核】linux内核启动流程详细分析【转】
转自:http://www.cnblogs.com/lcw/p/3337937.html Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件 ...
- 【内核】linux内核启动流程详细分析
Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件,包括内核入口ENTRY(stext)到start_kernel间的初始化代码, 主要作用 ...
- linux内核参数分析,linux内核启动第一阶段分析
linux内核启动第一阶段分析 http://blog.csdn.net/aaronychen/article/details/2838341 本文的很多内容是参考了网上某位大侠的文章写的<&l ...
- Linux内核启动流程(待完善)
文章目录 一.Linux内核自解压过程 二.Linux内核启动第二阶段stage1 2.1.linux系统启动入口函数(stext) 2.2.内核初始化阶段(start_kernel) 2.3.2 r ...
最新文章
- Java 开源分布式缓存框架Ehcache
- Qt工程生成xcode工程文件
- 百度地图动态插入标注
- 2019 年百度之星·程序设计大赛 - 初赛一
- LeetCode 1024. 视频拼接(动态规划/贪心)
- DesignPattern_Java:Adapter Pattern
- leetcode - Search in Rotated Sorted Array II
- Atitit.jdk java8的语法特性详解 attilax 总结
- 电脑有网络,但所有浏览器网页都打不开,是怎么回事?
- 关于被隐藏的文件夹无法去掉隐藏的属性
- 合作、竞争、猜忌……车联网江湖的“战国时代”
- 产品经理必备原型工具Axure RP 8自定义元件库
- 如何提高团队开发质量
- 如何double你的能力
- 浅谈“Robots文件信息泄露”
- 抛出异常关键字throw与定义异常关键字throws
- 【场景削减】拉丁超立方抽样方法场景削减(Matlab代码实现)
- 长沙云栖谷交通事故_长沙含浦片区自发成立抗洪救灾志愿者服务队转移被困群众(组图)...
- ctf中常见的编码和密码收集
- n元齐次线性方程组Ax =0解