-
马哥Linux学习笔记13-4Linux内核管理初步
2019-03-03 23:24:34Linux kernel 单内核体系设计、但充分借鉴了微内核设计体系的优点,为内核引入模块化机制。 内核组成部分: kernel:内核核心,一般为bzImage,通常在/boot目录下,名称为vmlinuz-VERSION-RELEASE kernel object:...-
Linux kernel
单内核体系设计、但充分借鉴了微内核设计体系的优点,为内核引入模块化机制。
内核组成部分:
kernel:内核核心,一般为bzImage,通常在/boot目录下,名称为vmlinuz-VERSION-RELEASE
kernel object:内核对象,一般放置于/lib/modules/VERSION-RELEASE/
[ ]:N
[M]:M
[*]:Y
辅助文件:ramdisk
initrd
initramfs -
运行中的内核:
uname命令:uname - print system information
uname [OPTION]…
-n:显示节点名称
-r:显示VERSION-RELEASE -
模块:
-
lsmod命令:显示由核心已经装载的内核模块,显示的内容来自于:/proc/modules文件
-
modinfo命令;显示模块的详细描述信息
moinfo [ -k kernel ] [ modulename|fielname… ]
-n 只显示模块文件
-p 显示模块参数
-a author
-d description
-l license -
modprobe命令:
装载或卸载内核模块
modprobe [ -C config-file ] [ modulename ] [ module parame-ters… ]
配置文件:/etc/modprobe.conf,/etc/modprobe.d/*.conf
modprobe [ -r ] modulename… -
depmod命令:内核模块依赖关系文件及系统信息映射文件的生成工具
-
装载或卸载内核模块
insmod命令:insmod [ filename ] [ module options… ]
rmmod rmmod [ modulename ] -
proc目录:
内核把自己内部状态信息及统计信息,以及可配置参数通过proc伪文件系统加以输出
参数:
只读:输出信息
可写:可接受用户指定新值来实现对内核某功能或特性的配置/proc/sys
1sysctl命令用于查看或设定此目录中诸多参数
sysctl -w path.to.parameter=VALUE
sysctl -w kernel.hostname=mail.magedu.com
2echo命令通过重定向的方式也可以修改大多数参数的值
echo “www.magedu.com” > /proc/sys/kernel/hostname -
sysctl命令:
配置文件:/etc/sysctl.conf
1设置某参数:sysctl -w parameter=VALUE
2通过读取配置文件设置参数
sysctl -p [/path/to/conf_file]
内核中的路由转发:/proc/sys/net/ipv4/ip_forward
常用的几个参数:
net.ipv4.ip_forward
vm.drop_caches
kernel.hostname -
/sys目录
sysfs:输出内核识别出的各硬件设备的相关属性信息,也有内核对硬件特性的设定信息,有些参数是可以修改的,用于调整硬件工作特性
udev通过此路径下的输出的信息动态为各设备创建所需要设备文件,udev是运行用户空间程序,专用工具:udevadmn,hotplug
udev为设备创建设备文件时,会读取其事先定义好的规则文件,一般在/etc/udev/rules.d及/usr/lib/udev/rules.d目录下 -
ramdisk文件的制作:
1mkinitrd命令
为当前正在使用的内核重新制作ramdisk文件
mkinitrd /boot/initramfs-$(uname -r).img $(uname -r)
2dracut命令:
为当前正在使用的内核重新制作ramdisk文件
dracut /boot/initramfs-¥(uname -r).img $(uname -r) -
编译内核:
前提:1准备好开发环境
2获取目标主机上硬件设备的相关信息
3获取目标主机系统功能的相关信息,例如要启用的文件系统
4获取内核
准备好开发环境:
包组(centos 6):
server platform development
development tools
目标主机硬件设备相关信息:
CPU:cat /proc/cpuinfo
x86info -a
lscpu
PCI设备:
lspci
-v
-vv
或lsusb
-v
-vv
或lsblk
了解全部硬件设备信息
hal-device
简单依据模板文件的制作过程:
tar xf linux-3.10.67.tar.xz -C /usr/src
cd /usr/src
Ln -sv Linux-3.10.67 Linux
cd Linux
cp /boot/config-$(uname -r) ./.config
make menuconfig
screen
make -j #
make modules_install
make install
重启系统,并测试使用新内核
-
-
linux内核学习(好东西)
2012-10-15 14:02:23linux内核学习(好东西) 2012-05-11 21:12:13| 分类: linux学习博客|字号 订阅 1. 内核学习方法,编译、调试等常见问题 1.1 关于编译升级内核到2.6.0的一些问题 作转自:http://blog.csdn.net/michaelrun/archive/2010/05/30/5634390.aspx
linux内核学习(好东西)
1. 内核学习方法,编译、调试等常见问题
1.1 关于编译升级内核到2.6.0的一些问题 作者:ommm
http://linux.chinaunix.net/bbs/thread-281831-1-5.html
1.2 VMWare Workstation 6.0调试Linux Kernel,竟如此方便 作者:albcamus
http://linux.chinaunix.net/bbs/thread-896214-1-5.html
1.3 基于S3C2410的Linux全线移植文档 作者:dozec
http://linux.chinaunix.net/bbs/thread-798304-1-6.html
1.4 【原创】《Linker Script in Linux》 作者: zx_wing
http://linux.chinaunix.net/bbs/viewthread.php?tid=1032711
1.5 月经结贴 -- 《Segmentation Fault in Linux》 作者: zx_wing
http://linux.chinaunix.net/bbs/thread-1149936-1-19.html
1.6 【译】linux-2.6.31内核文档系列 作者:openspace
http://linux.chinaunix.net/bbs/thread-1149917-1-23.html
1.7 Solaris、Linux和FreeBSD的内核比较 作者:compnik
http://linux.chinaunix.net/bbs/thread-783940-1-24.html
1.8 定位Oops的具体代码行 作者:albcamus
http://linux.chinaunix.net/bbs/thread-1008573-1-25.html
1.9 调试KERNEL时,找出当前进程信息的方法 作者:accessory
http://linux.chinaunix.net/bbs/thread-1147973-1-36.html
1.10 Linux内核配置文档!!!(make menuconfig) 作者:HopeCao
http://linux.chinaunix.net/bbs/thread-16106-1-58.html
1.11 Git 中文教程 作者:swanrobin
http://linux.chinaunix.net/bbs/thread-724949-1-79.html
1.12 怎样为Linux内核打补丁 作者:jeffshia
http://linux.chinaunix.net/bbs/thread-811431-1-87.html
1.13 2.6 内核中宏定义 #define DEFINE(sym, val)的问题 ? 作者:kimyoung
http://linux.chinaunix.net/bbs/thread-702373-1-94.html
1.14 Linux内核中的红黑树 作者:Godbach
http://linux.chinaunix.net/bbs/thread-1055772-1-94.html
1.15 Linux内核解读入门 作者:小皮
http://linux.chinaunix.net/bbs/thread-85340-1-99.html
1.16 Linux汇编语言开发指南(zt) 作者:mmgg00
http://linux.chinaunix.net/bbs/thread-508038-1-99.html
1.17 Netconsole实例源代码分析 作者:dreamice
http://linux.chinaunix.net/bbs/thread-1047519-1-105.html
1.20 使用git参与kernel开发 作者:albcamus
http://linux.chinaunix.net/bbs/thread-920610-1-109.html
1.21 http://lwn.net/Articles/2.6-kernel-api/的翻译 作者:co63
http://linux.chinaunix.net/bbs/thread-1040681-1-113.html
1.22 linux情景分析非扫描带书签版本 作者:onlyflyer
http://linux.chinaunix.net/bbs/thread-1016938-1-123.html
1.23 kallsyms的分析 作者:qtdszws
http://linux.chinaunix.net/bbs/thread-1013999-1-135.html
1.24 【求助】关于inb和inw的疑问 作者:njngypp
http://linux.chinaunix.net/bbs/thread-992279-1-147.html
1.25 绝对精品--linux 内核代码构架图 作者:achlice
http://linux.chinaunix.net/bbs/thread-983931-1-153.html
1.26 [转贴]用tags/cscope看内核源代码-HOWTO 作者:leviathan.alan
http://linux.chinaunix.net/bbs/thread-719390-1-153.html
1.27 linux-2.6内核升级文档(全) 作者:killua
http://linux.chinaunix.net/bbs/thread-484867-1-155.html
1.28 请教一个扩展汇编的问题 作者:flw2
http://linux.chinaunix.net/bbs/thread-901464-1-169.html
1.29 前段时间arch/i386/kernel/head.S注解 作者:alasijiabandao
http://linux.chinaunix.net/bbs/thread-909584-1-177.html
1.30 ud2是什么指令? 作者:netentsec
http://linux.chinaunix.net/bbs/thread-901519-1-191.html
1.31 使用GDB与QEMU调试内核时的问题分析 作者:mingyanguo
http://linux.chinaunix.net/bbs/thread-702878-1-200.html
1.32 什么是module 以及如何写一个module(转) 作者:我菜我怕谁
http://linux.chinaunix.net/bbs/thread-612522-1-207.html
1.33 用netconsole从网络上收集Kernel Panic信息详细方法 作者:Jobs.AE@
http://linux.chinaunix.net/bbs/thread-811116-1-225.html
1.34 升级2.6内核的经验与心得 作者:vikingpro
http://linux.chinaunix.net/bbs/thread-251091-1-260.html2. 进程管理与进程间通信、模块间通信等
2.1 内核通知链 学习笔记 作者:scutan
http://linux.chinaunix.net/bbs/thread-1051266-1-2.html
2.2 使用netlink通讯时需要注意的一些问题 作者:duanjigang
http://linux.chinaunix.net/bbs/thread-1144547-1-9.html
2.3 工作队列分析 作者: rwen2012
http://linux.chinaunix.net/bbs/thread-882951-1-15.html
2.4 [原创]QEMU小实验:手工遍历所有进程的方法 作者:accessory
http://linux.chinaunix.net/bbs/thread-1155784-1-16.html
2.5 用户空间内核空间ipc总结(sockopt,ioctl,mmap,netlink,proc,seq,file,copy_user) 作者:ubuntuer
http://linux.chinaunix.net/bbs/thread-1154038-1-23.html
2.6 netlink socket 编程之 why & how 作者:duanjigang
http://linux.chinaunix.net/bbs/thread-1031932-1-39.html
2.7 linux2.6.29 swtich_to 详细分析(一) 作者:liujunwei1234
http://linux.chinaunix.net/bbs/thread-1099177-1-57.html
2.8 Linux 用户态与内核态的交互——netlink 篇 作者:独孤九贱
http://linux.chinaunix.net/bbs/thread-822500-1-60.html
2.9 基于NETLINK的内核与用户空间共享内存的实现 作者:bripengandre
http://linux.chinaunix.net/bbs/thread-1113929-1-63.html
2.10 内核源码kfifo分析(原创) 作者:springtty
http://linux.chinaunix.net/bbs/thread-1089313-1-74.html
2.11 Unreliable Guide to Locking -by Rusty Russell-中文版 作者:albcamus
http://linux.chinaunix.net/bbs/thread-656347-1-79.html
2.12 完全公平调度(CFS) 作者:wxc200
http://linux.chinaunix.net/bbs/thread-1063798-1-90.html
2.13 Linux 2.4 内核说明文档(进程与中断管理篇) 作者:xuediao
http://linux.chinaunix.net/bbs/thread-571760-1-127.html
2.14 写了一个内核模块 实现简单的类似ps命令. 作者:mq110
http://linux.chinaunix.net/bbs/thread-653764-1-130.html
2.15 PAE机制分析 作者:vestige
http://linux.chinaunix.net/bbs/thread-986982-1-149.html
2.16 Linux2.6内核进程创建过程分析 作者:scriptkidz
http://linux.chinaunix.net/bbs/thread-912485-1-172.html
2.17 [转贴]用户态和内核共享内存--最简单的例子 作者:leviathan.alan
http://linux.chinaunix.net/bbs/thread-719393-1-183.html
2.18 Linux 调度的科普文章 作者:raise_sail
http://linux.chinaunix.net/bbs/thread-903481-1-186.html
2.19 linux 2.4内核之信号(一) 作者:yjfpb04
http://linux.chinaunix.net/bbs/thread-900690-1-191.html 本帖最后由 Godbach 于 2010-05-29 01:48 编辑3. 内存管理及地址相关
3.1 Linux内存管理大图(第三稿) 作者:Aryang
http://linux.chinaunix.net/bbs/thread-1043740-1-1.html
3.2 我理解的逻辑地址、线性地址、物理地址和虚拟地址(补充完整了) 作者:独孤九贱
http://linux.chinaunix.net/bbs/thread-919019-1-6.html
3.3 发个简单(易用)的内存池 作者:duanjigang
http://linux.chinaunix.net/bbs/thread-1153205-1-20.html
3.4 Linux内存:内存管理的实质 作者:frank_seng
http://linux.chinaunix.net/bbs/thread-1003872-1-21.html
3.5 查找X86_64下内核代码段物理地址的方法 作者:accessory
http://linux.chinaunix.net/bbs/thread-1151780-1-26.html
3.6 linux内存管理报告 作者:kendyke
http://linux.chinaunix.net/bbs/thread-1145231-1-35.html
3.7 [推荐] LKML上一篇关于barrier文档草案的讨论 作者:xiaozhaoz
http://linux.chinaunix.net/bbs/thread-713279-1-44.html
3.8 还是不理解IOMMU、北桥、PCI的MMIO和ioremap 作者:epegasus
http://linux.chinaunix.net/bbs/thread-985872-1-50.html
3.9 求助:将用户空间的虚拟地址映射到内核态的逻辑地址。 作者:onlyflyer
http://linux.chinaunix.net/bbs/thread-885038-1-80.html
3.10 VMALLOC_RESERVE 和 896M 作者:思一克
http://linux.chinaunix.net/bbs/thread-690010-1-80.html
3.11 对Linux堆内存释放的总结 作者:snow_insky
http://linux.chinaunix.net/bbs/thread-677609-1-82.html
3.12 请问完全内存虚拟化处理缺页异常的流程是什么? 作者:kikanjuu
http://linux.chinaunix.net/bbs/thread-978835-1-88.html
3.13 Linux 内核中Demand paging 与swap机制的源码分析 作者:crosskernel
http://linux.chinaunix.net/bbs/thread-1060602-1-93.html
3.14 Linux sys_exec中可执行文件映射的建立及读取 作者:frank_seng
http://linux.chinaunix.net/bbs/thread-1000474-1-116.html
3.15 请教大家一个mmap的问题 作者:blossom007cn
http://linux.chinaunix.net/bbs/thread-900802-1-191.html
3.16 映射的冲突 作者:qtdszws
http://linux.chinaunix.net/bbs/thread-901328-1-190.html
3.17 Linux Memory Management or 'Why is there no free RAM?' 作者:snow_insky
http://linux.chinaunix.net/bbs/thread-686942-1-209.html4. 中断相关
4.1 《Interrupt in Linux(硬件篇)》(1楼有更新 2008.5.3) 作者:zw_wing
http://linux.chinaunix.net/bbs/thread-996409-1-23.html
4.2 [保留] 关于LINUX在中断(硬软)中不能睡眠的真正原因 作者:思一克
http://linux.chinaunix.net/bbs/thread-902033-1-38.html
4.3 2.6.10的中断处理分析 作者:normalnotebook
http://linux.chinaunix.net/bbs/thread-685702-1-126.html
4.4 请问如果在中断上下文中调用可能引起阻塞的代码到底会怎么样? 作者:dengcainiao
http://linux.chinaunix.net/bbs/thread-802655-1-256.html5. 文件系统方面
5.1 内核模块中对文件的读写 作者:ubuntuer
http://linux.chinaunix.net/bbs/thread-1148680-1-7.html
5.2 一个简单文件系统的实现 作者:goter
http://linux.chinaunix.net/bbs/thread-1113528-1-23.html
5.3 最近看vfs部分,写了个笔记,大家看看.(37 ~ 39 楼更新了mount 文件系统部分) 作者:xpl
http://linux.chinaunix.net/bbs/thread-1005219-1-27.html
5.4 何把内核中的信息打印到文件 作者:xiaozhe2000
http://linux.chinaunix.net/bbs/thread-738197-1-112.html
5.5 2.4.18预读算法详解 作者:taoistf
http://linux.chinaunix.net/bbs/thread-1029156-1-122.html
5.6 [转] Dr.Wu 的博士论文: linux内核中的预取算法 作者:albcamus
http://linux.chinaunix.net/bbs/thread-1029420-1-122.html
5.7 UNIX传统文件系统s5fs的实现 作者:xzh2002
http://linux.chinaunix.net/bbs/thread-13214-1-171.html
5.8 nfs权限 作者:zhaixinshe
http://linux.chinaunix.net/bbs/thread-557038-1-174.html .6.网络协议栈方面
6.1 基于2.6.20版本的《Linux内核源码剖析--TCP/IP实现》【样章01 02 03 22 30】 作者:lmarsin
http://linux.chinaunix.net/bbs/thread-1157659-1-1.html
6.2 [出版]--基于2.6.26内核的《追踪LINUX TCP/IP代码运行》 作者:qinjiana0786
http://linux.chinaunix.net/bbs/thread-1064374-1-2.html
6.3 PF_RING实现分析 作者:独孤九贱
http://linux.chinaunix.net/bbs/thread-1149919-1-5.html
6.4 Netfilter 连接跟踪与状态检测的实现 作者:独孤九贱
http://linux.chinaunix.net/bbs/thread-815129-1-9.html
6.5 Netfilter之连接跟踪实现机制初步分析 作者:Minit
http://linux.chinaunix.net/bbs/thread-1057483-1-9.html
6.6 教你修改以及重构skb 作者:ubuntuer
http://linux.chinaunix.net/bbs/thread-1152885-1-10.html
6.7 共享RFC集合,linux网络源码伴侣 作者:lmarsin
http://linux.chinaunix.net/bbs/thread-1159286-1-11.html
6.8 关于ptype_all和pypte_base中的pt_prev的说明[转] 作者:Godbach
http://linux.chinaunix.net/bbs/thread-1160785-1-12.html
6.9 Linux内核IP Queue机制的分析(三)——ip_queue内核模块的分析 作者:Godbach
http://linux.chinaunix.net/bbs/thread-1152070-1-17.html
6.10 udp数据报从网卡驱动到用户空间流程总结 作者:peimichael
http://linux.chinaunix.net/bbs/thread-1133017-1-38.html
6.11 Linux内核发送构造数据包的方式 作者:Godbach
http://linux.chinaunix.net/bbs/thread-1133084-1-42.html
6.12 Netfilter CONNMARK用法及分析(二)-- 内核代码分析 作者:godbach
http://linux.chinaunix.net/bbs/thread-1142069-1-44.html
6.13 [保留] 2.6内核数据包接收流程分析 作者:瀚海书香
http://linux.chinaunix.net/bbs/thread-1132965-1-45.html
6.14 敬告:已完成--基于LINUX内核中的TCP/IP的核心过程分析 作者:qinjiana0786
http://linux.chinaunix.net/bbs/thread-1049757-1-64.html
6.15 Netfilter 地址转换的实现 作者:独孤九贱
http://linux.chinaunix.net/bbs/thread-886488-1-71.html
6.16 [原]Netfilter实现机制分析 作者:Minit
http://linux.chinaunix.net/bbs/thread-1054981-1-78.html
6.17 Linux内核IP Queue机制的分析(二)——用户态处理并回传数据包 作者:Godbach
http://linux.chinaunix.net/bbs/thread-1063004-1-82.html
6.18 网络子系统在链路层的收发过程剖析 作者:rwen2012
http://linux.chinaunix.net/bbs/thread-886985-1-87.html
6.19 Netfilter源码分析-我来抛砖,望能引玉 作者:独孤九贱
http://linux.chinaunix.net/bbs/thread-670248-1-87.html
6.20 Hacking the Linux Kernel Network Stack(译本) 作者: duanjigang
http://linux.chinaunix.net/bbs/thread-758787-1-91.html
6.21 skbuff解释 - [转贴自CLF,作者:wheelz] 作者:leviathan.alan
http://linux.chinaunix.net/bbs/thread-776678-1-124.html
6.22 如何让 linux 包转发达到 40万pps,尝试中! 作者:sbyond
http://linux.chinaunix.net/bbs/thread-641802-1-142.html
6.23 我自己分析内核tc的一点心得 作者:qtdszws
http://linux.chinaunix.net/bbs/thread-854814-1-145.html
6.24 网络代码学习第二部分:网络子系统在IP层的收发过程剖析 作者:rwen2012
http://linux.chinaunix.net/bbs/thread-888336-1-150.html
6.25 Netfliter状态跟踪之动态协议的实现浅析(tftp实现) 作者:独孤九贱
http://linux.chinaunix.net/bbs/thread-841944-1-160.html
6.26 内核netfilter处理问题(暨packet接受与NAPI介绍) 作者:guotie
http://linux.chinaunix.net/bbs/thread-684828-1-200.html7. CPU与多核方面
7.1 关于LINUX上中断在各个CPU之间的负载平衡问题 作者:思一克
http://linux.chinaunix.net/bbs/thread-902244-1-3.html
7.2 在多核系统上网络数据转发实验和一点思考 作者:独孤九贱
http://linux.chinaunix.net/bbs/thread-1112413-1-3.html
7.3 关于 atomic 的话题 作者:mik
http://linux.chinaunix.net/bbs/thread-1145097-1-40.html
7.4 关于AMD TLB bug 作者:crspo
http://linux.chinaunix.net/bbs/thread-984846-1-153.html8. 硬件相关与设备驱动
8.1 [原创] 写一个块设备驱动 作者:OstrichFly
http://linux.chinaunix.net/bbs/thread-1045283-1-2.html
8.2 LINUX下USB1.1设备学习小记(更新完毕) 作者:superfight
http://linux.chinaunix.net/bbs/thread-1067271-1-2.html
8.3 请教个网卡驱动的问题 作者:VIP_fuck
http://linux.chinaunix.net/bbs/thread-1158886-1-11.html
8.4 个人对kobject的一点研究 作者:superfight
http://linux.chinaunix.net/bbs/thread-1058833-1-12.html
8.5 RTL8139网卡驱动程序分析[转] 作者:Godbach
http://linux.chinaunix.net/bbs/thread-1095257-1-14.html
8.6 Linux那些事儿之我是USB Core——PDF下载 作者:ilttv.cn
http://linux.chinaunix.net/bbs/thread-913310-1-14.html
8.7 【原】Linux-千兆网卡驱动实现机制浅析 作者:Minit
http://linux.chinaunix.net/bbs/thread-1094725-1-17.html
8.8 利用udev在/dev下动态生成/移除设备文件 作者:albcamus
http://linux.chinaunix.net/bbs/thread-892777-1-18.html
8.9 ACPI in Linux - Myths vs. Reality 中文版 作者:albcamus
http://linux.chinaunix.net/bbs/thread-903433-1-24.html
8.10 Intel-E100网卡驱动实例分析 作者:lenn
http://linux.chinaunix.net/bbs/thread-690741-1-24.html
8.11 说一说:关于数据传送中 address bus 的工作原理 作者:mik
http://linux.chinaunix.net/bbs/thread-1145254-1-39.html
8.12 有谁对网卡DMA有所了解 作者:duanius
http://linux.chinaunix.net/bbs/thread-983479-1-49.html
8.13 [转] linux那些事儿之我是HUB - PDF文件 作者:albcamus
http://linux.chinaunix.net/bbs/thread-912798-1-57.html
8.14 网卡驱动注册到PCI总线这一过程的分析 作者: scutan
http://linux.chinaunix.net/bbs/thread-1052717-1-59.html
8.15 PCI驱动的suspend/resume方法,在何时调用? 作者:albcamus
http://linux.chinaunix.net/bbs/thread-984759-1-65.html
8.16 请教e1000中DMA传输的问题 作者:tqkangkang
http://linux.chinaunix.net/bbs/thread-896596-1-71.html
8.17 改写drivers/net/8139too.c 作者:xiongce
http://linux.chinaunix.net/bbs/thread-895246-1-72.html
8.18 字符设备驱动 架构分析 作者:xpl
http://linux.chinaunix.net/bbs/thread-1027719-1-82.html
8.19 看块设备驱动部分的笔记 作者:xpl
http://linux.chinaunix.net/bbs/thread-1008997-1-113.html
8.20 关于iptables中ip_conntrack_max和hash表的关系及调整 作者:NetDC
http://linux.chinaunix.net/bbs/thread-596067-1-150.html
8.21 pci_dma_sync_single_for_cpu到底同步的是什么? 作者:smalloc
http://linux.chinaunix.net/bbs/thread-987061-1-151.html
8.22 关于ROM BIOS的启动问题 作者:daidongly
http://linux.chinaunix.net/bbs/thread-979127-1-153.html
8.23 最近在学习2.6的device model,写了篇学习文档,分享给大家 作者:semiyd
http://linux.chinaunix.net/bbs/thread-905104-1-162.html
8.24 Linux那些事儿之我是U盘 提供pdf格式下载 作者:冷月葬花魂
http://linux.chinaunix.net/bbs/thread-905580-1-169.html
8.25 [转一好文]从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响 作者:albcamus
http://linux.chinaunix.net/bbs/thread-700366-1-177.html
8.26 硬盘扇区的读写函数及其调用路径 作者:思一克
http://linux.chinaunix.net/bbs/thread-718919-1-197.html
9. 安全相关9.1 使用 netfilter/iptables 为 Linux(内核 2.4.x )配置防火墙 作者:轩辕砍刀
http://linux.chinaunix.net/bbs/thread-63898-1-3.html
9.2 使用kprobes,截获execve系统调用 作者:albcamus
http://linux.chinaunix.net/bbs/thread-909712-1-8.html
9.3 Adore-ng-0.56源码分析 作者:ubuntuer
http://linux.chinaunix.net/bbs/thread-1138561-1-8.html
9.4 突破linux内核模块验证 作者:W.Z.T
http://linux.chinaunix.net/bbs/thread-1150719-1-15.html
9.5 【iptables交流贴】iptables执行的流程分析 作者:Godbach
http://linux.chinaunix.net/bbs/thread-1022438-1-16.html
9.6 剖析一个由sendfile引发的linux内核BUG 作者:kouu
http://linux.chinaunix.net/bbs/thread-1153577-1-16.html
9.7 Linux堆栈溢出的经典问题,欢迎围观!大牛前进 作者:GoldenSoldier
http://linux.chinaunix.net/bbs/thread-1145802-1-19.html
9.8 [欢迎进入讨论] 关于syn-proxy的一些问题 作者:Godbach
http://linux.chinaunix.net/bbs/thread-1065143-1-21.html
9.9 新爆内核高危漏洞sock_sendpage的利用分析的讨论 作者: 独孤九贱
http://linux.chinaunix.net/bbs/thread-1130648-1-21.html
9.10 Linux下实现劫持系统调用的总结 作者:Godbach
http://linux.chinaunix.net/bbs/thread-1147025-1-23.html
9.11 Snort 入侵检测系统源码分析 作者:Godbach 原创作者:独孤九贱
http://linux.chinaunix.net/bbs/thread-1122507-1-23.html
9.12 呵呵,我也凑个热闹,转发一个原来写的 iptables 版 DNS 匹配模块 作者:platinum
http://linux.chinaunix.net/bbs/thread-1149676-1-25.html
9.13 netlink+netfilter+BloomFilter内核态过滤URL 作者:ubuntuer
http://linux.chinaunix.net/bbs/thread-1149519-1-34.html
9.14 共享:linux arp 欺骗程序 作者:wojiaohesen
http://linux.chinaunix.net/bbs/thread-1134584-1-35.html
9.15 劫持函数调用 作者:ubuntuer
http://linux.chinaunix.net/bbs/thread-1148600-1-36.html
9.16 [原创]关于劫持系统调用隐藏进程的一些心得 作者:g84ch
http://linux.chinaunix.net/bbs/thread-1135859-1-38.html
9.17 Linux内核的加密函数框架 作者:richardhesidu
http://linux.chinaunix.net/bbs/thread-1098120-1-56.html
9.18 Linux-Netfilter&iptables实现机制的分析及应用 作者:Minit
http://linux.chinaunix.net/bbs/thread-1117331-1-59.html
9.19 iptables 源码分析 作者:独孤九贱
http://linux.chinaunix.net/bbs/thread-663849-1-93.html
9.20 get system call table in x86-64 Linux - 欢迎测试并报BUG 作者:albcamus
http://linux.chinaunix.net/bbs/thread-885248-1-100.html -
Linux内核学习笔记 -13 动手实践 - 打印进程描述符task_struct中的字段
2020-07-29 07:55:18采用的方式:插入内核模块 使用的方法:遍历进程链表 先在https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-5.3.y&id=d4f3318ed8fab6316cb7a269b8f42306632a3876下载源码,...采用的方式:插入内核模块
使用的方法:遍历进程链表
先在https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-5.3.y&id=d4f3318ed8fab6316cb7a269b8f42306632a3876 下载源码,用sublim浏览,在include目录下打开头文件。
下载好源码,解压后,用Sublime File--->OpenFolder打开源码所在目录
打开后,就会显示类似的目录结构
在include文件的目录下打开头文件。task_struct结构位于sched.h头文件中。/include/linux/sched.h
schde.h就显示了pcb在内核中的全貌。涉及的字段非常多。这里只关注pcb本身,能反映器其结构的字段。
首先看第一个字段thread_info,也就是它的状态信息,
打印pcb的重要信息,比如状态信息,优先级信息,亲属关系,文件系统信息以及内存方面的信息。
Makefile
# Makefile文件注意:加入前面的.c文件起名为first.c,那么这里的Makefile文件中的.o文件就要起名first.o # 只有root用户才能加载和卸载模块 obj-m:=task_struct.o # 产生first模块的目标文件 #目标文件 文件 要与模块名字相同 CURRENT_PATH:=$(shell pwd) LINUX_KERNEL:=$(shell uname -r) LINUX_KERNEL_PATH:=/usr/src/linux-headers-$(LINUX_KERNEL) all: make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules # 编译模块 #[TAB] 内核的路径 当前目录编译完放哪里? 表明编译的是内核模块 clean: make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean # 清理模块
task_struct.c
book@100ask:~/Mooc/CH03$ cat task_struct.c #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <linux/sched.h> //task结构体 #include <linux/fdtable.h> //files #include <linux/fs_struct.h> //fs #include <linux/mm_types.h> //打印内存信息 #include <linux/init_task.h> MODULE_LICENSE("GPL"); //许可证 //入口函数 static int __init print_pcb(void) //init宏是由init.h文件所支持 { struct task_struct *task,*p; struct list_head *pos; //双向链表 int count=0; printk("begin...\n"); //对链表遍历时,希望从第一个开始 task=&init_task; //指向0号进程pcb list_for_each(pos,&task->tasks) //遍历操作,使用pos指向,传入的参数task指向tasks字段.0号进程的tasks进行遍历。tasks将所有的进程连在一块。 { p=list_entry(pos,struct task_struct,tasks); //找到一个节点,就可以用这个节点的tasks字段,找到这个结构体的出口地址.对应的字段tasks //此时的p指针已经指向task_struct结构体的首部,后面就可以通过p指针进行操作 count++; //找到一个进程,自加 printk("\n\n"); printk("pid: %d; state: %lx; prior: %d; static_pri: %d; parent_pid: %d; count: %d; umask: %d",p->pid,p->state,p->prio,p->static_prio,(p->parent)->pid,(p->files)->count,(p->fs)->umask); //linux中内核线程的mm是空的,要对它进行打印,就会出错,指针错误 if((p->mm)!=NULL) printk("Total_vm: %ld",(p->mm)->total_vm); } printk("进程的个数:%d\n",count); return 0; } static void __exit exit_pcb(void) //出口函数 { printk("Exiting...\n"); } // 指明入口点与出口点,入口/出口点是由module.h支持的 module_init(print_pcb); module_exit(exit_pcb);
book@100ask:~/Mooc/CH03$ make make -C /usr/src/linux-headers-5.4.0-42-generic M=/home/book/Mooc/CH03 modules # 编译模块 make[1]: Entering directory '/usr/src/linux-headers-5.4.0-42-generic' CC [M] /home/book/Mooc/CH03/task_struct.o /home/book/Mooc/CH03/task_struct.c: In function ‘print_pcb’: /home/book/Mooc/CH03/task_struct.c:30:83: warning: format ‘%d’ expects argument of type ‘int’, but argument 7 has type ‘atomic_t {aka struct <anonymous>}’ [-Wformat=] printk("pid: %d; state: %lx; prior: %d; static_pri: %d; parent_pid: %d; count: %d; umask: %d",p->pid,p->state,p->prio,p->static_prio,(p->parent)->pid,(p->files)->count,(p->fs)->umask); ~^ ~~~~~~~~~~~~~~~~~ Building modules, stage 2. MODPOST 1 modules CC [M] /home/book/Mooc/CH03/task_struct.mod.o LD [M] /home/book/Mooc/CH03/task_struct.ko make[1]: Leaving directory '/usr/src/linux-headers-5.4.0-42-generic' book@100ask:~/Mooc/CH03$ ls Makefile modules.order Module.symvers task_struct.c task_struct.ko task_struct.mod task_struct.mod.c task_struct.mod.o task_struct.o
book@100ask:~/Mooc/CH03$ make clean make -C /usr/src/linux-headers-5.4.0-42-generic M=/home/book/Mooc/CH03 clean # 清理模块 make[1]: Entering directory '/usr/src/linux-headers-5.4.0-42-generic' CLEAN /home/book/Mooc/CH03/Module.symvers make[1]: Leaving directory '/usr/src/linux-headers-5.4.0-42-generic'
book@100ask:~/Mooc/CH03$ cat task_struct.c #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <linux/sched.h> //task结构体 #include <linux/fdtable.h> //files #include <linux/fs_struct.h> //fs #include <linux/mm_types.h> //打印内存信息 #include <linux/init_task.h> #include <linux/types.h> #include <linux/atomic.h> MODULE_LICENSE("GPL"); //许可证 //入口函数 static int __init print_pcb(void) //init宏是由init.h文件所支持 { struct task_struct *task,*p; struct list_head *pos; //双向链表 int count=0; printk("begin...\n"); //对链表遍历时,希望从第一个开始 task=&init_task; //指向0号进程pcb list_for_each(pos,&task->tasks) //遍历操作,使用pos指向,传入的参数task指向tasks字段.0号进程的tasks进行遍历。tasks将所有的进程连在一块。 { p=list_entry(pos,struct task_struct,tasks); //找到一个节点,就可以用这个节点的tasks字段,找到这个结构体的出口地址.对应的字段tasks //此时的p指针已经指向task_struct结构体的首部,后面就可以通过p指针进行操作 count++; //找到一个进程,自加 printk("\n\n"); printk("pid: %d; state: %lx; prior: %d; static_pri: %d; parent_pid: %d; count: %d; umask: %d",p->pid,p->state,p->prio,p->static_prio,(p->parent)->pid,atomic_read(&(p->files)->count),(p->fs)->umask); //linux中内核线程的mm是空的,要对它进行打印,就会出错,指针错误 if((p->mm)!=NULL) printk("Total_vm: %ld",(p->mm)->total_vm); } printk("进程的个数:%d\n",count); return 0; } static void __exit exit_pcb(void) //出口函数 { printk("Exiting...\n"); } // 指明入口点与出口点,入口/出口点是由module.h支持的 module_init(print_pcb); module_exit(exit_pcb);
book@100ask:~/Mooc/CH03$ make make -C /usr/src/linux-headers-5.4.0-42-generic M=/home/book/Mooc/CH03 modules # 编译模块 make[1]: Entering directory '/usr/src/linux-headers-5.4.0-42-generic' CC [M] /home/book/Mooc/CH03/task_struct.o Building modules, stage 2. MODPOST 1 modules CC [M] /home/book/Mooc/CH03/task_struct.mod.o LD [M] /home/book/Mooc/CH03/task_struct.ko make[1]: Leaving directory '/usr/src/linux-headers-5.4.0-42-generic'
sudo insmod task_struct.ko 加载内核模块
dmesg 查看内核打印信息
[ 5751.081752] pid: 1985; state: 1; prior: 120; static_pri: 120; parent_pid: 1847; count: 3; umask: 2 [ 5751.081752] Total_vm: 49445 [ 5751.081753] [ 5751.081755] pid: 2013; state: 1; prior: 120; static_pri: 120; parent_pid: 1; count: 3; umask: 18 [ 5751.081755] Total_vm: 79477 [ 5751.081756] [ 5751.081757] pid: 2093; state: 1; prior: 120; static_pri: 120; parent_pid: 1240; count: 3; umask: 2 [ 5751.081758] Total_vm: 65159 [ 5751.081758] [ 5751.081761] pid: 2509; state: 1; prior: 120; static_pri: 120; parent_pid: 1; count: 1; umask: 2 [ 5751.081761] Total_vm: 19293 [ 5751.081761] [ 5751.081763] pid: 2510; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 1; umask: 2 [ 5751.081763] Total_vm: 49029 [ 5751.081764] [ 5751.081765] pid: 2523; state: 1; prior: 120; static_pri: 120; parent_pid: 1; count: 4; umask: 2 [ 5751.081765] Total_vm: 70315 [ 5751.081766] [ 5751.081767] pid: 2529; state: 1; prior: 120; static_pri: 120; parent_pid: 2093; count: 3; umask: 2 [ 5751.081768] Total_vm: 51256 [ 5751.081768] [ 5751.081770] pid: 2531; state: 1; prior: 120; static_pri: 120; parent_pid: 2529; count: 2; umask: 18 [ 5751.081770] Total_vm: 98052 [ 5751.081771] [ 5751.081772] pid: 2536; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 1; umask: 18 [ 5751.081773] Total_vm: 12817 [ 5751.081773] [ 5751.081775] pid: 2539; state: 1; prior: 120; static_pri: 120; parent_pid: 2529; count: 4; umask: 2 [ 5751.081776] Total_vm: 174903 [ 5751.081776] [ 5751.081777] pid: 2634; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 1; umask: 2 [ 5751.081778] Total_vm: 2825 [ 5751.081778] [ 5751.081780] pid: 2663; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 4; umask: 18 [ 5751.081780] Total_vm: 87322 [ 5751.081781] [ 5751.081813] pid: 2668; state: 1; prior: 120; static_pri: 120; parent_pid: 2663; count: 1; umask: 18 [ 5751.081814] Total_vm: 12480 [ 5751.081815] [ 5751.081845] pid: 2671; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 3; umask: 18 [ 5751.081846] Total_vm: 55177 [ 5751.081846] [ 5751.081848] pid: 2690; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 12; umask: 2 [ 5751.081848] Total_vm: 830957 [ 5751.081849] [ 5751.081851] pid: 2700; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 3; umask: 18 [ 5751.081851] Total_vm: 71216 [ 5751.081851] [ 5751.081928] pid: 2705; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 6; umask: 18 [ 5751.081961] Total_vm: 104028 [ 5751.081962] [ 5751.081964] pid: 2721; state: 1; prior: 109; static_pri: 109; parent_pid: 1; count: 4; umask: 18 [ 5751.081965] Total_vm: 333507 [ 5751.081965] [ 5751.081967] pid: 2753; state: 1; prior: 120; static_pri: 120; parent_pid: 2690; count: 3; umask: 2 [ 5751.081967] Total_vm: 106998 [ 5751.081968] [ 5751.081969] pid: 2758; state: 1; prior: 120; static_pri: 120; parent_pid: 2753; count: 4; umask: 2 [ 5751.081970] Total_vm: 68409 [ 5751.081970] [ 5751.081973] pid: 2760; state: 1; prior: 120; static_pri: 120; parent_pid: 1; count: 3; umask: 2 [ 5751.081973] Total_vm: 84220 [ 5751.081975] [ 5751.081978] pid: 2762; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 3; umask: 18 [ 5751.081979] Total_vm: 67862 [ 5751.081981] [ 5751.081983] pid: 2800; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 6; umask: 18 [ 5751.081984] Total_vm: 172441 [ 5751.081986] [ 5751.081990] pid: 2805; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 4; umask: 18 [ 5751.081991] Total_vm: 324879 [ 5751.081993] [ 5751.081996] pid: 2815; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 4; umask: 18 [ 5751.081997] Total_vm: 194163 [ 5751.081999] [ 5751.082003] pid: 2823; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 3; umask: 18 [ 5751.082004] Total_vm: 46976 [ 5751.082006] [ 5751.082007] pid: 2827; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 3; umask: 18 [ 5751.082009] Total_vm: 74834 [ 5751.082010] [ 5751.082013] pid: 2836; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 4; umask: 18 [ 5751.082014] Total_vm: 74063 [ 5751.082017] [ 5751.082020] pid: 2841; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 3; umask: 18 [ 5751.082022] Total_vm: 67190 [ 5751.082026] [ 5751.082030] pid: 2845; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 3; umask: 18 [ 5751.082031] Total_vm: 66734 [ 5751.082034] [ 5751.082036] pid: 2849; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 4; umask: 18 [ 5751.082036] Total_vm: 92928 [ 5751.082037] [ 5751.082038] pid: 2854; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 3; umask: 18 [ 5751.082038] Total_vm: 70388 [ 5751.082039] [ 5751.082041] pid: 2858; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 4; umask: 2 [ 5751.082041] Total_vm: 127531 [ 5751.082042] [ 5751.082043] pid: 2859; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 3; umask: 2 [ 5751.082043] Total_vm: 85556 [ 5751.082043] [ 5751.082045] pid: 2862; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 3; umask: 2 [ 5751.082045] Total_vm: 104059 [ 5751.082046] [ 5751.082047] pid: 2864; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 3; umask: 2 [ 5751.082048] Total_vm: 67156 [ 5751.082048] [ 5751.082080] pid: 2868; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 4; umask: 2 [ 5751.082081] Total_vm: 111432 [ 5751.082081] [ 5751.082083] pid: 2872; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 4; umask: 2 [ 5751.082083] Total_vm: 81439 [ 5751.082083] [ 5751.082085] pid: 2873; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 4; umask: 2 [ 5751.082085] Total_vm: 121857 [ 5751.082086] [ 5751.082087] pid: 2879; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 5; umask: 2 [ 5751.082088] Total_vm: 92705 [ 5751.082088] [ 5751.082090] pid: 2887; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 3; umask: 2 [ 5751.082090] Total_vm: 105343 [ 5751.082090] [ 5751.082092] pid: 2896; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 4; umask: 2 [ 5751.082092] Total_vm: 67760 [ 5751.082093] [ 5751.082094] pid: 2897; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 3; umask: 2 [ 5751.082094] Total_vm: 84125 [ 5751.082095] [ 5751.082097] pid: 2898; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 4; umask: 2 [ 5751.082097] Total_vm: 162918 [ 5751.082098] [ 5751.082099] pid: 2900; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 4; umask: 2 [ 5751.082100] Total_vm: 115658 [ 5751.082100] [ 5751.082101] pid: 2903; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 4; umask: 2 [ 5751.082102] Total_vm: 89334 [ 5751.082102] [ 5751.082104] pid: 2904; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 4; umask: 2 [ 5751.082104] Total_vm: 124862 [ 5751.082105] [ 5751.082106] pid: 2905; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 4; umask: 2 [ 5751.082107] Total_vm: 268116 [ 5751.082107] [ 5751.082109] pid: 2911; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 4; umask: 2 [ 5751.082109] Total_vm: 67763 [ 5751.082109] [ 5751.082111] pid: 2932; state: 1; prior: 120; static_pri: 120; parent_pid: 1; count: 3; umask: 2 [ 5751.082112] Total_vm: 125415 [ 5751.082112] [ 5751.082114] pid: 2956; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 3; umask: 2 [ 5751.082114] Total_vm: 67983 [ 5751.082114] [ 5751.082116] pid: 2965; state: 1; prior: 120; static_pri: 120; parent_pid: 1; count: 4; umask: 2 [ 5751.082116] Total_vm: 119454 [ 5751.082117] [ 5751.082118] pid: 2966; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 4; umask: 2 [ 5751.082118] Total_vm: 229089 [ 5751.082119] [ 5751.082120] pid: 2983; state: 1; prior: 120; static_pri: 120; parent_pid: 2700; count: 3; umask: 18 [ 5751.082121] Total_vm: 90282 [ 5751.082121] [ 5751.082123] pid: 2999; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 5; umask: 18 [ 5751.082123] Total_vm: 221251 [ 5751.082124] [ 5751.082156] pid: 3047; state: 1; prior: 120; static_pri: 120; parent_pid: 2999; count: 9; umask: 18 [ 5751.082156] Total_vm: 263758 [ 5751.082157] [ 5751.082159] pid: 3049; state: 1; prior: 120; static_pri: 120; parent_pid: 2753; count: 3; umask: 2 [ 5751.082160] Total_vm: 49445 [ 5751.082160] [ 5751.082162] pid: 3066; state: 1; prior: 120; static_pri: 120; parent_pid: 2509; count: 5; umask: 18 [ 5751.082162] Total_vm: 181428 [ 5751.082162] [ 5751.082164] pid: 3077; state: 1; prior: 120; static_pri: 120; parent_pid: 3066; count: 6; umask: 18 [ 5751.082165] Total_vm: 252524 [ 5751.082165] [ 5751.082167] pid: 3322; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 4; umask: 2 [ 5751.082167] Total_vm: 109559 [ 5751.082167] [ 5751.082169] pid: 3324; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 4; umask: 2 [ 5751.082170] Total_vm: 334283 [ 5751.082170] [ 5751.082172] pid: 3351; state: 1; prior: 120; static_pri: 120; parent_pid: 1; count: 5; umask: 18 [ 5751.082204] Total_vm: 145759 [ 5751.082206] [ 5751.082208] pid: 3540; state: 1; prior: 120; static_pri: 120; parent_pid: 1; count: 1; umask: 18 [ 5751.082208] Total_vm: 25147 [ 5751.082209] [ 5751.082210] pid: 3541; state: 1; prior: 120; static_pri: 120; parent_pid: 1; count: 3; umask: 18 [ 5751.082211] Total_vm: 75882 [ 5751.082211] [ 5751.082213] pid: 3609; state: 1; prior: 120; static_pri: 120; parent_pid: 1140; count: 1; umask: 2 [ 5751.082214] Total_vm: 26945 [ 5751.082214] [ 5751.082216] pid: 3666; state: 1; prior: 120; static_pri: 120; parent_pid: 2539; count: 4; umask: 2 [ 5751.082216] Total_vm: 197501 [ 5751.082216] [ 5751.082218] pid: 3746; state: 1; prior: 120; static_pri: 120; parent_pid: 3609; count: 1; umask: 2 [ 5751.082219] Total_vm: 27519 [ 5751.082219] [ 5751.082221] pid: 3747; state: 1; prior: 120; static_pri: 120; parent_pid: 3746; count: 1; umask: 2 [ 5751.082221] Total_vm: 5668 [ 5751.082222] [ 5751.082224] pid: 3837; state: 402; prior: 120; static_pri: 120; parent_pid: 2; count: 199; umask: 0 [ 5751.082224] [ 5751.082226] pid: 6105; state: 402; prior: 120; static_pri: 120; parent_pid: 2; count: 199; umask: 0 [ 5751.082226] [ 5751.082227] pid: 6122; state: 402; prior: 120; static_pri: 120; parent_pid: 2; count: 199; umask: 0 [ 5751.082228] [ 5751.082230] pid: 6443; state: 402; prior: 120; static_pri: 120; parent_pid: 2; count: 199; umask: 0 [ 5751.082230] //没有打印total_vm,说明它的mm字段为空,是内核线程? [ 5751.082231] pid: 6859; state: 1; prior: 120; static_pri: 120; parent_pid: 3747; count: 1; umask: 18 [ 5751.082232] Total_vm: 18034 //说明该进程的线性空间共有18034个页 [ 5751.082232] [ 5751.082234] pid: 6861; state: 1; prior: 120; static_pri: 120; parent_pid: 1; count: 3; umask: 18 [ 5751.082235] Total_vm: 53708 [ 5751.082235] [ 5751.082236] pid: 6867; state: 0; prior: 120; static_pri: 120; parent_pid: 6859; count: 1; umask: 18 [ 5751.082237] Total_vm: 1163 [ 5751.082237] 进程的个数:342 //共342个进程
#include/linux/list.h
/** * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. */ #define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next) #书写遍历所有进程的代码,此处需要用到list.h这个宏。在list.h中首先用到的是list_for_each, 遍历的是head链表。遍历到每一个节点时,使用pos指向。具体到某一个节点> ,用到list_entry.
/** * list_entry - get the struct for this entry * @ptr: the &struct list_head pointer. * @type: the type of the struct this is embedded in. * @member: the name of the list_head within the struct. */ #define list_entry(ptr, type, member) \ container_of(ptr, type, member) list_entry实际上使用的container_of宏,这个宏中ptr代表的是结构体中member的地址。 type就是结构体的类型,member就是结构体中的成员。上一步,使用for语句遍历到每一个节点, 在这个节点,前面所了解到的字段中已经是tasks来连接起来。即可以利用tasks字段来得到当前 结构体的首地址。之后我们再使用一个指针指向,然后就可以对这个结构体进行打印操作。
fdtable.h
struct files_struct { /* * read mostly part */ atomic_t count; //count是原子操作,加1操作,分三步: 1- 从内存中读取数值到寄存器中; 2-寄存器加1 3-存寄存器中返回内存。如果执行过程中发送中断,则会影响到值。需要用到同步机制。 bool resize_in_progress; wait_queue_head_t resize_wait; struct fdtable __rcu *fdt; struct fdtable fdtab; /* * written part on a separate cache line in SMP */ spinlock_t file_lock ____cacheline_aligned_in_smp; unsigned int next_fd; unsigned long close_on_exec_init[1]; unsigned long open_fds_init[1]; unsigned long full_fds_bits_init[1]; struct file __rcu * fd_array[NR_OPEN_DEFAULT]; };
原子的操作,都在atomic.h文件中。
struct task_struct { #ifdef CONFIG_THREAD_INFO_IN_TASK /* * For reasons of header soup (see current_thread_info()), this * must be the first element of task_struct. */ struct thread_info thread_info; #endif /* -1 unrunnable, 0 runnable, >0 stopped: */ //状态信息 volatile long state; /* * This begins the randomizable portion of task_struct. Only * scheduling-critical items should be added above here. */ randomized_struct_fields_start void *stack; refcount_t usage; /* Per task flags (PF_*), defined further below: */ //内核栈 unsigned int flags; //标计 unsigned int ptrace; //主要用于断点调试 #ifdef CONFIG_SMP struct llist_node wake_entry; int on_cpu; #ifdef CONFIG_THREAD_INFO_IN_TASK /* Current CPU: */ unsigned int cpu; #endif unsigned int wakee_flips; unsigned long wakee_flip_decay_ts; struct task_struct *last_wakee; /* * recent_used_cpu is initially set as the last CPU used by a task * that wakes affine another task. Waker/wakee relationships can * push tasks around a CPU where each wakeup moves to the next one. * Tracking a recently used CPU allows a quick search for a recently * used CPU that may be idle. */ int recent_used_cpu; int wake_cpu; #endif int on_rq; int prio; //优先级信息,动态优先级 int static_prio; //静态优先级 int normal_prio; unsigned int rt_priority; //实时优先级 const struct sched_class *sched_class; struct sched_entity se; struct sched_rt_entity rt; #ifdef CONFIG_CGROUP_SCHED struct task_group *sched_task_group; #endif struct sched_dl_entity dl; #ifdef CONFIG_UCLAMP_TASK /* Clamp values requested for a scheduling entity */ struct uclamp_se uclamp_req[UCLAMP_CNT]; /* Effective clamp values used for a scheduling entity */ struct uclamp_se uclamp[UCLAMP_CNT]; #endif #ifdef CONFIG_PREEMPT_NOTIFIERS /* List of struct preempt_notifier: */ struct hlist_head preempt_notifiers; #endif #ifdef CONFIG_BLK_DEV_IO_TRACE unsigned int btrace_seq; #endif unsigned int policy; //进程调度策略 int nr_cpus_allowed; const cpumask_t *cpus_ptr; cpumask_t cpus_mask; #ifdef CONFIG_PREEMPT_RCU int rcu_read_lock_nesting; union rcu_special rcu_read_unlock_special; struct list_head rcu_node_entry; struct rcu_node *rcu_blocked_node; #endif /* #ifdef CONFIG_PREEMPT_RCU */ #ifdef CONFIG_TASKS_RCU unsigned long rcu_tasks_nvcsw; u8 rcu_tasks_holdout; u8 rcu_tasks_idx; int rcu_tasks_idle_cpu; struct list_head rcu_tasks_holdout_list; #endif /* #ifdef CONFIG_TASKS_RCU */ struct sched_info sched_info; //调度器统计进程的运行信息 struct list_head tasks; //tasks字段是一个双向链表,正是这个字段将所有的进程连在一块,然后才能对进程进行遍历。 #ifdef CONFIG_SMP struct plist_node pushable_tasks; struct rb_node pushable_dl_tasks; #endif struct mm_struct *mm; //线性地址的所有信息 struct mm_struct *active_mm; //最后访问的地址空间指针 /* Per-thread vma caching: */ struct vmacache vmacache; #ifdef SPLIT_RSS_COUNTING struct task_rss_stat rss_stat; #endif int exit_state; //判断标志 int exit_code; //进程终止代号 int exit_signal; /* The signal sent when the parent dies: */ int pdeath_signal; /* JOBCTL_*, siglock protected: */ unsigned long jobctl; /* Used for emulating ABI behavior of previous Linux versions: */ unsigned int personality; /* Scheduler bits, serialized by scheduler locks: */ unsigned sched_reset_on_fork:1; unsigned sched_contributes_to_load:1; unsigned sched_migrated:1; unsigned sched_remote_wakeup:1; #ifdef CONFIG_PSI unsigned sched_psi_wake_requeue:1; #endif /* Force alignment to the next boundary: */ unsigned :0; /* Unserialized, strictly 'current' */ /* Bit to tell LSMs we're in execve(): */ unsigned in_execve:1; unsigned in_iowait:1; #ifndef TIF_RESTORE_SIGMASK unsigned restore_sigmask:1; #endif #ifdef CONFIG_MEMCG unsigned in_user_fault:1; #endif #ifdef CONFIG_COMPAT_BRK unsigned brk_randomized:1; #endif #ifdef CONFIG_CGROUPS /* disallow userland-initiated cgroup migration */ unsigned no_cgroup_migration:1; /* task is frozen/stopped (used by the cgroup freezer) */ unsigned frozen:1; #endif #ifdef CONFIG_BLK_CGROUP /* to be used once the psi infrastructure lands upstream. */ unsigned use_memdelay:1; #endif unsigned long atomic_flags; /* Flags requiring atomic access. */ struct restart_block restart_block; pid_t pid; //进程标识符 pid_t tgid; #ifdef CONFIG_STACKPROTECTOR /* Canary value for the -fstack-protector GCC feature: */ unsigned long stack_canary; #endif /* * Pointers to the (original) parent process, youngest child, younger sibling, * older sibling, respectively. (p->father can be replaced with * p->real_parent->pid) */ /* Real parent process: */ struct task_struct __rcu *real_parent; //进程的亲属关系 /* Recipient of SIGCHLD, wait4() reports: */ struct task_struct __rcu *parent; /* * Children/sibling form the list of natural children: */ struct list_head children; struct list_head sibling; struct task_struct *group_leader; /* * 'ptraced' is the list of tasks this task is using ptrace() on. * * This includes both natural children and PTRACE_ATTACH targets. * 'ptrace_entry' is this task's link on the p->parent->ptraced list. */ struct list_head ptraced; struct list_head ptrace_entry; /* PID/PID hash table linkage. */ struct pid *thread_pid; struct hlist_node pid_links[PIDTYPE_MAX]; struct list_head thread_group; struct list_head thread_node; struct completion *vfork_done; /* CLONE_CHILD_SETTID: */ int __user *set_child_tid; /* CLONE_CHILD_CLEARTID: */ int __user *clear_child_tid; u64 utime; u64 stime; #ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME u64 utimescaled; u64 stimescaled; #endif u64 gtime; struct prev_cputime prev_cputime; #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN struct vtime vtime; #endif #ifdef CONFIG_NO_HZ_FULL atomic_t tick_dep_mask; #endif /* Context switch counts: */ unsigned long nvcsw; //这两个字段是用来反映上下文切换的次数,其中nvcsw反映主动上下文切换的次数; unsigned long nivcsw; //nivcsw反映被动上下文切换的次数 /* Monotonic time in nsecs: */ u64 start_time; /* Boot based time in nsecs: */ u64 real_start_time; /* MM fault and swap info: this can arguably be seen as either mm-specific or thread-specific: */ unsigned long min_flt; //缺页统计 unsigned long maj_flt; #ifdef CONFIG_POSIX_TIMERS struct task_cputime cputime_expires; struct list_head cpu_timers[3]; #endif /* Process credentials: */ /* Tracer's credentials at attach: */ const struct cred __rcu *ptracer_cred; /* Objective and real subjective task credentials (COW): */ const struct cred __rcu *real_cred; /* Effective (overridable) subjective task credentials (COW): */ const struct cred __rcu *cred; #ifdef CONFIG_KEYS /* Cached requested key. */ struct key *cached_requested_key; #endif /* * executable name, excluding path. * * - normally initialized setup_new_exec() * - access it with [gs]et_task_comm() * - lock it with task_lock() */ char comm[TASK_COMM_LEN]; //该数组是相应程序的名字 struct nameidata *nameidata; #ifdef CONFIG_SYSVIPC struct sysv_sem sysvsem; //如下两个字段负责进程间通信 struct sysv_shm sysvshm; #endif #ifdef CONFIG_DETECT_HUNG_TASK unsigned long last_switch_count; unsigned long last_switch_time; #endif /* Filesystem information: */ struct fs_struct *fs; //文件信息,fs保持指向文件信息的指针 /* Open file information: */ struct files_struct *files; //保存指向进程的文件,描述表的指针 /* Namespaces: */ struct nsproxy *nsproxy; //命名空间 /* Signal handlers: */ struct signal_struct *signal; //信号描述符 struct sighand_struct *sighand; sigset_t blocked; sigset_t real_blocked; /* Restored if set_restore_sigmask() was used: */ sigset_t saved_sigmask; struct sigpending pending; unsigned long sas_ss_sp; size_t sas_ss_size; unsigned int sas_ss_flags; struct callback_head *task_works; #ifdef CONFIG_AUDIT #ifdef CONFIG_AUDITSYSCALL struct audit_context *audit_context; #endif kuid_t loginuid; unsigned int sessionid; #endif struct seccomp seccomp; /* Thread group tracking: */ u32 parent_exec_id; u32 self_exec_id; /* Protection against (de-)allocation: mm, files, fs, tty, keyrings, mems_allowed, mempolicy: */ spinlock_t alloc_lock; /* Protection of the PI data structures: */ raw_spinlock_t pi_lock; struct wake_q_node wake_q; #ifdef CONFIG_RT_MUTEXES /* PI waiters blocked on a rt_mutex held by this task: */ struct rb_root_cached pi_waiters; /* Updated under owner's pi_lock and rq lock */ struct task_struct *pi_top_task; /* Deadlock detection and priority inheritance handling: */ struct rt_mutex_waiter *pi_blocked_on; #endif #ifdef CONFIG_DEBUG_MUTEXES /* Mutex deadlock detection: */ struct mutex_waiter *blocked_on; #endif #ifdef CONFIG_TRACE_IRQFLAGS unsigned int irq_events; //irq unsigned long hardirq_enable_ip; unsigned long hardirq_disable_ip; unsigned int hardirq_enable_event; unsigned int hardirq_disable_event; int hardirqs_enabled; int hardirq_context; unsigned long softirq_disable_ip; unsigned long softirq_enable_ip; unsigned int softirq_disable_event; unsigned int softirq_enable_event; int softirqs_enabled; int softirq_context; #endif #ifdef CONFIG_LOCKDEP # define MAX_LOCK_DEPTH 48UL u64 curr_chain_key; int lockdep_depth; unsigned int lockdep_recursion; struct held_lock held_locks[MAX_LOCK_DEPTH]; #endif #ifdef CONFIG_UBSAN unsigned int in_ubsan; #endif /* Journalling filesystem info: */ void *journal_info; /* Stacked block device info: */ struct bio_list *bio_list; #ifdef CONFIG_BLOCK /* Stack plugging: */ struct blk_plug *plug; #endif /* VM state: */ struct reclaim_state *reclaim_state; //内存回收 struct backing_dev_info *backing_dev_info; struct io_context *io_context; //记录进程的io计数 #ifdef CONFIG_COMPACTION struct capture_control *capture_control; #endif /* Ptrace state: */ unsigned long ptrace_message; kernel_siginfo_t *last_siginfo; struct task_io_accounting ioac; #ifdef CONFIG_PSI /* Pressure stall state */ unsigned int psi_flags; #endif #ifdef CONFIG_TASK_XACCT /* Accumulated RSS usage: */ u64 acct_rss_mem1; /* Accumulated virtual memory usage: */ u64 acct_vm_mem1; /* stime + utime since last update: */ u64 acct_timexpd; #endif #ifdef CONFIG_CPUSETS /* Protected by ->alloc_lock: */ nodemask_t mems_allowed; /* Seqence number to catch updates: */ seqcount_t mems_allowed_seq; int cpuset_mem_spread_rotor; int cpuset_slab_spread_rotor; #endif #ifdef CONFIG_CGROUPS /* Control Group info protected by css_set_lock: */ struct css_set __rcu *cgroups; /* cg_list protected by css_set_lock and tsk->alloc_lock: */ struct list_head cg_list; #endif #ifdef CONFIG_X86_CPU_RESCTRL u32 closid; u32 rmid; #endif #ifdef CONFIG_FUTEX struct robust_list_head __user *robust_list; #ifdef CONFIG_COMPAT struct compat_robust_list_head __user *compat_robust_list; #endif struct list_head pi_state_list; struct futex_pi_state *pi_state_cache; #endif #ifdef CONFIG_PERF_EVENTS struct perf_event_context *perf_event_ctxp[perf_nr_task_contexts]; struct mutex perf_event_mutex; struct list_head perf_event_list; #endif #ifdef CONFIG_DEBUG_PREEMPT unsigned long preempt_disable_ip; #endif #ifdef CONFIG_NUMA /* Protected by alloc_lock: */ struct mempolicy *mempolicy; short il_prev; short pref_node_fork; #endif #ifdef CONFIG_NUMA_BALANCING int numa_scan_seq; unsigned int numa_scan_period; unsigned int numa_scan_period_max; int numa_preferred_nid; unsigned long numa_migrate_retry; /* Migration stamp: */ u64 node_stamp; u64 last_task_numa_placement; u64 last_sum_exec_runtime; struct callback_head numa_work; /* * This pointer is only modified for current in syscall and * pagefault context (and for tasks being destroyed), so it can be read * from any of the following contexts: * - RCU read-side critical section * - current->numa_group from everywhere * - task's runqueue locked, task not running */ struct numa_group __rcu *numa_group; /* * numa_faults is an array split into four regions: * faults_memory, faults_cpu, faults_memory_buffer, faults_cpu_buffer * in this precise order. * * faults_memory: Exponential decaying average of faults on a per-node * basis. Scheduling placement decisions are made based on these * counts. The values remain static for the duration of a PTE scan. * faults_cpu: Track the nodes the process was running on when a NUMA * hinting fault was incurred. * faults_memory_buffer and faults_cpu_buffer: Record faults per node * during the current scan window. When the scan completes, the counts * in faults_memory and faults_cpu decay and these values are copied. */ unsigned long *numa_faults; unsigned long total_numa_faults; /* * numa_faults_locality tracks if faults recorded during the last * scan window were remote/local or failed to migrate. The task scan * period is adapted based on the locality of the faults with different * weights depending on whether they were shared or private faults */ unsigned long numa_faults_locality[3]; unsigned long numa_pages_migrated; #endif /* CONFIG_NUMA_BALANCING */ #ifdef CONFIG_RSEQ struct rseq __user *rseq; u32 rseq_sig; /* * RmW on rseq_event_mask must be performed atomically * with respect to preemption. */ unsigned long rseq_event_mask; #endif struct tlbflush_unmap_batch tlb_ubc; struct rcu_head rcu; /* Cache last used pipe for splice(): */ struct pipe_inode_info *splice_pipe; struct page_frag task_frag; #ifdef CONFIG_TASK_DELAY_ACCT struct task_delay_info *delays; #endif #ifdef CONFIG_FAULT_INJECTION int make_it_fail; unsigned int fail_nth; #endif /* * When (nr_dirtied >= nr_dirtied_pause), it's time to call * balance_dirty_pages() for a dirty throttling pause: */ int nr_dirtied; int nr_dirtied_pause; /* Start of a write-and-pause period: */ unsigned long dirty_paused_when; #ifdef CONFIG_LATENCYTOP int latency_record_count; struct latency_record latency_record[LT_SAVECOUNT]; #endif /* * Time slack values; these are used to round up poll() and * select() etc timeout values. These are in nanoseconds. */ u64 timer_slack_ns; u64 default_timer_slack_ns; #ifdef CONFIG_KASAN unsigned int kasan_depth; #endif #ifdef CONFIG_FUNCTION_GRAPH_TRACER /* Index of current stored address in ret_stack: */ int curr_ret_stack; int curr_ret_depth; /* Stack of return addresses for return function tracing: */ struct ftrace_ret_stack *ret_stack; /* Timestamp for last schedule: */ unsigned long long ftrace_timestamp; /* * Number of functions that haven't been traced * because of depth overrun: */ atomic_t trace_overrun; /* Pause tracing: */ atomic_t tracing_graph_pause; #endif #ifdef CONFIG_TRACING /* State flags for use by tracers: */ unsigned long trace; /* Bitmask and counter of trace recursion: */ unsigned long trace_recursion; #endif /* CONFIG_TRACING */ #ifdef CONFIG_KCOV /* Coverage collection mode enabled for this task (0 if disabled): */ unsigned int kcov_mode; /* Size of the kcov_area: */ unsigned int kcov_size; /* Buffer for coverage collection: */ void *kcov_area; /* KCOV descriptor wired with this task or NULL: */ struct kcov *kcov; #endif #ifdef CONFIG_MEMCG struct mem_cgroup *memcg_in_oom; gfp_t memcg_oom_gfp_mask; int memcg_oom_order; /* Number of pages to reclaim on returning to userland: */ unsigned int memcg_nr_pages_over_high; /* Used by memcontrol for targeted memcg charge: */ struct mem_cgroup *active_memcg; #endif #ifdef CONFIG_BLK_CGROUP struct request_queue *throttle_queue; #endif #ifdef CONFIG_UPROBES struct uprobe_task *utask; #endif #if defined(CONFIG_BCACHE) || defined(CONFIG_BCACHE_MODULE) unsigned int sequential_io; unsigned int sequential_io_avg; #endif #ifdef CONFIG_DEBUG_ATOMIC_SLEEP unsigned long task_state_change; #endif int pagefault_disabled; #ifdef CONFIG_MMU struct task_struct *oom_reaper_list; #endif #ifdef CONFIG_VMAP_STACK struct vm_struct *stack_vm_area; #endif #ifdef CONFIG_THREAD_INFO_IN_TASK /* A live task holds one reference: */ refcount_t stack_refcount; #endif #ifdef CONFIG_LIVEPATCH int patch_state; #endif #ifdef CONFIG_SECURITY /* Used by LSM modules for access restriction: */ void *security; #endif #ifdef CONFIG_GCC_PLUGIN_STACKLEAK unsigned long lowest_stack; unsigned long prev_lowest_stack; #endif /* * New fields for task_struct should be added above here, so that * they are included in the randomized portion of task_struct. */ randomized_struct_fields_end /* CPU-specific state of this task: */ struct thread_struct thread; /* * WARNING: on x86, 'thread_struct' contains a variable-sized * structure. It *MUST* be at the end of 'task_struct'. * * Do not put anything below here! */ };
-
linux内核学习(13)我们开始慢慢地往上爬...
2011-01-08 10:15:00这个题目取得好,好像底层离我们越来越远了,因为内核在一步一步脱壳,很快漂亮的形状就会展现在我们眼前,在这之前,我们得屏气凝神,静静地等待这一时刻的到来。进入真实内核的第一个文件是arch/x86/kernel/...这个题目取得好,好像底层离我们越来越远了,因为内核在一步一步脱壳,很快漂亮的形状就会展现在我们眼前,在这之前,我们得屏气凝神,静静地等待这一时刻的到来。进入真实内核的第一个文件是arch/x86/kernel/head_32.S。
/*
* 32-bit kernel entrypoint; only used by the boot CPU. On entry,
* %esi points to the real-mode code as a 32-bit pointer.
* CS and DS must be 4 GB flat segments, but we don't depend on
* any particular GDT layout, because we load our own as soon as we
* can.
*/
__HEAD
ENTRY(startup_32)
/* test KEEP_SEGMENTS flag to see if the bootloader is asking
us to not reload segments */
testb $(1<<6), BP_loadflags(%esi) # 这个标志见过,询问是否重新加载一遍段寄存器
jnz 2f
/*
* Set segments to known values.
*/
lgdt pa(boot_gdt_descr) # boot_gdt_descr在下面数据区中有设置,记载GDT表首地址
movl $(__BOOT_DS),%eax
movl %eax,%ds
movl %eax,%es
movl %eax,%fs
movl %eax,%gs
2:
/*
* Clear BSS first so that there are no surprises...
*/
# 将bss段清0
cld /*di,si ++*/
xorl %eax,%eax
movl $pa(__bss_start),%edi
movl $pa(__bss_stop),%ecx
subl %edi,%ecx
shrl $2,%ecx
rep ; stosl
/*
* Copy bootup parameters out of the way.
* Note: %esi still has the pointer to the real-mode data.
* With the kexec as boot loader, parameter segment might be loaded beyond
* kernel image and might not even be addressable by early boot page tables.
* (kexec on panic case). Hence copy out the parameters before initializing
* page tables.
*/
# 拷贝实模式中的boot_params结构体
movl $pa(boot_params),%edi
movl $(PARAM_SIZE/4),%ecx /*PARAM_SIZE ==struct boot_params*/
cld
rep
movsl /*ds:esi copy to es:edi*/
# 拷贝命令行参数到boot_command_line
# 得到命令行参数地址
movl pa(boot_params) + NEW_CL_POINTER,%esi /*boot_params->hdr.cmd_line_ptr*/
andl %esi,%esi /*test if point is null*/ # 检查指针是否为空
jz 1f # No comand line
movl $pa(boot_command_line),%edi /*in the init/main.c*/
movl $(COMMAND_LINE_SIZE/4),%ecx
rep
movsl
1:
# 不用管
#ifdef CONFIG_OLPC_OPENFIRMWARE /*firmware*/
/* save OFW's pgdir table for later use when calling into OFW */
movl %cr3, %eax
movl %eax, pa(olpc_ofw_pgd)
#endif
# 虚拟环境,直接飘过~
#ifdef CONFIG_PARAVIRT /*virtual environment*/
/* This is can only trip for a broken bootloader... */
cmpw $0x207, pa(boot_params + BP_version)
jb default_entry
/* Paravirt-compatible boot parameters. Look to see what architecture
we're booting under. */
movl pa(boot_params + BP_hardware_subarch), %eax
cmpl $num_subarch_entries, %eax
jae bad_subarch /*if eax >= num_subarch_entries*/
movl pa(subarch_entries)(,%eax,4), %eax /*eax=subarch_entries+eax*4*/
subl $__PAGE_OFFSET, %eax
jmp *%eax
bad_subarch:
WEAK(lguest_entry)
WEAK(xen_entry)
/* Unknown implementation; there's really
nothing we can do at this point. */
ud2a
__INITDATA
subarch_entries:
.long default_entry /* normal x86/PC */ /*if hardware_subarch=0*/
.long lguest_entry /* lguest hypervisor */ /*0x00000001*/
.long xen_entry /* Xen hypervisor */ /*0x00000002*/
.long default_entry /* Moorestown MID */
num_subarch_entries = (. - subarch_entries) / 4
.previous
#endif /* CONFIG_PARAVIRT */
/*
* Initialize page tables. This creates a PDE and a set of page
* tables, which are located immediately beyond __brk_base. The variable
* _brk_end is set up to point to the first "safe" location.
* Mappings are created both at virtual address 0 (identity mapping)
* and PAGE_OFFSET for up to _end.
*
* Note that the stack is not yet set up!
*/
# 这段非常关键,之前的保护模式是没有分页功能的,这段就是设置全局页目录和页表项
# 然后开启分页机制
default_entry:
# 如果启用了PAE,也就是物理地址扩展,变成64G,这里不用考虑
#ifdef CONFIG_X86_PAE /*physical address extend , 64G */
/*
* In PAE mode swapper_pg_dir is statically defined to contain enough
* entries to cover the VMSPLIT option (that is the top 1, 2 or 3
* entries). The identity mapping is handled by pointing two PGD
* entries to the first kernel PMD.
*
* Note the upper half of each PMD or PTE are always zero at
* this stage.
*/
#define KPMDS (((-__PAGE_OFFSET) >> 30) & 3) /* Number of kernel PMDs */
/*__PAGE_OFFSET = 0xc0000000*/
xorl %ebx,%ebx /* %ebx is kept at zero */
movl $pa(__brk_base), %edi
movl $pa(swapper_pg_pmd), %edx
movl $PTE_IDENT_ATTR, %eax
10:
leal PDE_IDENT_ATTR(%edi),%ecx /* Create PMD entry */
movl %ecx,(%edx) /* Store PMD entry */
/* Upper half already zero */
addl $8,%edx
movl $512,%ecx
11:
stosl
xchgl %eax,%ebx
stosl
xchgl %eax,%ebx
addl $0x1000,%eax
loop 11b
/*
* End condition: we must map up to the end + MAPPING_BEYOND_END.
*/
movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
cmpl %ebp,%eax
jb 10b
1:
addl $__PAGE_OFFSET, %edi
movl %edi, pa(_brk_end)
shrl $12, %eax
movl %eax, pa(max_pfn_mapped)
/* Do early initialization of the fixmap area */
movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax
movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8)
#else /* Not PAE */
# 如果没有启用PAE,那么线性地址为4G,一般都属于这里
/*4G physical address*/
# 这个很重要,内核的线性地址偏移
# 我们知道在liunx中,进程空间为0-3G,高1G是内核空间使用的
# 也就是3G之后
# 这里的这个偏移是相对于全局页目录的,全局页目录大小为4k,每项大小为4b
# 每项可以表示4M的线性范围
# 因此这个偏移3k刚好就是3G,3k/4*4M=3G。
page_pde_offset = (__PAGE_OFFSET >> 20); /*0xc00= 3k , PGD(3k)=3G*/
# 这里的这个__brk_base在文件vmlinux.lds.S中,链接后,表示页表的首地址
. = ALIGN(PAGE_SIZE);
.brk : AT(ADDR(.brk) - LOAD_OFFSET) {
__brk_base = .;
. += 64 * 1024; /* 64k alignment slop space */
*(.brk_reservation) /* areas brk users have reserved */
__brk_limit = .;
}
_end = .;
# 可以看到总大小为64k,也就是说可以设置线性地址64M
movl $pa(__brk_base), %edi /*__brk_base==PTD*/
movl $pa(swapper_pg_dir), %edx # 全局页目录地址
# 这个宏只是个属性而已
# 不管是全局页目录项还是页表项都是4B
# 4B中最后12位来表示属性
movl $PTE_IDENT_ATTR, %eax /*PTE_IDENT_ATTR= 0x00000067*/
10:
# 外循环是填充全局页目录项的
# edi为页表首地址
leal PDE_IDENT_ATTR(%edi),%ecx /* Create PDE entry */
# 将计算出的页目录项填充到全局页目录中
# edx表示全局页目录地址
movl %ecx,(%edx) /* Store identity PDE entry */
movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
# 填充下一个全局页目录项
addl $4,%edx
movl $1024, %ecx
11: /*fill 4k PTD*/
# 内循环填充页表
# edi为页表地址,eax为页表项
stosl /*es:edi= eax,edi++*/
addl $0x1000,%eax # 注意理解这里的0x1000,后12位为属性,前20位为页地址,4k对齐
loop 11b
/*
* End condition: we must map up to the end + MAPPING_BEYOND_END.
*/ /*_end-__brk_base = 64k*/
# 如果64k页表还没用完,那么继续,eax表示当前页表地址(当然包括了属性)
# 都忽略属性标志,则eax表示在__brk_base中的偏移/4
# 这里没有看懂MAPPING_BEYOND_END
# 这个在上面定义的,我计算了一下为0x0c400000
# 不过这里好像有些不对,不过看程序没有影响,就是判断是否还有页表可以设置
movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
cmpl %ebp,%eax
jb 10b /*if eax < ebp jump*/
# 将页表末尾的线性地址存入_brk_end变量中
addl $__PAGE_OFFSET, %edi
movl %edi, pa(_brk_end) /*_brk_end = _end=edi+__PAGE_OFFSET*/
# 这次映射了多少物理页面都在eax中,存好
shrl $12, %eax
movl %eax, pa(max_pfn_mapped) /*previous eax pages(4k) in physical address*/
/* Do early initialization of the fixmap area */
# 这里还加了一个全局页目录项,页表地址为swapper_pg_fixmap
# 放入了全局页目录项的最后一项
movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax
movl %eax,pa(swapper_pg_dir+0xffc) /*a 4k PTD in the end of PGT*/
#endif
jmp 3f
/*
* Non-boot CPU entry point; entered from trampoline.S
* We can't lgdt here, because lgdt itself uses a data segment, but
* we know the trampoline has already loaded the boot_gdt for us.
*
* If cpu hotplug is not supported then this code can go in init section
* which will be freed later
*/
__CPUINIT
# 多处理器平台
#ifdef CONFIG_SMP
ENTRY(startup_32_smp)
cld
movl $(__BOOT_DS),%eax
movl %eax,%ds
movl %eax,%es
movl %eax,%fs
movl %eax,%gs
#endif /* CONFIG_SMP */
3:
/*
* New page tables may be in 4Mbyte page mode and may
* be using the global pages.
*
* NOTE! If we are on a 486 we may have no cr4 at all!
* So we do not try to touch it unless we really have
* some bits in it to set. This won't work if the BSP
* implements cr4 but this AP does not -- very unlikely
* but be warned! The same applies to the pse feature
* if not equally supported. --macro
*
* NOTE! We have to correct for the fact that we're
* not yet offset PAGE_OFFSET..
*/
# 这里可以设置页面大小为4M,cr4的PSE如果置位的话
# 可以完全飘过~ 飘到下标6f
#define cr4_bits pa(mmu_cr4_features) /*the bit in PSE on the cr4*/
movl cr4_bits,%edx
andl %edx,%edx /*if set the bit then start 4M page*/
jz 6f /*assume don't set the PSE bit*/
movl %cr4,%eax # Turn on paging options (PSE,PAE,..)
orl %edx,%eax
movl %eax,%cr4
testb $X86_CR4_PAE, %al # check if PAE is enabled
jz 6f
/* Check if extended functions are implemented */
movl $0x80000000, %eax
cpuid
/* Value must be in the range 0x80000001 to 0x8000ffff */
subl $0x80000001, %eax
cmpl $(0x8000ffff-0x80000001), %eax
ja 6f
mov $0x80000001, %eax
cpuid
/* Execute Disable bit supported? */
btl $(X86_FEATURE_NX & 31), %edx
jnc 6f
/* Setup EFER (Extended Feature Enable Register) */
movl $MSR_EFER, %ecx
rdmsr
btsl $_EFER_NX, %eax
/* Make changes effective */
wrmsr
6:
/*
* Enable paging
*/
# 从这里开始我们将完全进入保护模式
# initial_page_table就是全局页目录的首地址
# 放入cr3
movl pa(initial_page_table), %eax
movl %eax,%cr3 /* set the page table pointer.. */
# 将cr0的分页机制打开
movl %cr0,%eax
orl $X86_CR0_PG,%eax /*X86_CR0_PG=0x80000000*/
movl %eax,%cr0 /* ..and set paging (PG) bit */
# 这里,我们调皮的跳一下,完全进入保护模式,呵呵!
ljmp $__BOOT_CS,$1f /* Clear prefetch and normalize %eip */
1: /*Now completely go to protected mode...*/
/* Set up the stack pointer */
# 设置好栈
lss stack_start,%esp
/*
* Initialize eflags. Some BIOS's leave bits like NT set. This would
* confuse the debugger if this code is traced.
* XXX - best to initialize before switching to protected mode.
*/
# 将标志寄存器清0
pushl $0
popfl
# 多处理器,直接飘过~
#ifdef CONFIG_SMP
cmpb $0, ready
jz 1f /* Initial CPU cleans BSS */
jmp checkCPUtype
1:
#endif /* CONFIG_SMP */
/*
* start system 32-bit setup. We need to re-do some of the things done
* in 16-bit mode for the "real" operations.
*/
# 设置IDT,中断向量表,这个非常重要
# 不过现在还没有什么的
call setup_idt
# 检查一下CPU类型
checkCPUtype:
movl $-1,X86_CPUID # -1 for no CPUID initially
/* check if it is 486 or 386. */
/*
* XXX - this does a lot of unnecessary setup. Alignment checks don't
* apply at our cpl of 0 and the stack ought to be aligned already, and
* we don't need to preserve eflags.
*/
# 这段可以完全跳过,直接进入is386下标继续看
movb $3,X86 # at least 386
pushfl # push EFLAGS
popl %eax # get EFLAGS
movl %eax,%ecx # save original EFLAGS
xorl $0x240000,%eax # flip AC and ID bits in EFLAGS
pushl %eax # copy to EFLAGS
popfl # set EFLAGS
pushfl # get new EFLAGS
popl %eax # put it in eax
xorl %ecx,%eax # change in flags
pushl %ecx # restore original EFLAGS
popfl
testl $0x40000,%eax # check if AC bit changed
je is386
movb $4,X86 # at least 486
testl $0x200000,%eax # check if ID bit changed
je is486
/* get vendor info */
xorl %eax,%eax # call CPUID with 0 -> return vendor ID
cpuid
movl %eax,X86_CPUID # save CPUID level
movl %ebx,X86_VENDOR_ID # lo 4 chars
movl %edx,X86_VENDOR_ID+4 # next 4 chars
movl %ecx,X86_VENDOR_ID+8 # last 4 chars
orl %eax,%eax # do we have processor info as well?
je is486
movl $1,%eax # Use the CPUID instruction to get CPU type
cpuid
movb %al,%cl # save reg for future use
andb $0x0f,%ah # mask processor family
movb %ah,X86
andb $0xf0,%al # mask model
shrb $4,%al
movb %al,X86_MODEL
andb $0x0f,%cl # mask mask revision
movb %cl,X86_MASK
movl %edx,X86_CAPABILITY
is486: movl $0x50022,%ecx # set AM, WP, NE and MP
jmp 2f
# 在往下看,无非就是加载了GDT、IDT
is386: movl $2,%ecx # set MP
2: movl %cr0,%eax
andl $0x80000011,%eax # Save PG,PE,ET
orl %ecx,%eax
movl %eax,%cr0
call check_x87
lgdt early_gdt_descr
lidt idt_descr
ljmp $(__KERNEL_CS),$1f
1: movl $(__KERNEL_DS),%eax # reload all the segment registers
movl %eax,%ss # after changing gdt.
movl $(__USER_DS),%eax # DS/ES contains default USER segment
movl %eax,%ds
movl %eax,%es
movl $(__KERNEL_PERCPU), %eax
movl %eax,%fs # set this cpu's percpu
# 栈保护,飘过~
#ifdef CONFIG_CC_STACKPROTECTOR
/*
* The linker can't handle this by relocation. Manually set
* base address in stack canary segment descriptor.
*/
cmpb $0,ready
jne 1f
movl $gdt_page,%eax
movl $stack_canary,%ecx
movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
shrl $16, %ecx
movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
movb %ch, 8 * GDT_ENTRY_STACK_CANARY + 7(%eax)
1:
#endif
# 飘到这里了~
movl $(__KERNEL_STACK_CANARY),%eax
movl %eax,%gs
xorl %eax,%eax # Clear LDT
lldt %ax
cld # gcc2 wants the direction flag cleared at all times
pushl $0 # fake return address for unwinder
# 又是多处理器,继续飘~
#ifdef CONFIG_SMP
movb ready, %cl
movb $1, ready
cmpb $0,%cl # the first CPU calls start_kernel
je 1f
movl (stack_start), %esp
1:
#endif /* CONFIG_SMP */
# 关键点了,即将进入C代码了,哈哈!
jmp *(initial_code)
/*
* We depend on ET to be correct. This checks for 287/387.
*/
# is386里的调用,居然还要检查一下x87
check_x87:
movb $0,X86_HARD_MATH
clts
fninit
fstsw %ax
cmpb $0,%al
je 1f
movl %cr0,%eax /* no coprocessor: have to set bits */
xorl $4,%eax /* set EM */
movl %eax,%cr0
ret
ALIGN
1: movb $1,X86_HARD_MATH
.byte 0xDB,0xE4 /* fsetpm for 287, ignored by 387 */
ret
/*
* setup_idt
*
* sets up a idt with 256 entries pointing to
* ignore_int, interrupt gates. It doesn't actually load
* idt - that can be done only after paging has been enabled
* and the kernel moved to PAGE_OFFSET. Interrupts
* are enabled elsewhere, when we can be relatively
* sure everything is ok.
*
* Warning: %esi is live across this function.
*/
# 这就是设置IDT表了
setup_idt:
# 默认中断处理程序
lea ignore_int,%edx
# 注意得用代码段选择子,而且肯定是内核代码段
movl $(__KERNEL_CS << 16),%eax /*set selector in the GDT*/
movw %dx,%ax /* selector = 0x0010 = cs */
movw $0x8E00,%dx /* interrupt gate - dpl=0, present */
lea idt_table,%edi # idt_table为idt表的首地址
mov $256,%ecx # 总共设置256项
rp_sidt:
movl %eax,(%edi)
movl %edx,4(%edi)
addl $8,%edi
dec %ecx
jne rp_sidt
# 下面先设置几个后面可能会用的着的中断向量
.macro set_early_handler handler,trapno
lea /handler,%edx
movl $(__KERNEL_CS << 16),%eax
movw %dx,%ax
movw $0x8E00,%dx /* interrupt gate - dpl=0, present */
lea idt_table,%edi
movl %eax,8*/trapno(%edi)
movl %edx,8*/trapno+4(%edi)
.endm
# 宏描述,类似C里的define
set_early_handler handler=early_divide_err,trapno=0
set_early_handler handler=early_illegal_opcode,trapno=6
set_early_handler handler=early_protection_fault,trapno=13
set_early_handler handler=early_page_fault,trapno=14
ret
# 对应的中断处理程序
early_divide_err:
xor %edx,%edx
pushl $0 /* fake errcode */
jmp early_fault
early_illegal_opcode:
movl $6,%edx
pushl $0 /* fake errcode */
jmp early_fault
early_protection_fault:
movl $13,%edx
jmp early_fault
early_page_fault:
movl $14,%edx
jmp early_fault
early_fault:
cld /*di,si ++*/
#ifdef CONFIG_PRINTK
pusha
movl $(__KERNEL_DS),%eax
movl %eax,%ds
movl %eax,%es
cmpl $2,early_recursion_flag
je hlt_loop
incl early_recursion_flag
movl %cr2,%eax
pushl %eax
pushl %edx /* trapno */
pushl $fault_msg
call printk
#endif
call dump_stack
hlt_loop:
hlt
jmp hlt_loop
/* This is the default interrupt "handler" :-) */
ALIGN
# 这就是那个默认中断处理程序
ignore_int:
cld
#ifdef CONFIG_PRINTK
pushl %eax
pushl %ecx
pushl %edx
pushl %es
pushl %ds
movl $(__KERNEL_DS),%eax
movl %eax,%ds
movl %eax,%es
cmpl $2,early_recursion_flag
je hlt_loop
incl early_recursion_flag
pushl 16(%esp)
pushl 24(%esp)
pushl 32(%esp)
pushl 40(%esp)
pushl $int_msg
call printk
call dump_stack
addl $(5*4),%esp
popl %ds
popl %es
popl %edx
popl %ecx
popl %eax
#endif
iret
__REFDATA
.align 4
# 看到没,之前那个跳转就是这里设置的这个,my name is "i386_start_kernel"。
ENTRY(initial_code)
.long i386_start_kernel
ENTRY(initial_page_table)
.long pa(swapper_pg_dir)
/*
* BSS section
*/
# bss段
__PAGE_ALIGNED_BSS
.align PAGE_SIZE_asm
#ifdef CONFIG_X86_PAE
swapper_pg_pmd:
.fill 1024*KPMDS,4,0
#else
# 这就是那个全局页目录共4k,1024项,每项4B
ENTRY(swapper_pg_dir) /*a page for 4k*/
.fill 1024,4,0
#endif
# 这个是设置的最后那个全局页目录项的页表地址
swapper_pg_fixmap: /*a page for 4k*/
.fill 1024,4,0
#ifdef CONFIG_X86_TRAMPOLINE
ENTRY(trampoline_pg_dir)
.fill 1024,4,0
#endif
ENTRY(empty_zero_page)
.fill 4096,1,0
/*
* This starts the data section.
*/
# 注意这里我们假设没有开启PAE物理地址扩展的
#ifdef CONFIG_X86_PAE /*if physical address extend 64G*/
__PAGE_ALIGNED_DATA
/* Page-aligned for the benefit of paravirt? */
.align PAGE_SIZE_asm
ENTRY(swapper_pg_dir)
.long pa(swapper_pg_pmd+PGD_IDENT_ATTR),0 /* low identity map */
# if KPMDS == 3
.long pa(swapper_pg_pmd+PGD_IDENT_ATTR),0
.long pa(swapper_pg_pmd+PGD_IDENT_ATTR+0x1000),0
.long pa(swapper_pg_pmd+PGD_IDENT_ATTR+0x2000),0
# elif KPMDS == 2
.long 0,0
.long pa(swapper_pg_pmd+PGD_IDENT_ATTR),0
.long pa(swapper_pg_pmd+PGD_IDENT_ATTR+0x1000),0
# elif KPMDS == 1
.long 0,0
.long 0,0
.long pa(swapper_pg_pmd+PGD_IDENT_ATTR),0
# else
# error "Kernel PMDs should be 1, 2 or 3"
# endif
.align PAGE_SIZE_asm /* needs to be page-sized too */
#endif
.data
# 栈的存放处
ENTRY(stack_start)
.long init_thread_union+THREAD_SIZE
.long __BOOT_DS
ready: .byte 0
early_recursion_flag:
.long 0
int_msg:
.asciz "Unknown interrupt or fault at: %p %p %p/n"
fault_msg:
/* fault info: */
.ascii "BUG: Int %d: CR2 %p/n"
/* pusha regs: */
.ascii " EDI %p ESI %p EBP %p ESP %p/n"
.ascii " EBX %p EDX %p ECX %p EAX %p/n"
/* fault frame: */
.ascii " err %p EIP %p CS %p flg %p/n"
.ascii "Stack: %p %p %p %p %p %p %p %p/n"
.ascii " %p %p %p %p %p %p %p %p/n"
.asciz " %p %p %p %p %p %p %p %p/n"
# 这个我们好像不是感兴趣
#include "../../x86/xen/xen-head.S"
/*
* The IDT and GDT 'descriptors' are a strange 48-bit object
* only used by the lidt and lgdt instructions. They are not
* like usual segment descriptors - they consist of a 16-bit
* segment size, and 32-bit linear address value:
*/
.globl boot_gdt_descr # 很久以前设置的GDT了
.globl idt_descr # IDT中断向量表描述符
ALIGN
# early boot GDT descriptor (must use 1:1 address mapping)
.word 0 # 32 bit align gdt_desc.address
boot_gdt_descr:
.word __BOOT_DS+7
.long boot_gdt - __PAGE_OFFSET
.word 0 # 32-bit align idt_desc.address
idt_descr:
.word IDT_ENTRIES*8-1 # idt contains 256 entries
.long idt_table
# boot GDT descriptor (later on used by CPU#0):
.word 0 # 32 bit align gdt_desc.address
ENTRY(early_gdt_descr)
.word GDT_ENTRIES*8-1
.long gdt_page /* Overwritten for secondary CPUs */
/*
* The boot_gdt must mirror the equivalent in setup.S and is
* used only for booting.
*/
.align L1_CACHE_BYTES
ENTRY(boot_gdt)
.fill GDT_ENTRY_BOOT_CS,8,0
.quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
.quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
我的妈呀!看看这段程序,长得跟什么似的,其实真正我们关心的也没几个,其实即使是我们关心的,也不会成为我们的后面的焦点,因为这些还太底层了,我们不需要,呵呵!还得往上爬点,到了,我们自然就会流露处欣喜的表情。如果你也认真分析了,而且一直坚持到现在,估计后面的分析会比较好了,至少说遇到不懂的问题,你不会放弃,当然这里指的“不懂的问题”是我们所关心的。 -
Linux-内核-学习笔记(13):移植三星官方内核
2020-04-05 16:24:46Linux-内核-学习笔记(13):移植三星官方内核 一、移植前的准备 当拿到源代码时,首先要在window下利用SourceInsight创建一个工程,并将uboot源代码加载到SI中,方便修改和查看函数调用。 项目->新项目->设置... -
linux内核学习笔记——x86分段
2013-06-23 10:12:00以前从来不做笔记,好多东西学了忘,忘了学,今天开始记录下来。 X86的分段 x86微处理器有两种工作模式,实模式和保护模式。... 16位的高13位是段描述的索引号(段描述符马上就讨论),TI位指示是全... -
linux内核学习(13)我们开始慢慢地往上爬...(上)
2011-01-07 17:23:00这个题目取得好,好像底层离我们越来越远了,因为内核在一步一步脱壳,很快漂亮的形状就会展现在我们眼前,在这之前,我们得屏气凝神,静静地等待这一时刻的到来。进入真实内核的第一个文件是arch/x86/kernel/head_... -
linux内核学习(13)我们开始慢慢地往上爬...(下)
2011-01-07 17:29:00set_early_handler handler=early_protection_fault,trapno=13 set_early_handler handler=early_page_fault,trapno=14 ret # 对应的中断处理程序 early_divide_err: xor %edx,%edx pushl ... -
24小时学通Linux内核之构建Linux内核
2015-01-27 19:05:00所以告诫各位技术男敲醒警钟,不要想我看齐,不然就只能和代码为伴了的~~话说没了腊八粥但还是有代码,还有各位读者的支持呀,所以得继续写下去,静下心来,完成Linux内核的学习,坚持,加油~13; 到目前为止,... -
我的内核学习笔记13:x86平台linux系统重启流程跟踪
2017-01-12 19:16:04一直以来,笔者只知道重启Linux系统性使用reboot,但对其过程却无所知,涉及到哪些知识点也无概念。本文就跟踪一下重启的流程,平台为Intel x86,Linux内核版本为3.17。 -
嵌入式LINUX驱动学习之13内核数据结构(链表)
2020-08-29 13:29:15嵌入式LINUX驱动学习之13内核数据结构(链表)一、头文件、函数及说明 一、头文件、函数及说明 /* 1、初始化链表函数 :INIT_LIST_HEAD() */ static inline void INIT_LIST_HEAD(struct list_head *list) { ... -
linux内核学习(21)设备模型之第二层device_register
2013-01-02 15:04:11linux内核学习(21)设备模型之第二层device_register 2010-12-30 13:05:30| 分类: Linux_内核|字号 订阅 这篇文章将那个3个注册函数说说,把整个设备模型框架搭建起来,当然,是重点部分了... -
linux内核学习之likely()和unlikely()
2010-01-05 12:53:00参考资料 : linux内核设计和实现 P13 likely()和unlikely()是内核编译时用于优化 if 判断语句的宏likely()代表优化unlikely()代表不优化一般为了效率 由程序员自己判断if语句里面的内容是否要优化,显然... -
龟速linux内核学习之旅(二)
2010-11-07 20:47:00难点一是对硬盘的结构和术语没有一个概念,二是从硬盘加载内核镜像的代码段逻辑较为复杂,三是对汇编指令的作用还不是很清楚,四是对BIOS中断的不熟悉,主要是INT10和INT13号中断。最后还是在下班前把它搞懂了。 ... -
《Linux内核设计与实现》学习笔记
2020-08-01 15:01:59《Linux内核设计与实现》学习笔记第三章 进程管理第四章 进程调度第五章 系统调用第六章 内核数据结构第七章 中断和中断处理第十章 内核同步方法第11章 定时器和时间管理第12章 内存管理第13章 虚拟文件系统第14章 ... -
linux内核启动过程学习总结
2016-04-01 15:25:10通用寄存器的作用r0 :在函数开始时使用r1 :存放堆栈指针,相当于ia32架构中的esp寄存器r2 :存放当前进程的描述符的地址r3 :存放第一个参数和返回地址r4-r10 :存放...Linux启动过程描述 第一步:使用Boot ... -
Linux内核学习笔记五——中断推后处理机制
2013-08-20 17:14:25转自 http://www.cnblogs.com/bastard/archive/2012/09/13/2683771.html -
《Linux内核设计的艺术》学习笔记(二)INT 0x13中断
2019-09-24 13:55:35参考资料: 1. 《IBM-PC汇编语言程序设计》 2.... 3.http://www.ctyme.com/intr/int-13.htm ◆ 磁盘复位: 功能号:AH = 00H 调用参数:DL = 驱动器号 (00H~7FH为软盘;8... -
二三层转发原理及过程_推荐一本深入linux内核架构与底层原理,内核学习必备...
2020-11-18 16:41:55本书共13章,其中第1~3章是总览,第4~13章是分领域阐述。第1~3章总体介绍Linux的基本知识;第4章以Linux系统的启动开始深入叙述;第5章是Linux系统运行中使用者*常接触到的进程概念,重点介绍进程的原理;第6章是... -
Linux内核测试学习(一):总论
2011-04-26 17:19:45http://news.51tester.cn/www/13/2010-01/7011.html 转载于:https://blog.51cto.com/liubinwei/554111 -
_Linux内核的整体架构
2020-11-04 02:08:58转载自蜗窝科技Linux内核的整体架构www.wowotech.net作者:wowo发布于:2014-2-21 13:23 分类:Linux内核分析0. 转载者说在前面的话转载目的:能够让更多的小伙伴发现优质的文章对原文进行重新排版梳理替换,让... -
Linux 2.4.30 内核文件系统学习
2009-12-29 15:02:30根据以前学习内核源码的经验,在学习文件系统实现之前,我大概定了个目标: 1、 建立一个清晰的全局概念。为将来需要研究代码细节打下坚实基础。 2、 只研究虚拟文件系统 VFS 的实现,不研究... -
linux 哪个进程在使用串口_Linux内核的整体架构
2020-12-13 13:41:45转载自蜗窝科技Linux内核的整体架构www.wowotech.net作者:wowo发布于:2014-2-21 13:23 分类:Linux内核分析0. 转载者说在前面的话转载目的:能够让更多的小伙伴发现优质的文章对原文进行重新排版梳理替换,让... -
13、IMX6ULL学习笔记-linux设备树之内核定时器实验
2020-04-08 10:06:05一、所用函数如下 1、 void init_timer(struct timer_list *timer) 函数->负责初始化timer_list类型变量 2、 void add_timer(struct...用于向Linux内核注册定时器 3、 int del_timer(struct timer_list * timer) ... -
Linux内核源代码情景分析学习简记1
2010-12-28 22:31:00全局的段描述表寄存器中用作GDT下标的有13位(其它,0和1位表示特权级别,2位表示使用的是全局还是局部描述表),共可以有8192项,除去第1项永远是0,第2、3项表示内核的代码段和数据段,4、5项表示当前进程的代码段... -
linux ns级定时器_linux学习13,一文弄懂内核的“绝对公平调度”机制是如何设计的...
2020-12-25 15:34:23前面两节介绍了一下 linux 中进程的资源,本节再来学习下 linux 中 cfs 进程的调度。linux 进程的时间记账上一节说到为了尽量让每个进程都有相对公平的机会运行,linux 在设计进程调度时,提出了 cpu使用比的概念,... -
linux设备驱动开发详解_linux内核字符设备驱动到platform驱动架构改造过程
2020-11-28 18:44:43关注”技术简说“(13站同名),带你由浅入深学习linux内核源码。linux内核开发100讲免费教程,每周二、四晚9点准时更新,敬请收看。进我主页点”视频“栏目即可观看。改造前的字符设备驱动源码:#include #include #... -
20169207《Linux内核原理与分析》第九周作业
2016-11-15 17:39:00阅读学习教材「Linux内核设计与实现 (Linux Kernel Development)」第教材第13,14章。二是学习MOOC「Linux内核分析」第七讲「Linux内核的实质和Linux系统的一般执行过程」,并完成实验楼上配套实验。 然后我们开始这...
-
视频转换器WonderFox便携注册版 UI界面好看.rar
-
金三银四:2021阿里巴巴天猫-春招来袭
-
统计数组中元素的个数
-
利用社交媒体创造销售奇迹的十大经典案例.jpg
-
第四章 C语言 PTA数组——作业-答案.html
-
零基础极简以太坊智能合约开发环境搭建并开发部署
-
安装mysql 和hive
-
青蛙跳台阶问题-2
-
MySQL 高可用工具 DRBD 实战部署详解
-
【考研初试】安徽建筑大学702公共管理学考研真题库资料
-
用微服务spring cloud架构打造物联网云平台
-
2014阿里巴巴校园招聘数据分析师职位笔试题目(回忆版).pdf
-
常用端口号
-
物联网基础篇:快速玩转MQTT
-
InnoDB 是如何存储数据的(数据目录 -> 聚簇索引 -> 页 -> 行格式 -> 独立表空间 -> 区,组,段 -> 系统表空间)
-
[蓝桥杯] 填算式 python解法
-
2021-02-28
-
读书笔记:七种单例模式
-
第三章 C语言 PTA循环控制——作业-答案.html
-
13款手机浏览器分析(Android).pptx