NIOS2 Linux 启动过程

概述

1 Bootloader

CPU上电复位, 从NOR Flash物理地址0x00000000启动

拷贝内核镜像到ram高位地址

传dtb给内核,

传启动参数给内核

跳转到压缩镜像入口

2 linux/arch/nios2/boot/compressed/head.S  
进入__start
关闭中断
使指令和数据cache无效
 解压内核镜像到低地址

初始化指令和数据cache

初始化MMU, 开始使用虚拟地址

jump到kernel address
3 linux-2.6/arch/nios2/kernel/head.S
__start入口
Disable interrupts
刷新指令cache
中断异常入口
刷新data cache
屏蔽所有interrupts
clear .BSS
call start_kernel函数
4 linux-2.6/init/main.c  start_kernel()函数
调用setup_arch()
调用rest_init()

5 linux-2.6/arch/nios2/kernel  setup_arch()函数

6 linux-2.6/init/main.c  rest_init()函数

主要功能是创建并启动内核线程init

kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);//创建kernel_init内核线程,PID=1

pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);//创建kthread内核线程,PID=2

cpu_idle(); //内核本体进入idle状态,用循环消耗空闲的CPU时间

7 linux-2.6/init/main.c   kernel_init()函数

do_basic_setup(); //重要函数,主要是初始化设备驱动程序

init_post(); //启动用户空间init进程

8 linux-2.6/init/main.c   do_basic_setup()函数

init_tmpfs();   //

driver_init(); //初始化驱动模型中的各个子系统

9 linux-2.6/drivers/base/init.c    driver_init()函数

devtmpfs_init();   //初始化devtmpfs文件系统

devices_init();   //初始化驱动模型中的部分子系统和kobject
buses_init();    //初始化驱动模型中的bus子系统
classes_init();   //初始化驱动模型中的class子系统
firmware_init();  //初始化驱动模型中的firmware子系统
hypervisor_init();   //初始化驱动模型中的hypervisor子系统
platform_bus_init();   //初始化驱动模型中的bus/platform子系统
system_bus_init();   //初始化驱动模型中的devices/system子系统
cpu_dev_init();    //初始化驱动模型中的devices/system/cpu子系统
memory_dev_init();    //初始化驱动模型中的devices/system/memory子系统

10 linux-2.6/init/main.c   init_post()函数

启动用户init进程(1号进程)

11 执行/etc/rc

12 init进程读取/etc/inittab文件, 启动更多子进程 

参考

http://blog.chinaunix.net/uid-20746260-id-3176497.html

NIOS2 Linux 启动时终端输出

Linux version 2.6.39-01079-g938653e-dirty ([email protected]) (gcc version 4.1.2) #207 Wed Apr 16 07:56:21 PDT 2014
//linux-2.6/init/main.c start_kernel()
printk(KERN_NOTICE "%s", linux_banner);
bootconsole [early0] enabled
early_console initialized at 0xe0401440

//linux-2.6/init/main.c  start_kernel()-->
//linux-2.6/arch/nios2/kernel/setup.c  setup_arch()-->
//linux-2.6/arch/nios2/kernel/early_printk.c   setup_early_printk()-->
    register_console(&early_console);
    printk(KERN_INFO "early_console initialized at 0x%08lx\n", base_addr);

//linux-2.6/kernel/printk.c    register_console()
if (bcon &&
        ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV) &&
        !keep_bootcon) {
        /* we need to iterate through twice, to make sure we print
         * everything out, before we unregister the console(s)
         */
        printk(KERN_INFO "console [%s%d] enabled, bootconsole disabled\n",  
            newcon->name, newcon->index);
        for_each_console(bcon)
            if (bcon->flags & CON_BOOT)
                unregister_console(bcon);
    } else {
        printk(KERN_INFO "%sconsole [%s%d] enabled\n", 
            (newcon->flags & CON_BOOT) ? "boot" : "" ,
            newcon->name, newcon->index);
    }
On node 0 totalpages: 8192
free_area_init_node: node 0, pgdat d0556c68, node_mem_map d0571800
  DMA zone: 64 pages used for memmap
  DMA zone: 0 pages reserved
  DMA zone: 8128 pages, LIFO batch:0

//linux-2.6/init/main.c  start_kernel()-->
//linux-2.6/arch/nios2/kernel/setup.c  setup_arch()-->
//linux-2.6/arch/nios2/mm/init.c  paging_init()-->
//linux-2.6/mm/page_alloc.c  free_area_init()-->
//linux-2.6/mm/page_alloc.c  free_area_init_node()-->
    calculate_node_totalpages(pgdat, zones_size, zholes_size);
    alloc_node_mem_map(pgdat);

#ifdef CONFIG_FLAT_NODE_MEM_MAP
    printk(KERN_DEBUG "free_area_init_node: node %d, pgdat %08lx, node_mem_map %08lx\n",
        nid, (unsigned long)pgdat,
        (unsigned long)pgdat->node_mem_map);
