2.16.6.内核启动的C语言阶段3

本节讲解setup_arch函数中的machine查找的部分,初步分析了内核对机器码的定义和存储方式、比对方式、获取方式。

2.16.6.1、setup_arch函数简介

setup_arch(&command_line);

(1)从名字看,这个函数是CPU架构相关的一些创建过程。

(2)实际上这个函数是用来确定我们当前内核的机器(arch、machine)的。我们的linux内核会支持一种CPU的运行,CPU+开发板就确定了一个硬件平台,然后我们当前配置的内核就在这个平台上可以运行。之前说过的机器码就是给这个硬件平台一个固定的编码,以表征这个平台。

每个体系都有自己的set_arch函数,是体系结构相关的,具体编译哪个体系的setup_arch函数,又顶层的makefile中的arch变量决定。

它首先通过检测出来的处理器类型进行处理器内核的初始化,然后通过bootmem_init函数根据系统定义的meminfo结构体进行内存结构的初始化,最后调用pageing_init开启MMU,创建良好页表,映射所有的物理内存和IO空间。

start_kernel ()

--> setup_arch ()

--> paging_init ()

--> bootmem_init ()

--> alloc_bootmem_low_pages ()

(3)当前内核支持的机器码以及硬件平台相关的一些定义都在这个函数中处理。

2.16.6.2、Machine查找

(1)setup_processor函数用来查找CPU信息,可以结合串口打印的信息来分析。

setup_processor();

* 这个函数首先从arm寄存器里面取得CPU ID,然后调用lookup_processor_type来取得proc_info_list这个结构体。取得proc_info_list之后,将里面的内容一个个赋值相应的全局变量,然后将CPU的信息打印出来。然后它会从ARM寄存器里面获得cache的信息,并将cache的信息打印出来。最后它会调用cpu_proc_init的函数,这个函数实际上定义在proc_v6.S里面,没有做任何事情。

(2)mdesc = setup_machine(machine_arch_type);

* setup_machine函数的传参是机器码编号,machine_arch_type符号在include/generated/mach-types.h的32039-32050行定义了。经过分析后确定这个传参值就是2456.

* 函数的作用是通过传入的机器码编号,找到对应这个机器码的machine_desc描述符,并且返回这个描述符的指针。

* 其实真正干活的函数是lookup_machine_type,找这个函数发现在head-common.S中,真正干活的函数是__lookup_machine_type

* __lookup_machine_type函数的工作原理:内核在建立的时候就把各种CPU架构的信息组织成一个一个的machine_desc结构体实例,然后都给一个段属性.arch.info.init,链接的时候会保证这些描述符会被连接在一起。__lookup_machine_type就去那个那些描述符所在处依次挨个遍历各个描述符,比对看机器码哪个相同。

原文地址:https://www.cnblogs.com/Ocean-Star/p/9236005.html

时间: 2024-11-12 03:17:18

2.16.6.内核启动的C语言阶段3的相关文章

2.16.4.内核启动的C语言阶段1

本节讲述内核学习的学习思路.学习方法和主体线路.本节课程的学习目的是让大家对内核的特点和不同的学习思路有个认识. 2.16.4.1.这一块的学习思路 (1)抓大放小,不深究. (2)感兴趣可以就某个话题去网上搜索资料学习 (3)重点局部深入分析 2.16.4.2.具体学习方法 (1)顺着代码执行路径抓全.这是我们的学习主线. (2)对照内核启动的打印信息进行分析. 2.16.4.3.几条学习线路 (1)分析uboot给kernel传参的影响和实现 (2)硬件初始化与驱动加载 (3)内核启动后的结

2.16.3.内核启动的汇编阶段

