Linux内核学习简要笔记

这里记录 跟从 “奔跑吧Linux内核”视频学习的简要笔记,

2019/2/11

奔跑2.0.2 内存管理总览二

32位cpu的虚拟内存空间是4G,一般0~3G是用户空间,3~4G是内核空间。当然也可以把用户空间和内核空间设为2G:2G(为什么默认会设为3G:1G呢?)。

物理内存分为高端映射和线性映射。线性映射,把地址直接映射到3G开始虚拟内存空间,物理内存地址+偏移量=虚拟内存地址;高端映射(High Memory), 动态映射到1G空间。

Page的structure十分重要;Mem_map[]数组是用来存放每一个page struct数据,通过这个数据结构,可以方便地通过page找到页帧号(page frame number);除了page以外,还有一个主要的数据结构Zone用来管理内存,zone内存区域,对应到物理内存的高端映射是Zone High,对应到线性映射是Zone Normal。

用户空间的1G~3G是mmap段,0~1G是堆空间和数据段/代码段;

OS一般用PCB(Process Control Block)来描述进程相关的信息,在Linux中,使用task_struct来描述进程。mm_struct是其重要的成员变量,他又包含2个重要的成员变量mmap和pgd。

mmap指向vma的进程链表,进程地址空间采用vma来管理,内核采用链表和红黑树来管理进程的内存。

pgd是进程进程所在的页表,进程的一级页表在fork的时候创建,进程的二级页表在使用的时候才会动态创建;

从进程管理的角度讲述内存管理的概貌图。

 

2019/2/10

奔跑2.0.1 内存管理总览一

内存空间分为 用户空间 和 内核空间。

用户空间调用的内存管理函数,到了内核空间都是一一对应的,如malloc对应sys_brk,mmap对应sys_mmap等。

这些内存管理函数申请的地址空间都是在虚拟地址空间的,这一部分是由vma管理。在linux内核中,这样的区域被称之为虚拟内存区域(virtual memory areas),简称vma。一个vma就是一块连续的线性地址空间的抽象,它拥有自身的权限(可读,可写,可执行等等) ,每一个虚拟内存区域都由一个相关的struct vm_area_struct结构来描述。

vma返回的地址还是虚拟地址,用户进程是无法写入的,这个时候就需要“缺页中断”来和物理内存建立关系。

缺页中断会产生2中类型的内存,一是匿名页面(没有关联文件,如malloc),另外一种是page cache(有关联具体文件的内存,如视频播放器去观看一个视频文件,这时系统读取视频文件会产生缓存,这些缓存就是page cache类型的)。

然后通过“页面分配器”和伙伴系统来分配页面。如果物理内存十分充足,则页面分配器十分容易分配页面;但是如果内存十分紧张,则需要涉及到OOM/内存规整等其他技术。分配好页面后,下面来分配页表。

内存相关的硬件则对应MMU/TLB/Cache/物理内存。

页面分配是以页为单位,但是如果一些进程只需要几个byte的内存,就会造成浪费,linux引入slab来解决这个问题。slab是Linux操作系统的一种内存分配机制。其工作是针对一些经常分配并释放的对象,如进程描述符等,这些对象的大小一般比较小,如果直接采用伙伴系统来进行分配和释放,不仅会造成大量的内存碎片,而且处理速度也太慢。而slab分配器是基于对象进行管理的,相同类型的对象归为一类(如进程描述符就是一类),每当要申请这样一个对象,slab分配器就从一个slab列表中分配一个这样大小的单元出去,而当要释放时,将其重新保存在该列表中,而不是直接返回给伙伴系统,从而避免这些内碎片。slab分配器并不丢弃已分配的对象,而是释放并把它们保存在内存中。当以后又要请求新的对象时,就可以从内存直接获取而不用重复初始化。

如果内存不够,则需要启动页面回收机制。对于匿名页面,需要写入swap分区(swap out),需要的时候再次载入(swap in);对于page cache,脏数据则需要写入文件(write back)。

反向映射,是指找到哪些Virtual Address使用了这个页面,以方便页面回收的时候进行相关的操作。在Linux内存管理器中,页表保持对进程使用的内存物理页的追踪,它们将虚拟页映射到物理页。有些页可能不是长时间使用,它们应该被交换出去。但是在交换出去之前,我们首先要做的就是要更新使用该交换页的每1个进程的页表项。为了更新进程页表项,以往为了确定某个要回收的物理页面都被哪些页表项引用,必须要遍历所有进程,这是1项非常耗资源和时间的工程。所以引入反向映射(RMAP)机制,使得更加有效地回收1个共享页面,反向映射技术的实现主要是基于页表项链表。

