zoukankan      html  css  js  c++  java
  • 2013337朱荟潼 Linux第二章读书笔记——从内核出发

    1.获取内核源码

    1.1Git

    分布式的;下载和管理Linux内核源代码;

    - 获取最新提交到版本树的一个副本
     $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
    - 下载代码后,更新自己的分支到最新分支
     $ git pull
    

    1.2安装内核源代码

    - 压缩形式为bzip2
     运行:$ tar xvjf linux-x.y.z.tar.bz2
    - 压缩形式为zip
     运行:$ tar xvzf linux-x.y.z.tar.gz
    
    - 注释(xvjf、xvzf):
    	-x 解开;
    	-v 显示详细信息;
    	-j 使用bzip2程序;
    	-z 使用gzip程序;
    	-f 使用归档文件;
    

    1.3使用补丁

    - 从内部源码树开始
    	运行$ patch -p1 < ../patch-x,y,z
    

    2.内核源码树

    (详见书《Linux内核设计与实现》原书第3版 第11—12页表2-1内核源码树的根目录描述)

    COPYIN:内核许可证;
    CREDITS:内核代码的开发者列表;
    MAINTAINTERS:维护者列表——负责维护内核子系统和驱动程序;
    Makefile:是基本内核的Makefile;
    

    3.编译内核

    3.1配置内核(关于make与config)

    - 配置选项(指定内核源码可以访问的值,一般以预处理宏的形式表示)
    	1.决定哪些文件编译进内核;通过预处理命令处理代码。
    	2.二选一:yes/no
    	3.三选一:yes(把代码编译进主内核映像中)/no/module(该配置项被选定了)【驱动程序一般是三选一】
    	4.可以是字符串或整数
    
    - 配置工具:
    	$ make config 配置命令解释器,最简单的一个字符界面下的命令行工具;
    	$ make menuconfig 配置用户界面,基于ncurse库的图形界面工具;
    	$ make gconfig 基于gtk+的图形工具;
    	$ make defconfig 基于默认的配置为个人的体系结构创建一个配置;
    	$ make oldconfig 验证和更新配置;
    - .config文件:配置项会被存放在内核代码树根目录下。
    

    	$ zcat /proc/config.gz > .config 目前的内核已经启用了CONFIG_IKCONFIG_PROC选项,可以从/proc下复制文件;
    	$ make oldconfig 便以一个新内核;
    	$ make 编译该配置好的内核;
    

    3.2减少编译的垃圾信息

    	- 不看错误报告和警告信息,对输出重定向
    		$ make > ../detritus
    	- 把无用的输出信息重定向到永无返回值的黑洞/dev/null中
    		$ make > /dev/null
    

    3.3衍生多个编译作业

    - 以多个作业编译内核
    	$ make -jn (j:指定同时执行多任务;n:要衍生出的作业数)
    - 16核处理器
        $ make -j32 > /dev/null
    

    3.4安装新内核

    - 以root身份,运行,把所有已编译的模块安装到正确的主目录/lib/modules下。
    	% make modules_install
    - System.map文件:编译时在内核代码树的根目录下创建的文件;是一个符号对照表;用来将内核符号与它们的起始地址对应起来;调试时,把内存地址转化为函数名和变量名,很有用。
    

    4.内核开发的特点

    4.1无libc库抑或标准头文件

    主要原因:速度与大小。
    

    4.1.1头文件

    - 基本头文件位于内核源代码顶级目录下的include中。
    -体系结构相关头文件:内核源代码树的arch/<architecture>/include/asm目录下
    

    4.2GNU C

    GCC是多种GNU编译器的集合。

    4.2.1内联函数

    - 定义一个内联函数,用static作关键字,用inline限定它。
    	static inline void wolf(unsigned long tail_size);
    

    4.2.2内联汇编

    - 用asm()指令嵌入汇编代码
    	unsigned int low, high;
    	asm volatile("rdtsc" : "=a" (low), "=d" (high)); //low 和 high 分别包含64位时间戳的低32位和高32位 
    

    4.2.3分支声明

    - /* error在绝大多数情况下为0 */
    	if (unlikely(error)) {
    		/* ... */
    	}
    
    - /* success在通常不为0 */
    	if (likely(success)) {
    		 /* ... */
    	}
    
    - 如果判断正确,性能会提升;如果搞错,性能反而下降。
    

    4.3没有内存保护机制

    在内核中,不该访问非法的内存地址,引用空指针,否则内核会over;
    内核中的内存不分页:每用掉一个字节,物理内存都减少一个;
    

    4.4不用轻易在内核中使用浮点数

    与用户空间进程不同,内核不完美支持浮点操作,因为他本身不能陷入;
    

    4.5容积小而固定的栈

    用户空间的栈本身比较大,而且可以动态增长;
    对于不用的体系结构,内核栈的大小不一样并都是固定的;
    

    4.6同步和并发

    - 内核易产生竞争条件,许多特性都要求能过并发地访问共享数据,就要求同步机制以保证不出现竞争条件,特别是:
    •	Linux是抢占多任务操作系统
    •	Linux内核支持对称多处理器系统(SMP)
    •	中断异步到来
    •	Linux内核可以抢占
    - 常用解决方法:自旋锁和信号量
    

    4.7可移植性的重要性

    Linux是可移植的操作系统。
    

    5.小结

    内核有独一无二的特质,拥有整个系统的最高管理权。
  • 相关阅读:
    CodeForces 404C Ivan and Powers of Two
    CodeForces 433C Ryouko's Memory Note-暴力
    if not
    python3的print函数
    交叉熵
    tensorflow一个很好的博客
    关于第几维的问题
    更新软件
    tensorflow训练代码
    tensorflow的一些函数
  • 原文地址:https://www.cnblogs.com/zzzz5/p/5271985.html
Copyright © 2011-2022 走看看