作为一名软件开发工程师,似乎很少去关注这样偏硬件问题。相比于
在浏览器中输入网址之后发生了什么?
而言,当我们按了开机键发生了什么
更加偏向于硬件。昨天和一个清华毕业的CTO(膜拜)交流的时候,他向我问了这个问题,当时答得不是很完整,顾在这里做个总结。
在浏览器中输入网址之后发生了什么?
在浏览器地址栏输入一个URL后回车,背后会进行哪些技术步骤?
当我们按了开机键,发生了什么?
下面分几个部分介绍:
- 1.PC
- 2.Andriod
- 3.iPhone(暂时还未找到相关资料。可以和PC,Andriod类比)
PC
简单来说分为下面几个步骤:
- 1.按下开机键,告诉PC打开电源
- 2.当电源打开后,PC做的第一件事情就是CPU从内置的芯片中加载一个最简单程序,这个程序叫做BIOS(基本输入输出系统)。
- 3.BIOS程序启动后就会检测硬件设备,比如显卡,内存,
- 4.CPU从硬盘上加载操作系统(Windows/MacOS/Linux。
- 5.完成启动过程
如果想更为深入的了解。那需要了解计算机的组成
- PSU(power supply unit):电源提供单元,提供PC所有部分的电源,通常像一个金属盒子安装在主机的前后和电线连接下一起。PC所有的电源都由这里供给。
- Motherboard:主机板Motherboard或是Mainboard是计算机最主要的电路板,上面装着计算机系统的主要电子组件如CPU、芯片组、内存插槽,及键盘、I/O、磁盘驱动器等的控制器。并从PSU获得电源
- CPU:中央处理器,处理逻辑运算的地方,通过插槽嵌在主板中。
- RAM: 随机存储器,其实就是内存。
- Hard Drives:硬盘
- Northbridge:北桥:一般位于主板上离CPU插槽较进的地方。一般来说,芯片组的名称就是以北桥芯片的名称来命名的,北桥芯片负责与CPU的联系并控制内存、PCI-E数据在北桥内部传输,提供对CPU的类型和主频、系统的前端总线频率、内存的类型(SDRAM,DDR、DDR2、DDR3、以及RDRAM等等)和最大容量、AGP/PCI-E插槽、ECC纠错等支持,整合型芯片组的北桥芯片还集成了显示核心。
- Southbridge:南桥:一般位于主板上离CPU插槽较远的下方,PCI插槽的附近,这种布局是考虑到它所连接的I/O总线较多,离处理器远一点有利于布线。相对于北桥芯片来说,其数据处理量并不算大,所以南桥芯片一般都没有覆盖散热片。南桥芯片不与处理器直接相连,而是通过一定的方式(不同厂商各种芯片组有所不同,例如英特尔的英特尔Hub Architecture以及SIS的Multi-Threaded“妙渠”)与北桥芯片相连。南桥芯片主要是负责I/O接口等一些外设接口的控制、IDE设备的控制及附加功能等等。
- BIOS:基本输入输出系统:包含了最为基本的启动代码,集成在主板上的一个内存芯片,和南桥相连。这就解释为为什么所有的程序软件包括操作系统都是运行在内存中的,然而我们的操作系统一般是存放在硬盘上的,当我们按下开机键的时候,此时内存中什么程序也没有,后来居然操作系统能够被加载的原因。完成将操作系统加载到内存中,这就是BIOS的任务。
所有真真发生了什么呢?这个问题真的有点复杂。详细内容可以看看What are the steps in the process of a PC start-up after pressing the power on?
- You push the power button. This power button is a simply a contact switch connected to the motherboard.
- That contact switch is connected to a circuit on the motherboard that activates the PSU's "power on" input. Physically, that's the thin green wire in the big bundle of wires between the motherboard and the PSU. Pushing the button activates a circuit in the motherboard that shorts that wire to ground (all the black wires) and latches it, so that the power remains on even when you remove your finger from the button. The circuit on the motherboard also does one other thing - when the power is already on, pushing the button again doesn't kill the power, instead a signal is sent to the Southbridge as an IRQ to signal to the OS to shut down safely. Only when the OS is finished shutting down does it automatically cut the power. However, holding the button for three seconds causes the circuit to override this behaviour, and kill the power directly.
- When the PSU detects a power-on signal, it turns on and starts supplying power to all the components. All the fans spin up, and the hard drives turn on, this is why you hear all the whirring when you push the power button.
- The first thing that happens at power on, is the CPU starts executing the program stored in the BIOS chip's memory (if you want details of how this works, refer to how CPUs work in general, but the gist is: the CPU sends out the memory address that corresponds to the BIOS to the Northbridge, which routes it to the Southbridge, which then signals the BIOS chipt to deliver the data contained in that memory, and that data works its way back up to the CPU, were it is executed). This program contains the routines for the CPU to be able to detect and access the drives (including boot from USB, boot from CD, etc.), how to load up the OS, basic keyboard inputs, other self-testing routines like POST, and also other similar memory like the network boot ROM.
- When the BIOS program is done with all the self-testing and is ready to boot, it scans all the drives that it knows how to access for a valid bootloader. On most Windows computers you don't see the bootloader unless you hit the F8 key when booting (you'll be presented with various booting options). On Linux machines, you'll see GRUB or LILO, or one of the other common bootloaders. These are small piece of software that allows the CPU to begin loading the OS program, and gives any special start-up conditions/configurations to the OS to use when booting up (e.g. Windows has stuff like "safe mode", Linux has a plethora of options).
- The CPU is now set up to begin loading the OS from the boot drive (again, what this means is that the CPU sends out the address of the data that it wants, the Northbridge and Southbridge routes that address to the device in question, and the device produces the data, which is then routed back into the CPU where it is executed (or loaded into the RAM where it's stored for later execution)).
BIOS程序怎么启动
- CS:代码段寄存器,存在于CPU中,指向CPU当前执行代码在内存中所在的区域。
- IP:指令寄存器,存在于CPU中,记录将要执行的指令在代码段内的偏移地址,与CS组合即为将要执行的指令的内存地址。
BIOS
的启动,是由硬件完成的,Intel 80x86
系列的cpu的硬件都设计为加电(即开机瞬间)就进入16位实模式状态运行,此时将cpu的硬件逻辑设计为强行将CS的值设置为0xFFFF
,IP的值设置为0x0000
,这样CS:IP就指向了0xFFFF0这个位置,而这个位置就是BIOS程序的入口地址。因此这是一个硬件厂商之间的约定,所有的BIOS程序入口地址均为0xFFFF0,这样在开机的时候,就找到这个地址,如果该地址并没有代码段,那么计算机将会死机,如果这个地址处有代码段,将会执行这个代码段,并由此执行下去,即BIOS
程序开始启动。
操作系统如何从硬盘加载
当BIOS程序启动时,就会检测硬件设备,比如我们的显卡、内存等信息。BIOS会在内存中建立中断向量表和中断服务程序。中断向量表中有256个中断向量,每个中断向量占4个字节,每个中断向量指向一个中断服务程序,这些中断服务程序完成了将操作系统由硬盘加载到内存中的任务。
具体来讲就是计算机硬件体系会与BIOS联合操作,让cpu接收到一个int 0x19
中断,cpu接收到这个中断后,会立即在中断向量表中找到int 0x19
中断向量,此时会找到对应的中断服务程序,并由该中断服务程序将硬盘中第一个扇区的引导程序加在到内存中的指定位置。随后,在引导程序的作用下,陆续将操作系统的其他程序载入内存,完成实模式到保护模式的转变,为执行操作系统的入口函数main做准备,后面就是操作系统的初始化工作了,最后完成计算机的启动。
Android
由于Android
是开源的,所以比较容易分析。网上也有比较全面的文章介绍。直接给出几个链接,有兴趣的可以看看。
http://blog.chinaunix.net/uid-26569496-id-3891554.html
http://www.jianshu.com/p/b4aab68c12c0
http://gityuan.com/2016/01/30/android-boot/
要点:
PC中的BIOS程序。取而代之的是Bootloader——系统启动加载器。它类似于BIOS,在系统加载前,用以初始化硬件设备,建立内存空间的映像图,为最终调用系统内核准备好环境。
PC中硬盘,取而代之的是ROM,它类似于硬盘存放操作系统,用户程序等。ROM跟硬盘一样也会划分为不同的区域,用于放置不同的程序,在Android中主要划分为一下几个分区:
/boot:存放引导程序,包括内核和内存操作程序
/system:相当于电脑c盘,存放Android系统及系统应用
/recovery:恢复分区,可以进入该分区进行系统恢复
/data:用户数据区,包含了用户的数据:联系人、短信、设置、用户安装的程序
/cache:安卓系统缓存区,保存系统最常访问的数据和应用程序
/misc:包含一些杂项内容,如系统设置和系统功能启用禁用设置
/sdcard:用户自己的存储区,可以存放照片,音乐,视频等文件
加载Bootloader程序(类比加载BIOS)
cpu会从cpu制造厂商预设的地址上取指令,这个地址是各厂商约定俗称的,类似于上面80x86架构里的0xFFFF0
地址,因此Android手机会将固态存储设备ROM预先映射到该地址上,当开机加电的时候,cpu就会从该地址执行/boot分区下的Bootloader程序,载入linux内核到RAM中。
Zygote fork
当linux内核启动后会初始化各种软硬件环境,加载驱动程序,挂载根文件系统,并开始执行根文件系统的init程序,init程序是Android启动过程中最重要的核心程序。init进程会启动各种系统本地服务,如:Media Server、Service Manager、bootanim(开机动画)等。init进程会在解析init.rc文件后fork出Zygote,而Zygote是所有Java进程的父进程,我们的App都是由Zygote fork出来的。
Zygote进程主要包含:
加载ZygoteInit类,注册Zygote Socket服务端套接字;
加载虚拟机;
预加载Android核心类
预加载系统资源
随后Zygote进程会fork出System Server进程,System Server进程负责启动和管理整个framework,包括Activity Manager,PowerManager等服务。
当System Server将系统服务启动就绪后,就会通知ActivityManager启动首个Android程序Home即我们看到的桌面程序。
iPhone
暂时没有找到介绍这方面的资料。苹果封闭的生态,我们只要靠猜。
网友评论