KSM是合并内容相同的匿名页面。2.6.32引入了KSM(Kernel Samepage Merging)允许这个系统管理程序通过合并内存页面来增加并发虚拟机的数量。VMware 的 ESX 服务器系统管理程序将这个特性命名为 Transparent Page Sharing (TPS),而 XEN 将其称为 MemoryCoW。不管采用哪种名称和实现,这个特性都提供了更好的内存利用率,从而允许操作系统(KVM 的系统管理程序)过量使用内存,支持更多的应用程序或 VM。

Huge Page主要用于服务器,手机系统则很少使用。huge page分配2M或以上的大小页面(一般的page大小是4k)。好处是减少TLB miss的次数。

页迁移,可以迁移一个进程的内存到指定的节点。在很多的内核模块都有使用,如内存规整和内存热插拔,都有用到页迁移。

内存规整是为了解决内存碎片化。

OOM killer,内存不足的时候,必要的时候会起到OOM Killer,杀掉某些进程。

2019/2/9

奔跑2.0.0 内存管理硬件知识

早期内存使用直接是访问物理地址,这会造成一下问题,

1. 一个程序的内存空间,容易被其他程序篡改;甚至内核的内存空间也可能被恶意程序篡改;

2. 内存的使用效率不高。

因此,后面也就有了“内存分段”的概念,来解决问题1;“内存分页”则用来引入“虚拟内存”的概念,来解决问题2.

“虚拟内存”和“物理内存”是相互映射的,通过硬件MMU来管理。

下面举例来说明,

比如,CPU要访问某一个数据,会先通过MMU来看看是否可以在“一级缓存”中存在,如果“一级缓存”没有,则看看“二级缓存”;

如果缓存中没有要访问的数据(TLB没有命中),则访问实际的“物理内存”;

如果此时数据因为一些原因被放到“交换分区swap”,则需要访问磁盘。

 

2019/2/8

序言2.3 搭建Eclipse图形化调试内核

这部分是在“序言2.2 搭建Qemu加gdb单步调试内核”基础之上,加入了Eclipse可视化,这样调试内核代码就像调试应用程序一样方便,可以查看栈的信息,以及各种数据结构。

大致方法如下,

1. 安装 "sudo apt-get install eclipse-cdt", 这个是eclipse c/c++的环境;

2. 新建一个项目,并且配置,这个可以参考 笨叔叔 的视频,要点如下,

2.1 点选 run->Debug Configurations.., 选择C/C++ Attach to Application, 选中“New_configuration”

2.1.1 "Name"可以输入自己喜欢的,如“linux”,

2.1.2 "Main"选项中,“Project”输入自己喜欢的,如“linux-4.0”, 然后通过“Browse”选择之前编译好的"vmlinux"文件。

2.1.3 "Debugger"页面中,“Debugger”选中“gdbserver”; "Main"页面下, 在“gdb debugger”中,输入“arm-none-eabi-gdb”;“Connection”页面下,“port number”更改为“1234”.

然后选择“Apply”-》“Debug”, 至此配置完成。

3. 新开一个terminal,输入“qemu-system-arm -M vexpress-a9 -smp 4 -m 1024M -kernel arch/arm/boot/zImage -append "rdinit=/linuxrc console=ttyAMA0 loglevel=8" -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -S -s”

4. 然后在Eclipse中,在debug中选择刚刚配置的linux选项

4.1 然后在“console”中,输入“file vmlinux”

4.2 设置断点“b do_fork”

4.3 输入“c”继续调试

然后就可以看到局部变量等信息。

 

2019/2/7

序言2.2 搭建Qemu加gdb单步调试内核

1. Install the package
sudo apt-get install qemu libncurses5-dev gcc-arm-linux-gnueabi build-essential gdb-arm-none-eabi gcc-aarch64-linux-gnu eclipse-cdt git
2.
https://github.com/figozhang/runninglinuxkernel_4.0.git3. Follow below step, to build kernel image and running it in the qemu, 

本实验是在Ubuntu 16.04上完成的,使用其他版本的Linux发行版遇到编译问题请自行解决了。

 

