linux源码分析(五)-start_kernel
前置:这里使用的linux版本是4.8,x86体系。
local_irq_disable();
这个函数是做了关闭中断操作。和后面的local_irq_enable相对应。说明启动的下面函数是不允许被中断抢占的。这个函数追下去会发现下面的代码:
static inline void native_irq_disable(void)
{
asm volatile("cli": : :"memory");
}
这个写法是linux的内联汇编写法。在C语言中写汇编语言。实际上调用的是汇编cli命令。cli命令是禁用中断功能。http://rock3.info/blog/2013/11/24/linux-c中调用汇编用法/
接着start_kernel,linux关闭完中断之后,还使用了一个变量early_boot_irqs_disabled来标记已经关闭irq了。
这里稍微说说irq的概念,我们把中断分为两个概念,一个是上半部,一个是下半部,上半部指的是硬件直接要求立即响应的中断。下半部指的是可以在某个特定时间之后执行的。这里的IRQ就是一个上半部概念。每个硬件设备都有一个irq线,通过这个线把中断描述符传递给CPU,CPU获取中断之后立即执行对应已经注册的操作。
boot_cpu_init()
这个函数功能是初始化第一个CPU。
void __init boot_cpu_init(void)
{
int cpu = smp_processor_id();
/* Mark the boot cpu "present", "online" etc for SMP and UP case */
set_cpu_online(cpu, true);
set_cpu_active(cpu, true);
set_cpu_present(cpu, true);
set_cpu_possible(cpu, true);
}
先获取cpu的id,在smp下,获取第一个处理器ip,非smp,第一个cpu的id为0。后面就是设置cpu的四个标志位。
page_address_init()
这个是页地址初始化操作。
我们先要了解下段式管理和页式管理。我们会有三个地址,逻辑地址,虚拟地址,物理地址。CPU要将一个逻辑地址转换为物理地址,需要两步:首先CPU利用段式内存管理单元,先将逻辑地址转换为线性地址(虚拟地址)。再利用页式管理单元,把虚拟地址,转化为物理地址。
形象理解,段式管理就是一个大大的内存按照目的分为几段,有的段比较大,有的段比较小。但是呢,每个段的最低地址位都是0,实际的地址位是段的偏移量。所以,这里就存在逻辑地址和虚拟地址的转换了。为什么要进行分段管理呢?进行分段管理,能使得我们有可能对不同的内存段赋予不同的权限管理。
页式管理是一段内存,按照指定大小划分,每4k为一页。这里就有一个虚拟地址和物理地址的映射关系了。比如在一个三级的页式管理中,一个虚拟地址32位按照10,10,12分为3段,前10位是页目录地址,后10位是页表地址,最后12位是偏移量地址。这里其实有个奇怪的地方了。
为什么要进行页式管理呢?不管是否有分页管理,一个32位的地址,最多指向的也就是4G内存空间。页式管理其实是为了更好地利用内存。比如假设内存是连续分配的,进程A获取了1~100的内存空间,进程B获取了100~104的内存空间,进程C获取了104~200的内存空间。现在进程B释放空间了,但是只有很小的4。这个时候,如果后续的进程要申请的空间都是大于4的,那么100~104这个内存空间段就永远没有办法被分配。而使用页式管理就有办法避免这个问题。它可以让程序使用的内存在逻辑上是连续的,在物理上是离散的。
回到linux中,由于仅有一部分体系支持段式管理,基于兼容的原因吧,linux并没有支持段式管理。换句话说,linux把内存块当作是一个段。所以实际上,在linux中,逻辑地址和虚拟地址是一样的。但是linux把页式管理是全盘接受了。
回到这个函数,page_address_init()
查找这个函数的定义,你可以看到根据宏不同有两种定义,一种是
#if !defined(HASHED_PAGE_VIRTUAL) && !defined(WANT_PAGE_VIRTUAL)
#define page_address(page) lowmem_page_address(page)
#define set_page_address(page, address) do { } while(0)
#define page_address_init() do { } while(0)
#endif
一种是
void __init page_address_init(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(page_address_htable); i++) {
INIT_LIST_HEAD(&page_address_htable[i].lh);
spin_lock_init(&page_address_htable[i].lock);
}
}
#endif /* defined(CONFIG_HIGHMEM) && !defined(WANT_PAGE_VIRTUAL) */
首先,这里分配的页地址空间指的是内核的页地址空间。linux把4G的虚拟地址空间分为3G用户地址空间+1G内核地址空间。基本上是使用物理地址+3G的方式进行直接映射的。所以一般初始化内核地址空间的时候并不需要做任何操作。但是,当有些系统自身需要的内存大于896M的时候,就出现问题了。首先1G的内核空间,linux内核会把它分为896M的操作系统使用的空间,和128M的IO映射空间。当有些操作系统自身需要的内存大于896M,那么就难免有一些操作系统空间需要使用虚拟地址的形式,实际上是占用了原本用户的系统空间,这一部分空间就叫做high memory。(那么想对,原本已经有的896M的空间叫做low memory)。这一部分的空间映射,是保存在128M的IO映射空间里面的。http://blog.sina.com.cn/s/blog_6488248f0100wu6v.html
linux源码分析(五)-start_kernel的更多相关文章
- linux源码分析2
linux源码分析 这里使用的linux版本是4.8,x86体系. 这篇是 http://home.ustc.edu.cn/~boj/courses/linux_kernel/1_boot.html ...
- Vue系列---理解Vue.nextTick使用及源码分析(五)
_ 阅读目录 一. 什么是Vue.nextTick()? 二. Vue.nextTick()方法的应用场景有哪些? 2.1 更改数据后,进行节点DOM操作. 2.2 在created生命周期中进行DO ...
- ABP源码分析五:ABP初始化全过程
ABP在初始化阶段做了哪些操作,前面的四篇文章大致描述了一下. 为个更清楚的描述其脉络,做了张流程图以辅助说明.其中每一步都涉及很多细节,难以在一张图中全部表现出来.每一步的细节(会涉及到较多接口,类 ...
- MPTCP 源码分析(五) 接收端窗口值
简述: 在TCP协议中影响数据发送的三个因素分别为:发送端窗口值.接收端窗口值和拥塞窗口值. 本文主要分析MPTCP中各个子路径对接收端窗口值rcv_wnd的处理. 接收端窗口值的初始化 ...
- vuex 源码分析(五) action 详解
action类似于mutation,不同的是Action提交的是mutation,而不是直接变更状态,而且action里可以包含任意异步操作,每个mutation的参数1是一个对象,可以包含如下六个属 ...
- jQuery 源码分析(五) map函数 $.map和$.fn.map函数 详解
$.map() 函数用于使用指定函数处理数组中的每个元素(或对象的每个属性),并将处理结果封装为新的数组返回,该函数有三个参数,如下: elems Array/Object类型 指定的需要处理的数组或 ...
- Vue.js 源码分析(五) 基础篇 方法 methods属性详解
methods中定义了Vue实例的方法,官网是这样介绍的: 例如:: <!DOCTYPE html> <html lang="en"> <head&g ...
- motan源码分析五:cluster相关
上一章我们分析了客户端调用服务端相关的源码,但是到了cluster里面的部分我们就没有分析了,本章将深入分析cluster和它的相关支持类. 1.clustersupport的创建过程,上一章的Ref ...
- java动态代理——代理方法的假设和验证及Proxy源码分析五
前文地址 https://www.cnblogs.com/tera/p/13419025.html 本系列文章主要是博主在学习spring aop的过程中了解到其使用了java动态代理,本着究根问底的 ...
- Linux源码分析之:malloc、free
之前写代码的时候一直有个疑问,malloc申请内存的时候指定了内存大小,但是free的时候却只指定要释放的内存地址,那么free是如何知道它要释放的内存空间大小呢? 源码之前,了无秘密,下面就从源码来 ...
随机推荐
- myeclipse中导入js报如下错误Syntax error on token "Invalid Regular Expression Options", no accurate correc
今天在使用bootstrap的时候引入的js文件出现错误Syntax error on token "Invalid Regular Expression Options", no ...
- ABP理论学习之审计日志
返回总目录 本篇目录 介绍 配置 通过特性开启/关闭 注意 我项目中的例子 介绍 维基百科说: "审计跟踪(也叫审计日志)是与安全相关的按照时间顺序的记录,记录集或者记录源,它们提供了活动序 ...
- UI控件(UISegmentedControl)
@implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; NSArray* segmentArray = [[ ...
- CSS3魔法堂:CSS3滤镜及Canvas、SVG和IE滤镜替代方案详解
一.前言 IE特有的滤镜常常作为CSS3各种新特性的降级处理补充,而Adobe转向HTML5后与Chrome合作推出CSS3的Filter特性,因此当前仅Webkit内核的浏览器支持CSS3 F ...
- 女生的最爱,装饰品。WPF也有,Adorner。(上海晒衣服理念)
说到装饰,不由要说到女性. 去年过年回家给我妈买了周大福项链,很明显就感觉待遇就不一样了,即使这样,还是被一个阿姨说应该买更重点的.看来钱这种东西果然是多一点才好.虽然自己无所谓,但让家里人更开心也是 ...
- Go项目结构和模块导入
Go项目结构和模块导入 golang项目结构与其他语言类似,但是仍然有一些需要注意的地方. 项目结构 环境配置 go 命令依赖一个重要的环境变量:$GOPATH,它表示GO项目的路径,如下设置 exp ...
- Nodejs初阶之express
PS: 2014/09/24 更新<Express 4.X 启航指南>,欢迎阅读和评论:) 老规矩,开头部分都是些自娱自乐的随想,想到哪写到哪... 到今天俺已经在俺厂工作俩年零几天了 ...
- 《SQL必知必会》—— 读后总结
- fir.im Weekly - TouchBar 从入门到开发
自从 Macbook Pro 发布重大更新, TouchBar 一直是开发者的重点关注对象.除了NSTouchBar官方文档,速度快者如 @毫无存在感的Cee,分享了一篇 NSTouchBar 的入门 ...
- salesforce 零基础学习(四十三)运算取余
工作中遇到一个简单的小问题,判断两个数是否整除,如果不整除,获取相关的余数. 习惯java的我毫不犹豫的写下了代码 public Boolean isDivisibility(Integer divi ...