当前位置:文档之家› openwrt启动脚本分析

openwrt启动脚本分析

openwrt启动脚本分析
openwrt启动脚本分析

openwrt启动脚本分析

一、内核启动

uboot

-> start_kernel -> rest_init()

->

kernel_thread(kernel_init)-->kernel_init_freeable()-->r un_init_process

->

1,start_kernel 函数

(trunk/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/ Linux-ramips_rt305x/linux-3.10.36/init/main.c)[cpp] view plain copy

<pre name="code" class="cpp">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);//-->[ 0.000000] Linux version 3.10.36 (hui@ubuntu) (gcc version 4.8.3 (OpenWrt/Linaro GCC 4.8-2014.04 r40773) ) #51 Wed Aug 20 07:55:04 PDT 2014

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);//-->[ 0.000000] Kernel command line: console=ttyS0,57600

rootfstype=squashfs,jffs2

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_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 = 0;

}

#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();

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();

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(); //-------------------------------------------------> } 在这里,启动应用程序[cpp] view

plain copy

static int __ref kernel_init(void *unused)

{

kernel_init_freeable();

/* need to finish all async __init code before freeing the memory */

async_synchronize_full();

free_initmem();

mark_rodata_ro();

system_state = SYSTEM_RUNNING;

numa_default_policy();

flush_delayed_fput();

if (ramdisk_execute_command) {

if

(!run_init_process(ramdisk_execute_command))

return 0;

pr_err("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) {

if (!run_init_process(execute_command))

return 0;

pr_err("Failed to execute %s. Attempting defaults...\n",

execute_command);

}

if (!run_init_process("/etc/preinit") ||

!run_init_process("/sbin/init") ||

!run_init_process("/etc/init") ||

!run_init_process("/bin/init") ||

!run_init_process("/bin/sh"))

return 0;

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

"See Linux Documentation/init.txt for guidance.");

} [cpp] view

plain copy

static noinline void __init kernel_init_freeable(void) {

/*

* Wait until kthreadd is all set-up.

*/

wait_for_completion(&kthreadd_done);

/* Now the scheduler is fully set up and can do blocking allocations */

gfp_allowed_mask = __GFP_BITS_MASK;

/*

* init can allocate pages on any node

*/

set_mems_allowed(node_states[N_MEMORY]); /*

* init can run on any cpu.

*/

set_cpus_allowed_ptr(current, cpu_all_mask); cad_pid = task_pid(current);

smp_prepare_cpus(setup_max_cpus);

do_pre_smp_initcalls();

lockup_detector_init();

smp_init();

sched_init_smp();

do_basic_setup();

/* Open the /dev/console on the rootfs, this should never fail */

if (sys_open((const char __user *) "/dev/console",

O_RDWR, 0) < 0)

pr_err("Warning: unable to open an initial console.\n");

(void) sys_dup(0);

(void) sys_dup(0);

/*

* check if there is an early userspace init. If yes, let it do all

* the work

*/

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

* we're essentially up and running. Get rid of the

* initmem segments and start the user-mode stuff..

*/

/* rootfs is available now, try loading default modules */

load_default_modules();

}

启动第一个应用,init

trunk\build_dir\target-mipsel_24kec+dsp_uClibc-0.9.33.2\p rocd-2014-03-18\initd\init.c[cpp] view

plain copy

int

main(int argc, char **argv)

{

pid_t pid;

sigaction(SIGTERM, &sa_shutdown, NULL);

sigaction(SIGUSR1, &sa_shutdown, NULL);

sigaction(SIGUSR2, &sa_shutdown, NULL);

early();//-------->early.c

cmdline();

watchdog_init(1); //------->../watchdog.c

pid = fork();

if (!pid) {

char *kmod[] = { "/sbin/kmodloader",

"/etc/modules-boot.d/", NULL };

if (debug < 3) {

int fd = open("/dev/null", O_RDWR);

if (fd > -1) {

dup2(fd, STDIN_FILENO);

dup2(fd, STDOUT_FILENO);

dup2(fd, STDERR_FILENO);

if (fd > STDERR_FILENO)

close(fd);

}

}

execvp(kmod[0], kmod);

ERROR("Failed to start kmodloader\n");

exit(-1);

}

if (pid <= 0)

ERROR("Failed to start kmodloader instance\n");

uloop_init();

preinit(); //-------------->watchdog.c

uloop_run();

return 0;

}

trunk\build_dir\target-mipsel_24kec+dsp_uClibc-0.9.33.2\p rocd-2014-03-18\state.c[cpp] view

plain copy

static void state_enter(void)