$ sudo apt-get install qemu libncurses5-dev gcc-arm-linux-gnueabi build-essential gdb-arm-none-eabi gcc-aarch64-linux-gnu eclipse-cdt libdw-dev systemtap systemtap-runtime

编译ARM32内核:

$ export ARCH=arm

$ export CROSS_COMPILE=arm-linux-gnueabi-

$ cd _install_arm32/dev/

$ sudo mknod console c 5 1 (注意,不要遗漏该步骤)

$ cd runninglinuxkernel_4.0

$ make vexpress_defconfig (在runninglinuxkernel_4.0目录下输入make命令)

$ make bzImage –j4

$ make dtbs

运行ARM32内核:

$ qemu-system-arm -M vexpress-a9 -smp 4 -m 1024M -kernel arch/arm/boot/zImage -append "rdinit=/linuxrc console=ttyAMA0 loglevel=8" -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic

4. gdb debu

4.1 running below command in one terminal,

$ qemu-system-arm -M vexpress-a9 -smp 4 -m 1024M -kernel arch/arm/boot/zImage -append "rdinit=/linuxrc console=ttyAMA0 loglevel=8" -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -S -s

4.2 running below command in another terminal, input 'c' to continue, input

$arm-none-eabi-gdb --tui vmlinux

4.3 Connect with qemu with gdb, input command 'target remote localhost:1234'

4.4 Set break points, for example 'b do_fork'

4.5 type 'c' to coninue

4.6 type 's' to debug step by step

 

2019/2/5

git入门与实战8:实战rebase到最新的代码

git入门与实战10:如何制作和管理多个patch

 

 

2019/2/2

git入门与实战5:提交更改

1. 修改最近一次提交,首先修改文件,然后使用git add,之后使用git commit --amend

2. 修改最近一个提交的作者,git commit -amend -author "xx@xx.com"

3. git reset,

3.1 --soft, 将HEAD引用指向给定的提交,索引和工作目录的内容保持不变;

3.2 --mixed,将HEAD引用指向给定的提交,索引跟着变,工作目录保持不变;

3.3 --hard, 将HEAD引用指向给定的提交,同时索引和工作目录都会改变

4. git revert, 撤销某个提交,如git revert master~3

5. git cherry-pick, 从某个git tree或者分支上摘取一个commit到当前分支, 如git cherry-pick dev~3

 

git入门与实战6:远程仓库

1. git remote命令

1.1 git remote命令可以添加一个远程仓库本地中

# git remote add ben 远程仓库地址

1.2 git remote show xxx,可以查看这个xx远程版本库的所有信息

1.3 git remote update 抓取远程版本库中所有可用更新到本地库里

1.4 git fetch xx, 抓取远程xx版本库到本地

2. 添加远程分支

# git push <远程主机名> <本地分支名>:<远程分支名>

3. 删除远程分支名

# git push <远程主机名> :<远程分支名>

# git push <远程主机名> -d <远程分支名>

 

git入门与实战7:实战git和内核开发与管理

用到的命令

git --bare init

git clone

git commit

git remote add [注意:一个本地库里面,可以包含多个远程库]

git remote -v

git fetch

git reset

git merge 

git push

 

git入门与实战9:如何给Linux内核社区发补丁

三部曲,

1. 发现缺陷, 

2. 制作补丁,$ git format-patch -1

3. 发布补丁

3.1 安装git-email, $ sudo apt-get install git-email

3.2 配置send-email, 修改~/.gitconfig文件

3.3 获取维护者的名字

$ ./scrpts/git_maintainer.pl your_fix.patch

3.4 发送补丁

$ git send-email --to "xx@xx.com" 0001-your-fix-patch.patch

 

2019/2/1

git入门三:分支管理

1. 创建分支

$ git branch 分支名

$ git branch ben/dev (斜杠创建一个分层的命名)

2. 查看分支

$ git branch -a

$ git show-branch -a

3. 切换分支

$ git checkout 分支名

$ git checkout -b 分支名 (创建新分支并切换到新分支上)

4. 删除分支

$ git branch -D 分支名(删除新分支)

5. 合并分支

$ git merge xxx: 将xxx分支合并到当前分支,所有提交按照顺序

$ git rebase xxx: 新的提交基于在xxx分支之上

 

git入门实战4:冲突解决

1. 使用git merge命令进行合并分支,把dev分支合并到master上

