<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 淺談分析Arm linux 內(nèi)核移植及系統(tǒng)初始化的過程四

          淺談分析Arm linux 內(nèi)核移植及系統(tǒng)初始化的過程四

          作者: 時(shí)間:2016-11-09 來源:網(wǎng)絡(luò) 收藏
          7、淺談分析Arm linux 內(nèi)核移植系統(tǒng)初始化的過程 咨詢QQ:313807838

          MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
          * to SMDK2410 */
          /* Maintainer: Jonas Dietsche */
          .phys_io = S3C2410_PA_UART,
          .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
          .boot_params = S3C2410_SDRAM_PA + 0x100,
          .map_io = smdk2410_map_io,
          .init_irq = s3c24xx_init_irq,
          .init_machine = smdk_machine_init,
          .timer = &s3c24xx_timer,
          MACHINE_END

          本文引用地址:http://www.ex-cimer.com/article/201611/318026.htm

          由此可見在.arch.info.init段內(nèi)存放了__desc_mach_desc_SMDK2410結(jié)構(gòu)體。初始化了相應(yīng)的初始化函數(shù)指針。問題又來了, 這些初始化指針函數(shù)是什么時(shí)候被調(diào)用的呢?
          分析發(fā)現(xiàn),不一而同。
          如 s3c24xx_init_irq()函數(shù)是通過start_kernel()里的init_IRQ()函數(shù)調(diào)用init_arch_irq()實(shí)現(xiàn)的。 因?yàn)樵贛ACHINE_START結(jié)構(gòu)體中 .init_irq = s3c24xx_init_irq,而在setup_arch()函數(shù)中init_arch_irq = mdesc->init_irq, 所以調(diào)用init_arch_irq()就相當(dāng)于調(diào)用了s3c24xx_init_irq()。
          又如smdk_machine_init()函數(shù) 的初始化。在MACHINE_START結(jié)構(gòu)體中,函數(shù)指針賦值,.init_machine = smdk_machine_init。而init_machine()函數(shù)被linux/arch/arm/kernel/setup.c文件中的 customize_machine()函數(shù)調(diào)用并被arch_initcall(Fn)宏處 理,arch_initcall(customize_machine)。 被arch_initcall(Fn)宏處理過函數(shù)將linux/init/main.c
          do_initcalls()函數(shù)調(diào)用。 具體參看下邊的部分。

          void __init setup_arch(char cmdline_p)
          {
          struct tag *tags = (struct tag *)&init_tags;
          struct machine_desc *mdesc;
          char *from = default_command_line;

          setup_processor();
          mdesc = setup_machine(machine_arch_type);//machine_arch_type =SMDK2410 by edwin
          machine_name = mdesc->name;

          if (mdesc->soft_reboot)
          reboot_setup("s");

          if (mdesc->boot_params)
          tags = phys_to_virt(mdesc->boot_params);

          /*
          * If we have the old style parameters, convert them to
          * a tag list.
          */
          if (tags->hdr.tag != ATAG_CORE)
          convert_to_tag_list(tags);
          if (tags->hdr.tag != ATAG_CORE)
          tags = (struct tag *)&init_tags;

          if (mdesc->fixup)
          mdesc->fixup(mdesc, tags, &from, &meminfo);

          if (tags->hdr.tag == ATAG_CORE) {
          if (meminfo.nr_banks != 0)
          squash_mem_tags(tags);
          parse_tags(tags);
          }

          init_mm.start_code = (unsigned long) &_text;
          init_mm.end_code = (unsigned long) &_etext;
          init_mm.end_data = (unsigned long) &_edata;
          init_mm.brk = (unsigned long) &_end;

          memcpy(saved_command_line, from, COMMAND_LINE_SIZE);

          8、淺談分析Arm linux 內(nèi)核移植及系統(tǒng)初始化的過程 咨詢QQ:313807838
          saved_command_line[COMMAND_LINE_SIZE-1] = /0;
          parse_cmdline(cmdline_p, from);
          paging_init(&meminfo, mdesc);
          request_standard_resources(&meminfo, mdesc);

          #ifdef CONFIG_SMP
          smp_init_cpus();
          #endif

          cpu_init();

          /*
          * Set up various architecture-specific pointers
          */
          init_arch_irq = mdesc->init_irq;
          system_timer = mdesc->timer;
          init_machine = mdesc->init_machine;

          #ifdef CONFIG_VT
          #if defined(CONFIG_VGA_CONSOLE)
          conswitchp = &vga_con;
          #elif defined(CONFIG_DUMMY_CONSOLE)
          conswitchp = &dummy_con;
          #endif
          #endif
          }
          5.3. rest_init()函數(shù)分析
          下面我們來分析下rest_init()函數(shù)。
          Start_kernel() 函數(shù)負(fù)責(zé)初始化內(nèi)核各子系統(tǒng),最后調(diào)用reset_init(),啟動(dòng)一個(gè)叫做init的內(nèi)核線程,繼續(xù)初始化。在init內(nèi)核線程中,將執(zhí)行下列 init()函數(shù)的程序。Init()函數(shù)負(fù)責(zé)完成根文件系統(tǒng)的掛接、初始化設(shè)備驅(qū)動(dòng)程序和啟動(dòng)用戶空間的init進(jìn)程等重要工作。

          static void noinline rest_init(void)
          __releases(kernel_lock)
          {
          kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);
          numa_default_policy();
          unlock_kernel();

          /*
          * The boot idle thread must execute schedule()
          * at least one to get things moving:
          */
          preempt_enable_no_resched();
          schedule();
          preempt_disable();

          /* Call into cpu_idle with preempt disabled */
          cpu_idle();
          }


          static int init(void * unused)
          {
          lock_kernel();
          /*
          * init can run on any cpu.
          */
          set_cpus_allowed(current, CPU_MASK_ALL);
          /*
          * Tell the world that were going to be the grim
          * reaper of innocent orphaned children.
          *
          * We dont want people to have to make incorrect
          * assumptions about where in the task array this
          * can be found.
          */
          child_reaper = current;

          smp_prepare_cpus(max_cpus);

          do_pre_smp_initcalls();

          smp_init();
          sched_init_smp();

          cpuset_init_smp();

          /*
          * Do this before initcalls, because some drivers want to access
          * firmware files.
          */
          populate_rootfs(); //掛接根文件系統(tǒng)

          do_basic_setup(); //初始化設(shè)備驅(qū)動(dòng)程序

          /*
          * check if there is an early userspace init. If yes, let it do all
          * the work //啟動(dòng)用戶空間的init進(jìn)程

          9、淺談分析Arm linux 內(nèi)核移植及系統(tǒng)初始化的過程 咨詢QQ:313807838
          */

          if (!ramdisk_execute_command)
          ramdisk_execute_command = "/init";

          if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
          ramdisk_execute_command = NULL;
          prepare_namespace();
          }

          /*
          * Ok, we have completed the initial bootup, and
          * were essentially up and running. Get rid of the
          * initmem segments and start the user-mode stuff..
          */
          free_initmem();
          unlock_kernel();
          mark_rodata_ro();
          system_state = SYSTEM_RUNNING;
          numa_default_policy();

          if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
          printk(KERN_WARNING "Warning: unable to open an initial console./n");

          (void) sys_dup(0);
          (void) sys_dup(0);

          if (ramdisk_execute_command) {
          run_init_process(ramdisk_execute_command);
          printk(KERN_WARNING "Failed to execute %s/n",
          ramdisk_execute_command);
          }

          /*
          * We try each of these until one succeeds.
          *
          * The Bourne shell can be used instead of init if we are
          * trying to recover a really broken machine.
          */
          if (execute_command) {
          run_init_process(execute_command);
          printk(KERN_WARNING "Failed to execute %s. Attempting "
          "defaults.../n", execute_command);
          }
          run_init_process("/sbin/init");
          run_init_process("/etc/init");
          run_init_process("/bin/init");
          run_init_process("/bin/sh");

          panic("No init found. Try passing init= option to kernel.");
          }

          5.3.1. 掛接根文件系統(tǒng)
          Linux/init/ramfs.c
          void __init populate_rootfs(void)
          {
          char *err = unpack_to_rootfs(__initramfs_start,
          __initramfs_end - __initramfs_start, 0);
          if (err)
          panic(err);
          #ifdef CONFIG_BLK_DEV_INITRD
          if (initrd_start) {
          #ifdef CONFIG_BLK_DEV_RAM
          int fd;
          printk(KERN_INFO "checking if image is initramfs...");
          err = unpack_to_rootfs((char *)initrd_start,
          initrd_end - initrd_start, 1);
          if (!err) {
          printk(" it is/n");
          unpack_to_rootfs((char *)initrd_start,
          initrd_end - initrd_start, 0);
          free_initrd();
          return;
          }
          printk("it isnt (%s); looks like an initrd/n", err);



          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();