#endif
    free_area_init_core(pgdat, zones_size, zholes_size);
//linux-2.6/mm/page_alloc.c  calculate_node_totalpages()
printk(KERN_DEBUG "On node %d totalpages: %lu\n", pgdat->node_id,
                            realtotalpages);
//linux-2.6/mm/page_alloc.c  free_area_init_core()-->
if (realsize >= memmap_pages) {
            realsize -= memmap_pages;
            if (memmap_pages)
                printk(KERN_DEBUG
                       "  %s zone: %lu pages used for memmap\n",
                       zone_names[j], memmap_pages);
        } else
            printk(KERN_WARNING
                "  %s zone: %lu pages exceeds realsize %lu\n",
                zone_names[j], memmap_pages, realsize);
      /* Account for reserved pages */
        if (j == 0 && realsize > dma_reserve) {
            realsize -= dma_reserve;
            printk(KERN_DEBUG "  %s zone: %lu pages reserved\n",
                    zone_names[0], dma_reserve);
        }
...
        zone_pcp_init(zone);
//linux-2.6/mm/page_alloc.c  zone_pcp_init()
if (zone->present_pages)
        printk(KERN_DEBUG "  %s zone: %lu pages, LIFO batch:%u\n",
            zone->name, zone->present_pages,
                     zone_batchsize(zone));
pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
pcpu-alloc: [0] 0 

//linux-2.6/init/main.c  start_kernel()-->
//linux-2.6/mm/percpu.c  setup_per_cpu_areas()-->
//linux-2.6/mm/percpu.c  pcpu_embed_first_chunk()-->
//linux-2.6/mm/percpu.c  pcpu_setup_first_chunk()-->
//linux-2.6/mm/percpu.c  pcpu_dump_alloc_info()
    printk("%spcpu-alloc: s%zu r%zu d%zu u%zu alloc=%zu*%zu",
           lvl, ai->static_size, ai->reserved_size, ai->dyn_size,
           ai->unit_size, ai->alloc_size / ai->atom_size, ai->atom_size);
    for (group = 0; group < ai->nr_groups; group++) {
        const struct pcpu_group_info *gi = &ai->groups[group];
        int unit = 0, unit_end = 0;
       BUG_ON(gi->nr_units % upa);
        for (alloc_end += gi->nr_units / upa;
             alloc < alloc_end; alloc++) {
            if (!(alloc % apl)) {
                printk("\n");
                printk("%spcpu-alloc: ", lvl);
            }
            printk("[%0*d] ", group_width, group);
            for (unit_end += upa; unit < unit_end; unit++)
                if (gi->cpu_map[unit] != NR_CPUS)
                    printk("%0*d ", cpu_width,
                           gi->cpu_map[unit]);
                else
                    printk("%s ", empty_str);
        }
    }
    printk("\n");
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 8128
//linux-2.6/init/main.c  start_kernel()-->
//linux-2.6/mm/page_alloc.c  build_all_zonelists()
printk("Built %i zonelists in %s order, mobility grouping %s.  "
        "Total pages: %ld\n",
Kernel command line: debug console=ttyAL0,115200
//linux-2.6/init/main.c  start_kernel()-->
printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);
PID hash table entries: 128 (order: -3, 512 bytes)
//linux-2.6/init/main.c  start_kernel()-->
//linux-2.6/kernel/pid.c  pidhash_init()-->
//linux-2.6/mm/page_alloc.c  alloc_large_system_hash()
    printk(KERN_INFO "%s hash table entries: %ld (order: %d, %lu bytes)\n",
           tablename,
           (1UL << log2qty),
           ilog2(size) - PAGE_SHIFT,
           size);
Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
//linux-2.6/init/main.c  start_kernel()-->
//linux-2.6/fs/dcache.c  vfs_caches_init_early()-->
//linux-2.6/fs/dcache.c  dcache_init_early()-->
//linux-2.6/mm/page_alloc.c  alloc_large_system_hash()
    printk(KERN_INFO "%s hash table entries: %ld (order: %d, %lu bytes)\n",
           tablename,
           (1UL << log2qty),
           ilog2(size) - PAGE_SHIFT,
           size);
Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
//linux-2.6/init/main.c  start_kernel()-->
//linux-2.6/fs/dcache.c  vfs_caches_init_early()-->
//linux-2.6/fs/inode.c  inode_init_early()-->
//linux-2.6/mm/page_alloc.c  alloc_large_system_hash()
    printk(KERN_INFO "%s hash table entries: %ld (order: %d, %lu bytes)\n",
           tablename,
           (1UL << log2qty),
           ilog2(size) - PAGE_SHIFT,
           size);