1.1 git merge dev

1.2 查看冲突,vim test.c,手工修改冲突

1.3 添加修改文件,git add test.c

1.4 使用git merge --continue继续下一个冲突的地方

2. 使用git rebase命令进行合并分支,把dev分支合并到master

2.1 git rebase dev

2.2 查看冲突,vim test.c,然后手工修改冲突

2.3 添加修改文件, git add test.c

2.4 使用git rebase --continue继续下一个冲突的地方

3. 从dev分支最新commit生成一个patch发给master分支,并在master分支上打上这个patch

3.1 git am xxx.patch发生冲突的时候

3.2 $ git am --show-current-patch查看当前的patch

      $ git apply PATCH --reject

git add fixed_files

git am --resolved

 

2019/1/31

实战运维8:Linux内存管理参数调优(三)

这一节视频主要介绍了/sys/kernel/mm目录下面的参数调优

1. /sys/kernel/mm/hugepages

以前一个page大小是4kb,对于现在的系统而言太小了,会造成频繁的缺页中断,所以才有hugepages

2. 修改hugepages大小,需要编辑/etc/default/grub文件

3. /sys/kernel/mm/transparent_hugepage, 透明巨页(起到什么作用?)

4. ksm内存调优, pages_to_scan, sleep_milisecs, merge_across_nodes

5. OOM Killer

5.1 /proc/<pid>/oom_score_adj: -1000~100, -1000表示不会被oom killer选中。

5.2 /proc/<pid>/oom_adj: -17~15, 值越小越不会被oom killer选中。

 

git入门与实战2:快速入门

1. 查看git log

1.1 使用哈希ID值,绝对提交名

1.2 符号引用,HEAD指向当前分支最近的提交

1.3 相对提交,比如master表示master分支的head,master^表示master分支倒数第二个commit;master~12..master~10表示master分支倒数第11和第10个提交。

2. git diff

2.1 git diff, 显示尚未提交的改动

2.2 git diff --cached, 查看已经缓存的改动

2.3 git diff HEAD, 查看所有的改动

2.4 git diff --stat, 查看摘要

3. git status

分为3种,tracked, un-tracked, ignored

4. git add:添加文件或者文件夹

5. git rm:删除文件或者文件夹

6. git mv: 移动或者重新命名文件

7. git commit

   git commit --amend: 提交修改

(如果是要修改某个文件,则需要使用git add xxx.c,再使用git commit --amend)

 

2019/1/28

git入门一:基本用法

git的主要特点是分布式,开发成员可以选择把代码保存到本地或者server,也可以和team  member之间相互sync。

常用命令,

1. git log

    git log --oneline #比git log显示更加简洁,一行显示一个commit

    git log --author=Linus --oneline # 只显示author为Linus的commit

    git log --patch-with-stat # 显示更详细的提交内容,如详细的更改内容。

2. 提交一个commit

     a. 修改源代码

    b. git diff查看修改文件的差异

    c. git status查看哪些文件被修改了

    d. git add添加修改文件

    e. git commit提交修改到本地仓库

3. 本地建一个git repo

3.1 git服务器端

     a. git --bare init命令创建一个空的远程仓库

3.2 client端

    a. git init创建本地的仓库

    b. git add添加文件

    c. git commit生成一个新的提交

    d. git remote add命令来添加刚才远程仓库的地址

    e. git push origin master推送到远程仓库

 

2019/1/22

实战运维7:Linux内存管理参数调优(二)

下面的参数位于/proc/sys/vm

1. “cat min_free_kbytes”, min水位的值,大小和zone有关系,越大的话,会造成系统越早触及low水位;

2. “cat lowmem_reserve_ratio”, 为每个zone预留的内存,cat /proc/zoneinfo可以看到protection;先从DMA32先分配内存,然后从DMA;

3. “cat admin_reserve_kbyte”:为root用户预留的内存;

4. “cat user_reserve_kbytes”:为普通用户预留的内存;

5. “cat panic_on_oom”: 为1的时候,发生Out Of Memory时,系统会panic;一般设置为0;

6. “cat oom_dump_tasks”: dump被oom杀掉的task信息;

7. “cat oom_kill_allocating_task”: 设为0则表示oom会选取耗内存高的task杀掉;

8. “cat overcommit_memory”:是否允许内存过量分配;

9. “cat overcommit_kbytes”:overcommit_memory设为2才有用,和overcommit_ratio二选一;