{

char ubus_cmd[] = "/sbin/ubusd";

switch (state) {

case STATE_EARLY:

LOG("- early -\n");

watchdog_init(0);

hotplug("/etc/hotplug.json");

procd_coldplug();

break;

case STATE_INIT:

// try to reopen incase the wdt was not available

before coldplug

watchdog_init(0);

LOG("- ubus -\n");

procd_connect_ubus();

LOG("- init -\n");

service_init();

service_start_early("ubus", ubus_cmd);

procd_inittab();

procd_inittab_run("respawn");

procd_inittab_run("askconsole");

procd_inittab_run("askfirst");

procd_inittab_run("sysinit");

break;

case STATE_RUNNING:

LOG("- init complete -\n");

break;

case STATE_SHUTDOWN:

LOG("- shutdown -\n");

android系统开机启动流程分析

一,系统引导bootloader 加电,cpu执行bootloader程序,正常启动系统,加载boot.img【其中包含内核。还有ramdisk】 二,内核kernel bootloader加载kernel,kernel自解压,初始化,载入built-in驱动程序,完成启动。 内核启动后会创建若干内核线程,在后装入并执行程序/sbin/init/,载入init process,切换至用户空间(user-space) 内核zImage解压缩 head.S【这是ARM-Linux运行的第一个文件,这些代码是一个比较独立的代码包裹器。其作用就是解压Linux内核,并将PC指针跳到内核(vmlinux)的第一条指令】首先初始化自解压相关环境(内存等),调用decompress_kernel进行解压,解压后调用start_kernel启动内核【start_kernel是任何版本linux内核的通用初始化函数,它会初始化很多东西,输出linux版本信息,设置体系结构相关的环境,页表结构初始化,设置系 统自陷入口,初始化系统IRQ,初始化核心调度器等等】,最后调用rest_init【rest_init 会调用kernel_init启动init进程(缺省是/init)。然后执行schedule开始任务调度。这个init是由android的./system/core/init下的代码编译出来的,由此进入了android的代码】。 三,Init进程启动 【init是kernel启动的第一个进程,init启动以后,整个android系统就起来了】 init进程启动后,根据init.rc 和init. .rc脚本文件建立几个基本 服务(servicemanager zygote),然后担当property service 的功能 打开.rc文件,解析文件内容。【system/core/init/init.c】将service信息放置到service.list中【system/core/init/init_parser.c】。 建立service进程。【service_start(…) execve(…)】 在init.c中,完成以下工作 1、初始化log系统【解析/init.rc和init.%hardware%.rc文件,在两个 文件解析步骤2时执行“early-init”行动】 2、初始化设备【在/dev下创建所有设备节点,下载firmwares】 3、初始化属性服务器【在两个文件解析步骤2时执行“init”行动】

电脑启动过程详解!!!

电脑启动过程详解 1.当按下电源开关时,电源就开始向主板和其它设备供电,这时电压还不太稳定,主板上的控制芯片组会向CPU发生并保持一个RESET(重置)信号,让CPU内部自动恢复到初始状态,但CPU在些刻不会马上执行指令,当芯片组检查到电源已经开始稳定供电了(当然从不稳定,到稳定的过程只是一瞬间的事情)它便撤去RESET信号(如果是手工按下电脑面板上的RESET按钮来重启机器,那么松开该按钮时芯片组就会撤去RESET信号)CPU马上从地址FFFF0H处开始执行指令,这个地址实际在系统BIOS的地址范围内, 无论是Award BIOS,还是AMI BIOS,在这里的只是一条跳转指令,跳到系统BIOS中真正的启动代码处。 2.系统BIOS的启动代码首先要做的事情就进行POST(Power-On Self Test,加电后自检),POST的主要任务是检查系统中一些关键设备是否存在和是否正常工作,例如内存和显卡等设备.由于POST是最早进行的检查过程,此时显卡还没有初始化,如果系统BIOS在进行POST的过程中发现了些致命错误,例如没有找到内存或内存有问题 (此时只会检查640KB常规内存),那么系统BIOS就会直接控制嗽叭发生声音来报告错误,声音的长短和次数代表了错误的类型.在正常情况下,POST过程进行的非常快,我们几乎无法感觉到它的存在,POST结束之后就会调用其它代码来进行更完整的硬件检测。 3.接下来系统BIOS将查找显卡的BIOS,前面说过,存放显卡BIOS的ROM芯片的超始地址通常设在 C0000H,系统BIOS在这个地方找到显卡BIOS之后就调用它的初始化代码来初始化显卡,此时多数显卡都在屏幕上显示出一些初始化信息,介绍生产厂商,图形芯片类型等内容,不过这个画面几乎是一闪而过,系统BIOS接着会查找其它设备的BIOS程序,找到之后同样会调用这些BIOS内部的初始化代码来初始化相关的设备。 4.查找完所有其它设备的BIOS之后,系统BIOS将显示出它自己的启动画面,其中包括有系统BISO的类型,序列号和版本号等内容. 5.接着系统BIOS将检查和显示CPU的类型和工作频率,然后开始测试所有RAM,并同时在屏莫显示内存测试的速度,用户可以在CMOS设置中自行决定使用简单耗时少或详细耗时多的测试方式. 6.内存测试通过之后,系统BIOS将开始检测系统中安装的一些标准硬件设备,包括硬盘,CD-ROM,串口,并口,软驱等设备,另外绝大数较新版本的系统BIOS在这一过程中还要自动检测和设置内存的定时参数,硬盘参数和访问模式等. 7.标准设备检查完毕后,系统BIOS内部的支持即插即用的代码将开始检测和配置系统中安装的的即插即用设备,每找到一个设备之后,系统BIOS都会在屏幕上显示出设备的名称和型号等信息,同时为该设备分配中断,DMA通道和I/O端口等资源。 8.到这一步为止,所有硬件都已经检测配置完毕了,多数系统BIOS会重新清屏并在屏幕上方显示出一个表格,其它概略地列出了系统中安装的各种标准硬件设备,以及它们使用的资源和一些相关工作参数。 9.接下来系统BIOS会更新ESCD(Extended system configuration data,扩展系统配置数据.)ESCD是系统BIOS用来与操作系统交换硬件配置信息的一种手段,这些数据被存放在CMOS之中,通常ESCD数据只在系统配置发生改变后才会更新,所以不是每次启动电脑时都能够看到"updata ESCD … Success"这样的信息, 不过某些主板的系统BIOS在保存ESCD数据时使用了与widnwos 9x不相同的数据格式,于是widnwos 9x在启动过程中会把ESCD数据修改成自己的格式,但在下一次启动时,既使硬件配置没有发生改变,系统BIOS也会把ESCD的数据格式修改回来,如此循环,将会导致在每次启动电脑时,系统BIOS都要更新一遍ESCD,这就是为什么有些机器在每次启动时都会显示出相关信息的原因。 10.ESCD更新完毕后,系统BIOS的启动代码将进行它的最后一项工作,即根据用户指定的启动顺序从软件,硬件或光驱启动,以从C盘启动为例,系统BIOS将读取并执行硬盘上的主引导记录,主引导记录接着从分区表中找到第一个活动分区,然后读取并执行这个活动分区的引导记录,而分区引导记录将负责读取并执行 IO.SYS这是DOS和widnows 9x的IO.SYS(或NT的NTLDR)首先要初始化一些重要的系统数据,然后将显示出我们熟悉的蓝天白云,在这幅画面之下,widnwos 将继续进行DOS部分和GUI(图形用户界面)部分的引导和初始化工作. 上面介绍的便是电脑在打开电源开关(或按RESET)进行冷启动时所要完成的各种初始化工作,如果在DOS 下按Ctrl Alt DEL组合键,(或从windows中选择重新启动电脑)来进行热启动,那么POST过程将被跳过去,

Linux下添加脚本到开机自启动的方法

Linux下添加脚本到开机自启动的方法 Linux配置开机自启动执行脚本的方法有很多,这里分享两种方法,分别是修改/etc/rc.local方法和chkconfig管理设置的方法,均可实现Linux配置开机自启动执行脚本的功能! 设置test.sh为开机要启动的脚本 [root@oldboy scripts]# vim /server/scripts/test.sh [root@oldboy scripts]# cat /server/scripts/ test.sh #!/bin/bash /bin/echo $(/bin/date +%F_%T) >> /tmp/ test.log 方法一:修改/etc/rc.local [root@oldboy ~]# ll /etc/rc.local lrwxrwxrwx. 1 root root 13 Mar 30 10:50 /etc/rc.local -> rc.d/rc.local 修改/etc/rc.local文件 [root@oldboy scripts]# tail -n 1 /etc/rc.local /bin/bash /server/scripts/test.sh >/dev/null 2>/dev/null 重启系统,查看结果 [root@oldboy ~]# cat /tmp/test.log 2018-03-30_12:00:10 方法二:chkconfig管理 删除掉方法一的配置

[root@oldboy ~]# vim /etc/init.d/test #!/bin/bash # chkconfig: 3 88 88 /bin/bash /server/scripts/test.sh >/dev/null 2>/dev/null [root@oldboy ~]# chmod +x /etc/init.d/test 添加到chkconfig,开机自启动 [root@oldboy ~]# chkconfig --add test [root@oldboy ~]# chkconfig --list test test 0:off 1:off 2:off 3:on 4:off 5:off 6:off 重启系统,查看结果 [root@oldboy ~]# cat /tmp/test.log 2018-03-30_12:00:10 2018-03-30_12:33:20 操作成功 关闭开机启动 [root@oldboy ~]# chkconfig test off [root@oldboy ~]# chkconfig --list test test 0:off 1:off 2:off 3:off 4:off 5:off 6:off 从chkconfig管理中删除test [root@oldboy ~]# chkconfig --list test test 0:off 1:off 2:off 3:off 4:off 5:off 6:off [root@oldboy ~]# chkconfig --del test

Android 开机启动流程

Android的开机流程 1. 系统引导bootloader 1) 源码:bootable/bootloader/* 2) 说明:加电后,CPU将先执行bootloader程序,此处有三种选择 a) 开机按Camera+Power启动到fastboot,即命令或SD卡烧写模式,不加载内核及文件系统,此处可以进行工厂模式的烧写 b) 开机按Home+Power启动到recovery模式,加载recovery.img,recovery.i mg包含内核,基本的文件系统,用于工程模式的烧写 c) 开机按Power,正常启动系统,加载boot.img,boot.img包含内核,基本文件系统,用于正常启动手机(以下只分析正常启动的情况) 2. 内核kernel 1) 源码:kernel/* 2) 说明:kernel由bootloader加载 3. 文件系统及应用init 1) 源码:system/core/init/* 2) 配置文件:system/rootdir/init.rc, 3) 说明:init是一个由内核启动的用户级进程,它按照init.rc中的设置执行:启动服务(这里的服务指linux底层服务,如adbd提供adb支持,vold提供SD卡挂载等),执行命令和按其中的配置语句执行相应功能 4. 重要的后台程序zygote 1)源码:frameworks/base/cmds/app_main.cpp等 2) 说明:zygote是一个在init.rc中被指定启动的服务,该服务对应的命令是/system/bin/app_process a)建立Java Runtime,建立虚拟机 b) 建立Socket接收ActivityManangerService的请求,用于Fork应用程序 c) 启动System Server 5. 系统服务system server 1)源码:frameworks/base/services/java/com/android/server/SystemServer.jav a 2) 说明:被zygote启动,通过SystemManager管理android的服务(这里的服务指frameworks/base/services下的服务,如卫星定位服务,剪切板服务等) 6. 桌面launcher 1)源码:ActivityManagerService.java为入口,packages/apps/launcher*实现 2) 说明:系统启动成功后SystemServer使用xxx.systemReady()通知各个服务,系统已经就绪,桌面程序Home就是在ActivityManagerService.systemReady()通知的过程中建立的,最终调用()启launcher 7. 解锁 1) 源码: frameworks/policies/base/phone/com/android/internal/policy/impl/*lock* 2) 说明:系统启动成功后SystemServer调用wm.systemReady()通知WindowManagerService,进而调用PhoneWindowManager,最终通过LockPatternKeyguardView显示解锁界面,跟踪代码可以看到解锁界面并不是一个Activity,这是只是向特定层上绘图,其代码了存放在特殊的位置

详细讲解思科路由器的启动过程

详细讲解思科路由器的启动过程 在CISCO的路由器上大体有ROM,NVRAM,RAM,FLASH.四种相关的存储介质,分别承载不同的功能.IOS本身装载在FLASH(闪存)当中,RAM存储路由器当前运行的配置文件 (running-config),而路由器当前的启动配置文件(startup-config)则存储在NVRAM中,ROM 中则加载着MiniIos,BootStrap及RomMonitor运行模式程序. 其实路由器其实跟日常生活中的用PC机物理架构差不多,PC的主板,内存,处理器等等在路由里面都存在,一台PC也没有做成一台ROUTER,比如用的比较多的国外的ROUTEROS,国内的海蛛蛛等等软路由系统。 (1)路由器在加电启动以后再进行POST自检过程。 (2)POST自检通过之后,将通过路由器内部的ROM当中的BootStrap程序进行引导。初步引导完成之后,将定位查找FLASH里面的完整的IOS网络操作系统,如果在Rom里面找到完整的Ios文件的话,就进行加载引导。 (3)如果在Fash当中没有找到完整的IOS文件的话,将可以修改寄存器的16进制制值定位到其它模式的转变,比如MiniIos或者RomMonitor模式。通过TFTP服务上传一个完整的Ios文件,然后重起路由器,再进入路由的正常模式的配置。 (4)当Ios文件完整的加载之后,它会在NVRAM当中找寻路由器的Startup-config这个开始启动配置文件的存在,该配置文件保存路由器已经保存下来的配置条目信息,而是在接下来过程当中的Running-Config文件。加载路由器的所有配置,并将这个文件copy到Ram 当中,然后启动进入用户配置模式下进行相关的路由配置。如果在NVRAM当中没有找到开始配置文件(startup-config),将进入到一个向导式的配置模式进行路由器的配置。我们可以选择N,将进入CLI的配置界面进行配置。

计算机启动过程

从打开电源到开始操作,计算机的启动是一个非常复杂的过程。 零、boot 的含义 先问一个问题,"启动"用英语怎么说? 回答是boot。可是,boot 原来的意思是靴子,"启动"与靴子有什么关系呢?原来,这里的boot 是bootstrap(鞋带)的缩写,它来自一句谚语: "pull oneself up by one's bootstraps" 字面意思是"拽着鞋带把自己拉起来",这当然是不可能的事情。最早的时候,工程师们用它来比喻,计算机启动是一个很矛盾的过程:必须先运行程序,然后计算机才能启动,但是计算机不启动就无法运行程序! 早期真的是这样,必须想尽各种办法,把一小段程序装进内存,然后计算机才能正常运行。所以,工程师们把这个过程叫做"拉鞋带",久而久之就简称为boot 了。 计算机的整个启动过程分成四个阶段。 一、第一阶段:BIOS 上个世纪70 年代初,"只读内存"(read-only memory,缩写为ROM)发明,开机程序被刷入ROM 芯片,计算机通电后,第一件事就是读取它。 这块芯片里的程序叫做"基本輸出輸入系統"(Basic 无效/Output System),简称为BIOS。1. 1 硬件自检 BIOS 程序首先检查,计算机硬件能否满足运行的基本条件,这叫做"硬件自检"(Power-On Self-Test),缩写为POST。 如果硬件出现问题,主板会发出不同含义的蜂鸣,启动中止。如果没有问题,屏幕就会显示出CPU、内存、硬盘等信息。 1. 2 启动顺序 硬件自检完成后,BIOS 把控制权转交给下一阶段的启动程序。 这时,BIOS 需要知道,"下一阶段的启动程序"具体存放在哪一个设备。也就是说,BIOS 需要有一个外部储存设备的排序,排在前面的设备就是优先转交控制权的设备。这种排序叫做"启动顺序"(Boot Sequence)。 打开BIOS 的操作界面,里面有一项就是"设定启动顺序"。 二、第二阶段:主引导记录 BIOS 按照"启动顺序",把控制权转交给排在第一位的储存设备。 这时,计算机读取该设备的第一个扇区,也就是读取最前面的512 个字节。如果这512 个字节的最后两个字节是0x55 和0xAA,表明这个设备可以用于启动;如果不是,表明设备不能用于启动,控制权于是被转交给"启动顺序"中的下一个设备。 这最前面的512 个字节,就叫做"主引导记录"(Master boot record,缩写为MBR)。 2. 1 主引导记录的结构 "主引导记录"只有512 个字节,放不了太多东西。它的主要作用是,告诉计算机到硬盘的哪一个位置去找操作系统。 主引导记录由三个部分组成: (1)第1-446 字节:调用操作系统的机器码。 (2)第447-510 字节:分区表(Partition table)。 (3)第511-512 字节:主引导记录签名(0x55 和0xAA)。 其中,第二部分"分区表"的作用,是将硬盘分成若干个区。 2. 2 分区表 硬盘分区有很多好处。考虑到每个区可以安装不同的操作系统,"主引导记录"因此必须知道将控制权转交给哪个区。

linux系统脚本的常见启动顺序

由于相关变量定义不同, 所以以下启动顺序仅供参考 在Redhat Redflag centos fc linux系统里面脚本的启动 先后: 第一步:通过/boot/vm进行启动 vmlinuz 第二步:init /etc/inittab 第三步:启动相应的脚本,并且打开终端 rc.sysinit rc.d(里面的脚本) rc.local 第四步:启动login登录界面 login 第五步:在用户登录的时候执行sh脚本的顺序:每次登录的时候都会完全执行的/etc/profile.d/file /etc/profile /etc/bashrc /root/.bashrc /root/.bash_profile 在Suse Linux (sles server or Desktop 10) 第一步:通过/boot/vm进行启动 vmlinuz 第二步:init /etc/inittab 第三步:启动相应的脚本,并且打开终端 /etc/init.d/boot 里面包括: . /etc/rc.status ./etc/sysconfig/boot ./etc/init.d/boot.d下面的脚本 ./etc/init.d/boot.local rc X.d(里面的脚本) 第四步:启动login登录界面 login 第五步:在用户登录的时候执行sh脚本的顺序:每次登录的时候都会完全执行的/etc/profile.d/file /etc/profile /root/.bashrc /root/.profile 先后: 第一步:通过/boot/vm进行启动 vmlinuz 第二步:init /etc/inittab 第三步:启动相应的脚本,并且打开终端 rc.sysinit rc.d(里面的脚本) rc.local 第四步:启动login登录界面 login 第五步:在用户登录的时候执行sh脚本的顺序:每次登录的时候都会完全执行的/etc/profile.d/file

基于MT6752的 android 系统启动流程分析报告

基于MT6752的Android系统启动流程分析报告 1、Bootloader引导 (2) 2、Linux内核启动 (23) 3、Android系统启动 (23) 报告人: 日期:2016.09.03

对于Android整个启动过程来说,基本可以划分成三个阶段:Bootloader引导、Linux kernel启动、Android启动。但根据芯片架构和平台的不同,在启动的Bootloader阶段会有所差异。 本文以MTK的MT6752平台为例,分析一下基于该平台的Android系统启动流程。 1、Bootloader引导 1.1、Bootloader基本介绍 BootLoader是在操作系统运行之前运行的一段程序,它可以将系统的软硬件环境带到一个合适状态,为运行操作系统做好准备,目的就是引导linux操作系统及Android框架(framework)。 它的主要功能包括设置处理器和内存的频率、调试信息端口、可引导的存储设备等等。在可执行环境创建好之后,接下来把software装载到内存并执行。除了装载software,一个外部工具也能和bootloader握手(handshake),可指示设备进入不同的操作模式,比如USB下载模式和META模式。就算没有外部工具的握手,通过外部任何组合或是客户自定义按键,bootloader也能够进入这些模式。 由于不同处理器芯片厂商对arm core的封装差异比较大,所以不同的arm处理器,对于上电引导都是由特定处理器芯片厂商自己开发的程序,这个上电引导程序通常比较简单,会初始化硬件,提供下载模式等,然后才会加载通常的bootloader。 下面是几个arm平台的bootloader方案: marvell(pxa935) : bootROM + OBM + BLOB informax(im9815) : bootROM + barbox + U-boot mediatek(mt6517) : bootROM + pre-loader + U-boot broadcom(bcm2157) : bootROM + boot1/boot2 + U-boot 而对MT6752平台,MTK对bootloader引导方案又进行了调整,它将bootloader分为以下两个部分: (1) 第1部分bootloader,是MTK内部(in-house)的pre-loader,这部分依赖平台。 (2) 第2部分bootloader,是LK(little kernel的缩写,作用同常见的u-boot差不多),这部分依赖操作系统,负责引导linux操作系统和Android框架。 1.2、bootloader的工作流程 1.2.1 bootloader正常的启动流程 先来看启动流程图:

linux内核启动 Android系统启动过程详解

linux内核启动+Android系统启动过程详解 第一部分:汇编部分 Linux启动之 linux-rk3288-tchip/kernel/arch/arm/boot/compressed/ head.S分析这段代码是linux boot后执行的第一个程序,完成的主要工作是解压内核,然后跳转到相关执行地址。这部分代码在做驱动开发时不需要改动,但分析其执行流程对是理解android的第一步 开头有一段宏定义这是gnu arm汇编的宏定义。关于GUN 的汇编和其他编译器,在指令语法上有很大差别,具体可查询相关GUN汇编语法了解 另外此段代码必须不能包括重定位部分。因为这时一开始必须要立即运行的。所谓重定位,比如当编译时某个文件用到外部符号是用动态链接库的方式,那么该文件生成的目标文件将包含重定位信息,在加载时需要重定位该符号,否则执行时将因找不到地址而出错 #ifdef DEBUG//开始是调试用,主要是一些打印输出函数,不用关心 #if defined(CONFIG_DEBUG_ICEDCC)

……具体代码略 #endif 宏定义结束之后定义了一个段, .section ".start", #alloc, #execinstr 这个段的段名是 .start,#alloc表示Section contains allocated data, #execinstr表示Section contains executable instructions. 生成最终映像时,这段代码会放在最开头 .align start: .type start,#function /*.type指定start这个符号是函数类型*/ .rept 8 mov r0, r0 //将此命令重复8次,相当于nop,这里是为中断向量保存空间 .endr b 1f .word 0x016f2818 @ Magic numbers to help the loader

(完整版)路由器的启动过程

路由器的启动过程大致分为以下几个阶段: (1)开机自检(power-on self,POST) (2)如果(1)正常,IOS存在,将从闪存FLASH中查找和加载IOS到随机存储器RAM中(但2500系列不加载RAM中,直接从闪存中运行)。 (3)如果(1)和(2)正常,接下来它将在非易失存储器NVRAM中查找启动配置文件startup-config,假如没有找到任何启动配置文件,router将进入到SETUP模式。 (4)如果在非易失存储器NVRAM中查找到启动配置文件startup-config,将按照启动配置文件startup-config启动路由器。

这个图全面的说明了路由器的启动过程,其中有好几个需要说明的地方。 请各位注意: 1、boot field 启动字段 2、run rom monitor rom监控模式 3、use IOS in ROM(RXboot mode)运行在ROM中的MINI IOS 4、Config reg bit{13 Cisco系统的启动过程依赖于配置寄存器的值,在IOS中表现为 config-register。配置寄存器共16bits,表现为4个16进制数:0xABCD,赋值范围从0x0到0xFFFF。 平时的0x2102是16进制(0x 嘛~)换成2进制就出来途中的那些位了 0010 0001 0000 0010 从0位开始到15位 例子: 0x2102 :默认值(正常读取NVRAM的startup-config启动,Flash一般为Read Only)。 0x2142 :从Flash启动,但不使用NVRAM中的配置文件(用于口令恢复,Flash 一般为Read Only)。 0x2101 :从Boot RAM中启动,读取ROM中的IOS和NVRAM中的startup-config,

计算机启动过程

计算机启动过程 讲课教师:黄小龙 计算机启动过程总体分为两个过程,即硬件启动过程和操作系统启动过程。本课中操作系统我们仅选用Windows XP 的启动过程讲解。 一、硬件启动过程 ⑴加电 按下电源开关后,电源就开始向主板和其它设备供电,此时电压还不稳定, 主板上的控制芯片组会向CPU 发出并保持一个RESET(重置)信号,让CPU 初始化。当电源开始稳定供电后,芯片组便撤去RESET 信号(如果是按下Reset 按钮来重启,那么松开该按钮时芯片组就会撤去RESET 信号)。然后,CPU 马上就从地址FFFF0H 处开始执行指令(这是BIOS 的起始地址),但放在这里的只是一条跳转指令,跳到系统真正的BIOS 启动代码处,由BIOS 的代码进行下一步的POST 自检。 ⑵BIOS 进行post

POST就是加电自检,它是Power On Sel f Test的缩写。它是检查一些关键设备是否存在和能否正常工作,如内存和显卡等。如果发现错误,则通过喇叭发声来报告错误情况,此时的声音长短和次数代表了错误类型。 注:由于POST的检测过程在显示卡初始化之前,因此POST 自检过程发现的错误是无法在屏幕上显示出来的。 ⑶BIOS检测硬件的各种信息 BIOS进行加电自检后,就开始检测计算机上硬件设备的各种信息,如设备类型、工作频率、芯片组型号、出厂厂商等。这阶段的硬件检测顺序是:显示卡、CPU、内存、其它标准硬件设备(如硬盘、光驱、软驱、外设等)。 ⑷BIOS更新ESCD 按下来系统BIOS将更新ESCD(Extended System Configuration Data,扩展系统配置数据)。ESCD是系统BIOS用来与操作系统交换硬件配置信息的数据,这些数据被存放在CMOS之中。通常ESCD数据只在系统硬件配置发生改变后才会进行更新,因此不是每次启动都能看到"Update ESCD... Success"这样的信息。不过,某些主板的BIOS在保存ESCD数据时使用了与Windows 9x 不相同的数据格式,于是Windows 9x在每一次启动都会把ESCD 数据转换成自己的格式,导致BIOS每次重新启动时都认为是硬件配置发生变化,并重新改写ESCD数据,这就是为什么有的计算机在每次启动时都会显示"Update ESCD... Success"信息的原因。

设置Linux开机自动运行脚本

设置Linux开机自动运行脚本 参考资料 实现目标:在Linux启动时,自动运行位于普通用户test1根目录下的脚本程序test.py,该程序会在每次执行时自动向本地日志文件追加一条记录,源码如下: fromdatetime import datetime now=datetime.now() f=open('test.log','a') f.write('%s '%now) f.close() Linux在启动时,会自动执行/etc/rc.d目录下的初始化程序,因此我们可以把启动任务放到该目录下,有两种办法: 方案一: 1、因为其中的rc.local是在完成所有初始化之后执行,因此我们可以把启动脚本写到里面 2、用root账号登陆Linux,vi /etc/rc.d/rc.local编辑文件,在最后加入两行需要执行的脚本程序: cd /home/test1 --该步不可少,否则会提示没有权限打开'test.log'文件 su test1 -c "python /home/test1/test.py" --把要执行的命令作为一个参数传递级su 方案二: 1、init.d目录下都为可执行程序,他们其实是服务脚本,按照一定格式编写,Linux 在启动时会自动执行,类似Windows下的服务 2、用root帐号登录,vi /etc/rc.d/init.d/mystart,追加如下内容: #!/bin/bash #chkconfig:2345 80 05 --指定在哪几个级别执行,0一般指关机, 6指的是重启,其他为正常启动。80为启动的优先级,05为关闭的优先机 #description:mystart service RETVAL=0 start(){ --启动服务的入口函数 echo -n "mystartserive ..." cd /home/test1 su test1 -c "python /home/test1/test.py" }

Android开机启动流程样本

Android的开机流程 1. 系统引导bootloader 1) 源码: bootable/bootloader/* 2) 说明: 加电后, CPU将先执行bootloader程序, 此处有三种选择 a) 开机按Camera+Power启动到fastboot, 即命令或SD卡烧写模式, 不加载内核及文件系统, 此处能够进行工厂模式的烧写 b) 开机按Home+Power启动到recovery模式, 加载recovery.img, recovery.img包含内核, 基本的文件系统, 用于工程模式的烧写 c) 开机按Power, 正常启动系统, 加载boot.img, boot.img包含内核, 基本文件系统, 用于正常启动手机( 以下只分析正常启动的情况) 2. 内核kernel 1) 源码: kernel/* 2) 说明: kernel由bootloader加载 3. 文件系统及应用init 1) 源码: system/core/init/* 2) 配置文件: system/rootdir/init.rc, 3) 说明: init是一个由内核启动的用户级进程, 它按照init.rc中的设置执行: 启动服务( 这里的服务指linux底层服务, 如adbd提供adb支持, vold提供SD卡挂载等) , 执行命令和按其中的配置语句执行相应功能 4. 重要的后台程序zygote 1) 源码: frameworks/base/cmds/app_main.cpp等 2) 说明: zygote是一个在init.rc中被指定启动的服务, 该服务对应的命令是/system/bin/app_process

OSPF启动状态-OSPF接口启动过程(7个状态)

OSPF路由协议接口启动过程 ———————————————————————— 试验原理:OPSF接口工作的启动过程 ? DOWN状态:没有与任何邻居交换信息. ? INIT状态:每10秒发送HELLO包(类型1) ? TWO-WAY双向状态:基本状态,当看到自己出现在邻居路由器的HELLO数据包中时,它就进入了双向状态. ? EXSTART准启动状态:两个邻居路由器用DBD数据包来协商主从关系,有最高OSPF路由器ID的路由器胜出为主(debug ip ospf events). ? EXCHANGE交换状态:路由器相互描述它们的链路状态数据库. ? LOADING加载状态:接收类型3(LSR状态请求包)-回应类型4(LSU链路状态更新包) –确认类型5(LSA链路状态确认包) ? FULL ADJACENCY全邻接状态:生成邻接数据库(邻居路由器列表),另外,还有链路状态数据库(拓扑结构数据库)和转发数据库(路由表)生成。 广播型多路访问的网络中才进行DR/BDR的选举.多是以太网络环境。 试验拓扑: 实际环境: 只配置fa0/0接口:

l 在R1上: 配置接口地址: 1(config)#int fa0/0 1(config-if)#ip add 192.168.1.1 255.255.255.0 1(config-if)#no shut 启动协议: 1(config)#router ospf 1 1(config-router)#net 192.168.1.0 0.0.0.255 area 0 1(config-router)#end 在R2上: 配置接口: 2(config)#int fa0/0 2(config-if)#ip add 192.168.1.2 255.255.255.0 2(config-if)#no shut 启动协议: 2(config)#router ospf 1 2(config-router)#net 192.168.1.0 0.0.0.255 area 0 在R3上: 配置接口:

计算机启动过程

计算机系统的启动过程 1:硬件自检 BIOS程序首先检查计算机的硬件是否满足运行的基本条件,这就叫做“硬件自检”(Power-On Self-Test),POST。如果硬件出现问题,主板会发出不同含义的蜂鸣启动就会终止,,如果没有问题,屏幕就会显示出CPU,内存,硬盘等信息。 2:启动程序 硬件自检完成之后,BIOS就把控制权转交给下一阶段的启动程序。 这时,BIOS需要知道“下一阶段的启动程序”具体存放在哪一个设备。也就是说,BIOS 需要有一个外部储存设备的排序,排在前面的设备就是优先被转交控制权的设备。这种排序叫做“启动顺序”(Boot Sequence)。 打开BIOS的操作界面我们就可以看到里面有一项是“设定启动顺序”。 主引导记录 BIOS按照“启动顺序”,把控制权转交给排在第一位的储存设备。 这时,计算机读取该设备的第一个扇区,也就是读取最前面的512字节,如果这512个字节的最后两个字节是0x55和0xAA,表明这个设备可以启动,否则则不可以启动控制权被交与“启动顺序”中的下一个设备。 这最前面的512个字节,就叫做"主引导记录"(Master boot record,缩写为MBR)。 1:主引导记录的结构 “主引导记录”只有512个字节,放不了太多东西。它的主要作用是,告诉计算机到硬盘的哪一个位置去找操作系统。 主引导记录由三个部分组成: (1)第1-446字节:调用操作系统的机器码。 (2)第447-510字节:分区表(Partition table)。 (3)第511-512字节:主引导记录签名(0x55和0xAA)。 其中,第二部分"分区表"的作用,是将硬盘分成若干个区。 2:分区表 硬盘分区有很多好处。考虑到每个区可以安装不同的操作系统,"主引导记录"因此必须知道将控制权转交给哪个区。 分区表的长度只有64个字节,里面又分成四项,每项16个字节。所以,一个硬盘最多只能分四个一级分区,又叫做"主分区"。 每个主分区的16个字节,由6个部分组成: (1)第1个字节:如果为0x80,就表示该主分区是激活分区,控制权要转交给这个分四个主分区里面只能有一个是激活的。 (2)第2-4个字节:主分区第一个扇区的物理位置(柱面、磁头、扇区号等等)。 (3)第5个字节:主分区类型。 (4)第6-8个字节:主分区最后一个扇区的物理位置。

启动过程以及各个脚本的作用

开机自检-----MBR引导-----GRUB菜单------加载内核-----允许init进程 -----读取inittab(该文件中有运行级别,初始化文件,某个运行级别所要读取的文件,然后就执行/etc/rc.d/rcn.d向对应的文件) ----/etc/rc.d/rc.sysinit(由init进程调用执行,完成设置网络主机名加载文件系统等初始化工作------/etc/rc.d/rc(由init进程调用执行,根据指定的运行级别加载或终止相应的系统服务)------/etc/rc.d/rc.nd(是个目录,目录中有级别关闭和开启的服务K S 后的数字表示启动或关闭服务的优先级,越小越好----执行/etc/rc.d/rc.local(由rc脚本执行调用,保存用户定义的所需开机后自动执行的命令,可以开启某些服务,但是却不能关闭服务,因为关机时不读取该脚本,是最后读取的文件) -----启动mingetty(启动一个虚拟终端) init进程和inittab引导指令 init进程是系统所有进程的起点,内核在完成核内引导以后,即在本线程(进程)空间内加载init程序,它的进程号是1。 init程序需要读取/etc/inittab文件作为其行为指针,inittab是以行为单位的描述性(非执行性)文本,每一个指令行都具有以下格式: id:runlevel:action:process其中id为入口标识符,runlevel为运行级别,action为动作代号,process为具体的执行程序。 id一般要求4个字符以内,对于getty或其他login程序项,要求id与tty的编号相同,否则getty程序将不能正常工作。 runlevel是init所处于的运行级别的标识,一般使用0-6以及S或s。0、1、6运行级别被系统保留,0作为shutdown动作,1作为重启至单用户模式,6为重启;S和s意义相同,表示单用户模式,且无需inittab文件,因此也不在inittab中出现,实际上,进入单用户模式时,init直接在控制台(/dev/console)上运行/sbin/sulogin。 在一般的系统实现中,都使用了2、3、4、5几个级别,在Redhat系统中,2表示无NFS支持的多用户模式,3表示完全多用户模式(也是最常用的级别),4保留给用户自定义,5表示XDM图形登录方式。7-9级别也是可以使用的,传统的Unix系统没有定义这几个级别。runlevel可以是并列的多个值,以匹配多个运行级别,对大多数action来说,仅当runlevel与当前运行级别匹配成功才会执行。 initdefault是一个特殊的action值,用于标识缺省的启动级别;当init由核心激活以后,它将读取inittab中的initdefault项,取得其中的runlevel,并作为当前的运行级别。如果没有inittab文件,或者其中没有initdefault 项,init将在控制台上请求输入 runlevel。

Android SystemBar启动流程分析

Android SystemBar启动流程分析 SystemBars的服务被start时,最终会调用该类的onNoService()方法。 @Override public void start() { if (DEBUG) Log.d(TAG, "start"); ServiceMonitor mServiceMonitor = new ServiceMonitor(TAG, DEBUG, mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this); mServiceMonitor.start(); // will call onNoService if no remote service is found } @Override public void onNoService() { if (DEBUG) Log.d(TAG, "onNoService"); createStatusBarFromConfig(); // fallback to using an in-process implementation } private void createStatusBarFromConfig() { … mStatusBar = (BaseStatusBar) cls.newInstance(); … mStatusBar.start(); } BaseStatusBar是一个抽象类,故调用其子类的PhoneStatusBar的start 函数。 @Override public void start() { … super.start(); … } 子类的start又调用了父类的start public void start() { … createAndAddWindows(); … }

相关主题
文本预览
相关文档 最新文档