Memory available: 26876k/5554k RAM (2202k kernel code, 3351k data)
//linux-2.6/init/main.c  start_kernel()-->
//linux-2.6/init/main.c  mm_init()-->
//linux-2.6/arch/nios2/mm/mem_init()
    printk(KERN_INFO "Memory available: %luk/%luk RAM (%dk kernel code, %dk data)\n",
           nr_free_pages() << (PAGE_SHIFT - 10),
           (_end - _stext) >> 10,
           codek, datak);
NR_IRQS:32
//linux-2.6/init/main.c  start_kernel()-->
//linux-2.6/kernel/irq/irqdesc.c  early_irq_init()
printk(KERN_INFO "NR_IRQS:%d\n", NR_IRQS);
Calibrating delay loop... 40.44 BogoMIPS (lpj=20224)
//linux-2.6/init/main.c  start_kernel()-->
//linux-2.6/init/calibrate.c  calibrate_delay()
if (preset_lpj) {
        loops_per_jiffy = preset_lpj;
        if (!printed)
            pr_info("Calibrating delay loop (skipped) "
                "preset value.. ");
    } else if ((!printed) && lpj_fine) {
        loops_per_jiffy = lpj_fine;
        pr_info("Calibrating delay loop (skipped), "
            "value calculated using timer frequency.. ");
    } else if ((loops_per_jiffy = calibrate_delay_direct()) != 0) {
        if (!printed)
            pr_info("Calibrating delay using timer "
                "specific routine.. ");
    } else {
        if (!printed)
            pr_info("Calibrating delay loop... ");
        loops_per_jiffy = calibrate_delay_converge();
    }
    if (!printed)
        pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n",
            loops_per_jiffy/(500000/HZ),
            (loops_per_jiffy/(5000/HZ)) % 100, loops_per_jiffy);
pid_max: default: 32768 minimum: 301
//linux-2.6/init/main.c  start_kernel()-->
//linux-2.6/kernel/pid.c  pidmap_init()
    pid_max = min(pid_max_max, max_t(int, pid_max,
                PIDS_PER_CPU_DEFAULT * num_possible_cpus()));
    pid_max_min = max_t(int, pid_max_min,
                PIDS_PER_CPU_MIN * num_possible_cpus());
    pr_info("pid_max: default: %u minimum: %u\n", pid_max, pid_max_min);
Mount-cache hash table entries: 512
//linux-2.6/init/main.c  start_kernel()-->
//linux-2.6/fs/dcache.c  vfs_caches_init()-->
//linux-2.6/fs/namespcae.c  mmt_init()
printk(KERN_INFO "Mount-cache hash table entries: %lu\n", HASH_SIZE);
NET: Registered protocol family 16
bio: create slab <bio-0> at 0
Switching to clocksource timer
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 1024 (order: 1, 8192 bytes)
TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
TCP: Hash tables configured (established 1024 bind 1024)
TCP reno registered
UDP hash table entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.

//init线程
//linux-2.6/init/main.c  start_kernel()-->
//linux-2.6/init/main.c  rest_init()
kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);//启动init线程
//linux-2.6/init/main.c  kernel_init()-->
//linux-2.6/init/main.c  do_basic_setup()
do_initcalls();  //执行所有初始化代码
//网络子系统初始化
//linux-2.6/net/socket.c
core_initcall(sock_init); //压入.initcall1.init section 网络子系统初始化的第一个函数 应用层
//linux-2.6/net/core/sock.c
subsys_initcall(proto_init); //传输层
//linux-2.6/net/core/dev.c
subsys_initcall(net_dev_init); //设备链路层
//linux-2.6/net/ipv4/af_inet.c
fs_initcall(inet_init);  //网络层
altera_gpio: /sopc@0/gpio@0x401460: registered, irq 5 

altera_gpio: /sopc@0/gpio@0x401470: registered, irq -6 

JFFS2 version 2.2. (NAND) 漏 2001-2006 Red Hat, Inc. 

msgmni has been set to 52 

Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254) 

io scheduler noop registered io scheduler deadline registered 

io scheduler cfq registered (default) 

ttyAL0 at MMIO 0x401440 (irq = 3) is a Altera UART 

console [ttyAL0] enabled, bootconsole disabled 

spi_altera 401420.spi: base e0401420, irq 4

enc28j60 init

mousedev: PS/2 mouse device common for all mice 

TCP cubic registered 

NET: Registered protocol family 17
device_initcall(***)  //do_initcalls() 调用所有驱动
mudule_init(***)
Freeing unused kernel memory: 2764k freed (0xd0228000 - 0xd04db000)
//linux-2.6/init/main.c  post_init()-->
//linux-2.6/arch/nios2/mm/init.c  free_initmen()
//linux-2.6/arch/nios2/mm/init.c  free_init_page()
    printk(KERN_NOTICE "Freeing %s: %ldk freed (0x%lx - 0x%lx)\n",
           what, (end - start) >> 10, start, end);

猜你喜欢

转载自blog.csdn.net/shixha/article/details/23962281
今日推荐