10. “cat overcommit_ratio”

11. “cat block_dump”

12. "echo 1 > compact_memory": 让零散的内存整片化;

13. “cat laptop_mode”: 

14. "cat legacy_va_layout"

15. "cat max_map_count"

16. "cat mmap_min_addr":最小的虚拟地址

17. “cat page-cluster”:

18. "cat percpu_pagelist_fraction"

19. "cat stat_interval"

2019/1/21

实战运维4 - 读懂proc meminfo

1. “cat /proc/meminfo”, 这个节点十分普通,普通的不起眼,但是仔细看下去,里面很多细项都有很多知识点。以后要好好详细研究。特别提一下,内存分配的函数malloc(), kmalloc(), vmalloc(), 这3个函数有哪些差异?

2. “cat /proc/zoneinfo”,内存分配有node,node下面有zone,zone下面有page。

3. “cat /proc/pagetypeinfo”,里面含有page相关的内存信息。page block, 2的9次方大小,每个block有512pages。

4. "cat /proc/slabinfo",读取slab相关的信息,但是没有slabtop方便看。

5. "cat /proc/iomem", 查看以memory map为映射的方式,如ARM,会占用内存空间。

6. "cat /proc/ioport",查看以io map为映射的方式,如x86架构。

 

实战运维5 - Linux运维能力进阶图

Linux运维可以划分不同能力等级,

1. 入门级别,可以安装系统,部署服务,会使用简单的工具;

2. 初级的,可以读懂kernel log,使用top/vmstat等工具,读懂meminfo等常用的内核信息,会调节内核参数;

3. 中级,可以熟练使用debug工具,rkdump,systemtap,内存泄漏查找;读懂内核出错信息,了解内存管理/进程管理等。

4. 高级,就像Linuis本人类似的能力,读懂大部分内核代码,知道内核有哪些不足并能够提供方案。

 

实战运维6 - Linux内存管理参数调优(一)

1. "/proc/sys/vm"

page cache是什么?磁盘和CPU速度严重不匹配,怎么办呢?方法有,比如在磁盘端增加cache,还有在内存中增加page, cache,cpu端L1/L2/L3 cache。文件会先存放在page cache中,之后再sync到磁盘;何时sync则会影响到系统性能。

常用参数,

dirty_background

dirty_radio:脏数据超过这个比率时,就会flush。

dirty_backgournd_ratio: 和dirty_radio相比,类似,但是write不会被阻塞(异步)。

dirty_bytes: 超过dirty_bytes size后,则flush;和diryt_radio二选一;

dirty_expire_centisecs: 超过多次时间则被回写。

dirty_writeback_centisecs:多次时间被唤醒查看是否需要flush(单位10ms)

drop_cache: 更改减小page cache大小。不会drop脏的page,如果脏数据比较多,可以先使用sync命令。

vfs_cache_pressure: 回收inode和文件系统的cache。

swappiness:值越高,越倾向写入swap磁盘;如果设为0,则是尽量使用page cache。

2. "/sys/kernel/mm"

 

2019/1/20

实战运维2 - 查看内存信息工具(二),

1. 工具"vmstat". proc,有r(运行状态)和b(阻塞状态)的进程数目;memory,有swapd(交换分区),free,buff,cache;还有swap,io,system,cpu。可以查看哪个模块出了问题。

2. “cat /proc/slabinfo”工具,不过需要了解比较专业slab的知识;

3. “slabtop”工具, 比较容易了解slab的相关信息。

4. “pmap”工具,查看具体一个process的内存状态,anon匿名页面,查看分配了多少内存。

 

实战运维3 - 读懂内核log中的内存管理信息,

1. "dmesg", 打印kernel log。参数如-T,-d,等。

2. proc和sys文件系统。/proc/meminfo, /proc/cpuinfo可以查看内存和cpu相关的信息;sys系统则是为设备模型所引入。

 

2019/1/18

实战运维1 - 查看内存信息工具(一),

1. 从可视化工具“System Monitor”来查看内存状态。分为Memory和Swap(交换分区),可以查看已经使用和总的内存空间。

2. 使用"free" 命令。可以查看Memory和Swap的如下项目,如total, used, free, shared, buff/cache, avaiable. 别看他简单,特别有用哦。

3. "top"命令。可以查看cpu和内存使用状况,需要好好研究。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值