参考https://blog.csdn.net/skyflying2012/article/details/41344377 本节是内核启动的汇编阶段剩余内容,主要是cpu的校验.机器码的校验.传参tag的校验.页表的创建.各种段的处理等. 2.16.3.1.__lookup_processor_type (1)我们从cp15协处理器的c0寄存器中读取出硬件的CPU ID号,然后调用这个函数来进行合法性检验.如果合法则继续启动,如果不合法则停止启动,转向__error_p启动失败. (2)该函数

内核启动流程2-C语言部分的最后一个函数init_post()

最后分析最终调用用户空间init进程的函数init_post(). static noinline int init_post(void)这是一个非_init函数.强制让它为非内联函数,以防gcc让它内联到init()中成为init.text段的一部分. async_synchronize_full(); free_initmem(); 这两行用于释放所有init.*段所占用内存. unlock_kernel(); 释放大内核锁,使该线程可以在其他处理器上运行. mark_rodata_ro()

内核启动早期的打印

在移植4.16内核到tiny4412的过程中遇到一个问题,官方的uboot2012引导内核成功卡在staring the kernel没有了下文,看来内核还没有到注册uart驱动就已经挂掉了,尝试打开 early printk ,让内核自解压之后能够及时的打印信息. 说句题外话,内核启动卡在staring the kernel,在2440的时代,未使用设备树,这种情况往往是机器ID设置错误,或者是串口波特率等方面的原因导致,在设备树的时代,机器ID已经被废除,最有可能的问题可能就是出在设备树的身

Linux内核启动及根文件系统载入过程

上接博文<u-boot之u-boot-2009.11启动过程分析> Linux内核启动及文件系统载入过程 当u-boot開始运行bootcmd命令,就进入Linux内核启动阶段.与u-boot类似,普通Linux内核的启动过程也能够分为两个阶段,但针对压缩了的内核如uImage就要包含内核自解压过程了.本文以linux-2.6.37版源代码为例分三个阶段来描写叙述内核启动全过程.第一阶段为内核自解压过程,第二阶段主要工作是设置ARM处理器工作模式.使能MMU.设置一级页表等,而第三阶段则主要为

Linux内核启动及文件系统加载过程

上接博文<u-boot之u-boot-2009.11启动过程分析> 当u-boot开始执行bootcmd命令,就进入Linux内核启动阶段,与u-boot类似,普通Linux内核的启动过程也可以分为两个阶段,但针对压缩了的内核如uImage就要包括内核自解压过程了.本文以项目中使用的linux-2.6.37版源码为例分三个阶段来描述内核启动全过程.第一阶段为内核自解压过程,第二阶段主要工作是设置ARM处理器工作模式.使能MMU.设置一级页表等,而第三阶段则主要为C代码,包括内核初始化的全部工作

Linux内核启动及加载根文件系统

</pre></h1><p><span style="font-family:KaiTi_GB2312;font-size:18px;">上接博文<<a target=_blank href="http://blog.csdn.net/gqb_driver/article/details/8931775" style="text-decoration: none; font-family: 'Mi

Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3.0 ARMv7) 【转】

原文地址:Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3.0 ARMv7) 作者:tekkamanninja 转自:http://blog.chinaunix.net/uid-25909619-id-4938390.html 在构架相关的汇编代码运行完之后,程序跳入了构架无关的内核C语言代码:init/main.c中的start_kernel函数,在这个函数中Linux内核开始真正进入初始化阶段, 下面我就顺这代码逐个函数的解释,但是这里并不会过于深入

Tiny4412 Linux 内核启动流程

Linux内核的启动分为压缩内核和非压缩内核两种,这里我们以压缩内核为例.压缩内核运行时,将运行一段解压缩程序,得到真正的内核镜像,然后跳转到内核镜像运行.此时,Linux进入非压缩内核入口,在非压缩内核入口中,完成各种初始化操作后跳转到C语言入口处运行.主要流程如下所示. 1.解压缩内核镜像 解压缩程序通常在arch/arm/boot/compressed/目录中 ├── atags_to_fdt.c ├── big-endian.S ├── decompress.c ├── head.S ├