Linux菜鸟的内核学习笔记
- 格式:pdf
- 大小:206.64 KB
- 文档页数:8
Linux系统管理员真实ID用作记账,有效ID用作确定访问权限。
ls –hl深入理解Linux内核笔记_exit()函数的作用最为简单:直接使进程停止运行,清除其使用的内存空间,并销毁其在内核中的各种数据结构;exit() 函数则在这些基础上作了一些包装,在执行退出之前加了若干道工序,也是因为这个原因,有些人认为exit已经不能算是纯粹的系统调用。
exit()函数与_exit()函数最大的区别就在于exit()函数在调用exit系统调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,就是"清理I/O缓冲"。
一、内存寻址二、进程三、中断中断和进程切换有一个明显的差异:由中断或异常处理程序执行的代码不是一个进程(一个内核控制路径)。
异常由专门的异常处理程序处理UDP是不可靠的,它不必保存应用程序的数据拷贝,因此无需一个真正的发送缓冲区Linux情景源代码分析一、为什么分段:算术逻辑单元是16位,而地址总线是20位,所以要分段。
二、内存管理Linux采用buddy系统来解决页外碎片,采用slab 分配器来解决页内碎片。
同时Linux采用了Node,Zone和page三级结构来描述物理内存的。
buddy系统是建立在这三级结构之上的。
slab 同时又在buddy系统之上管理着物理页之内的内存请求(小内存分配)。
Linux中,页的大小默认是4k其中zone dma 的地址范围是0~16M,是用来ISA DMA的内存区。
当然,这个zone也可以存放内核数据和用户数据。
zone normal 的地址范围是16~896M,可以存放内核数据和用户数据。
zone highmem 的地址范围是高于896M 的物理地址空间,只能用来存放用户数据。
注意,虽然在x86平台下,是如此划分的,但是在其他平台,zone dma 和highmem可能都是空的,所有的物理页框都划分在zone normal。
【读书笔记】Linux系统管理初学者指南读书笔记1——第1-2章本博客记录⼀下《Linux系统管理初学者指南》这本书的读书笔记,最近由于想做⼀些关于嵌⼊式的项⽬,所以需要对Linux系统进⾏学习,正好之前买过这本书,内容还可以,能作为⼊门阅读第1章了解并安装Linux系统Linux系统的发展与特点Linux的发展历史Multics计划UNIX系统:1970年为UNIX元年,1970年1⽉1⽇0:00在UNIX系统中作为计算机时间的起点类UNIX操作系统MINIX系统Linux系统:Linus系统内核:负责完成操作系统基本功能的程序,主要作⽤是负责统⼀管理计算机中的硬件资源,提供⽤户擦操作界⾯,提供应⽤程序的运⾏环境Linux系统中的内核程序称为KernelGNU计划:世界知名的⾃由软件项⽬,决定了Linux系统⾃由、开放的属性Kernel作为Linux系统的核⼼,只能实现系统的基本功能,⽽⼀个完整的Linux系统应该包括Kernel和应⽤程序两部分,⽽⽆论是Kernel还是Linux,其中的绝⼤部分应⽤程序属于GNU计划,遵守GNU计划中的GPL或LGPL协议Linux的发⾏版本:作为⽤户使⽤的都是运⾏在内核之上的各种应⽤程序,很多公司或组织在Linux内核的基础上添加了各种管理⼯具和应⽤软件,构成了⼀个完整的操作系统将系统内核和应⽤软件封装在⼀起的操作系统成为Linux发⾏版,⼀般平时接触和使⽤的Linux系统都是Linux的发⾏版RedHat LinuxFedoraRHEL(RedHat Enterprise Linux)CentOS(Community Enterprise Operation System,社区企业操作系统)DebianUbuntuKali LinuxSUSELinux系统较为⼴泛的应⽤是⽹络服务器以及各种嵌⼊式系统在VMware Workstation安装虚拟机设置虚拟机的⽹络环境:桥接(bridged)模式:虚拟机像是⼀个独⽴主机,与物理主机是同等地位,可以通过物理主机的⽹卡访问外⽹,外部⽹络中的计算机也可以访问此虚拟机,桥接模式对应的虚拟⽹络名称为VMnet0仅主机(host-only)模式:仅主机模式对应的是虚拟⽹络VMnet1,这是⼀个独⽴的虚拟⽹络,与物理⽹络之间是隔离开的,所有设为仅主机模式的虚拟机之间以及虚拟机与物理主机之间可以相互通信,但它们与外部⽹络中的主机⽆法通信NAT(⽹络地址转换)模式:NAT模式对应的虚拟⽹络是VMnet8,物理主机就像⼀台⽀持NAT功能的代理服务器,⽽虚拟机就像NAT的客户端⼀样,虚拟机可以使⽤物理主机的IP地址直接访问外部⽹络中的计算机,但由于NAT技术的特点,外部⽹络中的计算机⽆法主动与NAT模式下的虚拟机进⾏通信Linux系统的基本操作⼀个完整的Linux系统是由Kernel和各种应⽤软件组成的,Linux系统的桌⾯环境(X Window)也是由应⽤软件来提供的,负责X Window桌⾯环境的软件主要有两个:GNOME和KDEX Window只是Linux系统的⼀个应⽤软件,并没有集成到Linux的内核中,因此⽤户可以根据需要选择是否运⾏图形界⾯ShellLinux系统的字符界⾯称为Shell(Shell本来是指系统的⽤户界⾯,为⽤户与系统内核进⾏交互操作提供了⼀种接⼝,图形界⾯和字符界⾯都属于Shell,图形界⾯的Shell称为GUI,字符界⾯的Shell称为CLI,由于Linux系统的操作以字符界⾯为主,因此Shell通常专指CLI)Shell是Linux系统中的⼀个应⽤程序,将⽤户输⼊的命令解释成系统内核能理解的语⾔,命令执⾏后再将结果以⽤户可以理解的⽅式显⽰出来Linux系统中负责提供Shell功能的软件有很多,⽐如sh、Csh、Zsh和Bash等,CentOS系统中默认使⽤的是Bash启动ShellLinux是⼀个多⽤户操作系统,可以同时接受多个⽤户登陆,⽽且还允许同⼀个⽤户从不同的终端进⾏多次登陆,在使⽤安装Linux系统的计算机时,虽然⽤户⾯对的也是⼀个物理终端设备,但可以在这⼀个物理终端上通过虚拟终端打开多个互不⼲扰,独⽴⼯作的页⾯Linux中提供的虚拟终端默认有6个,其中第1个是图形界⾯,第2-6个则是字符界⾯,可以通过Ctrl+Alt+F1-F6在不同的虚拟终端进⾏切换,同时在字符界⾯下执⾏startx命令也可以进⼊图形界⾯(在Ubuntu中Ctrl+Alt+F1-F6代表不同的虚拟终端,⽽Ctrl+Alt+F7则是返回图形界⾯,书中描述的是CentOS)虚拟终端的缩写为tty,执⾏tty命令就可显⽰⽤户⽬前所在的终端编号除了虚拟终端外,还有⼀种启动Shell的⽅式称为伪终端,缩写为pts,在图形界⾯中,右键打开终端即可弹出⼀个运⾏在图形环境中的字符界⾯窗⼝,这就是⼀个伪终端,在其中执⾏tty命令,其中的结果为/dev/pts/0,表⽰这是系统启动的第⼀个伪终端(伪终端的编号从0开始)启动Shell后,可以看到类似于zyh@zyh-virtual-machine:~$的命令提⽰符,命令提⽰符是Linux字符界⾯的标志zyh:表⽰当前登录的⽤户账户zyh-virtual-machine:表⽰本机的主机名是⼀个特殊符号,泛指⽤户的家⽬录):表⽰⽤户当前所在的位置,即⼯作⽬录($:表⽰当前登录的是普通⽤户,如果是管理员⽤户则变为#可以通过Ctrl+C键发出中断信号来中断命令的运⾏Shell命令格式Shell命令由命令名、选项和参数共3个部分组成:命令名 [选项] [参数](命令名、选项和参数之间必须⽤空格分隔)命令名:描述命令功能的英⽂单词或缩写选项:调节命令的具体功能选项通常以-开头,当有多个选项时,可以只使⽤⼀个-符号部分选项以--开头,这些选项通常是⼀个单词或词组少数命令的选项不需要-符号参数:命令的处理对象,可以是⽂件、⽬录或⽤户账号等内容在Shell中,⼀⾏可以输⼊多条命令,命令之间⽤分号分隔,如果在⼀⾏命令后加上****符号,就表⽰另起⼀⾏继续输⼊通过上下⽅向键可以找出曾经执⾏过的命令关机与重启命令关机:poweroff重启:rebootshutdown:既可以⽤来关机⼜可以⽤来重启⽴即关闭系统:shutdown -h now⽴即重启系统:shutdown -r now15分钟后关闭系统:shutdown -h +1510分钟后重启系统,并将信息发给登陆到本机中的各⽤户:shutdown -r +10 'The system will be rebooted!!'对于延时运⾏的关机重启操作,可以⽤shutdown -c命令或Ctrl+C组合键取消相⽐于poweroff和reboot命令,shutdown命令在执⾏前会给所有登陆⽤户发送警告信息,因次更加安全第2章⽂件和⽬录管理本章主要介绍⼀些常⽤的Linux系统的⽂件和⽬录管理类命令Linux设计思想⼀切皆⽂件:在Linux系统中,不只数据以⽂件的形式存在,其他资源(包括硬件设备)也被组织为⽂件的形式,例如硬盘以及硬盘中的每个分区在Linux中都被视为⼀个⽂件整个系统由众多的⼩程序组成:整个Linux系统是由众多单⼀功能的⼩程序组成的,每个⼩程序只负责实现某⼀项具体功能,⽐如Linux的绝⼤多数命令,其实各⾃有⼀个相应的⼩程序,如果需要完成⼀项复杂任务,只需将相应的命令组合在⼀起即可尽量避免与⽤户交互:在对系统进⾏管理操作时,要尽量避免⽤户的参与,因为Linux系统主要⽤作服务器的操作系统,在服务器上执⾏的操作最好通过编写脚本程序完成,从⽽⾃动化地完成某些功能使⽤纯⽂本⽂件保存配置信息:如果需要改动系统或程序中的某项功能,只需编辑相应的配置⽂件Linux系统中的⽂件和⽬录Linux的⽬录结构在Windows系统中,为每个磁盘分区分配⼀个盘符,在资源管理器中通过盘符就可以访问相应的分区,每个分区使⽤独⽴的⽂件系统,每个分区都有⼀个根⽬录,如C:\、D:\等Linux系统的绝⼤多数发⾏版遵循FHS(Filesystem Hierarchy Standard)⽂件系统层次化标准,采⽤统⼀的⽬录结构,按照FHS标准,整个Linux⽂件系统是⼀个倒置的树形结构,系统中只存在⼀个根⽬录,所有的⽬录和⽂件都在同⼀个根⽬录下在Linux系统中定位⽂件或⽬录时,使⽤/进⾏分隔(区别于Windows的),在整个树形⽬录结构中,使⽤/表⽰根⽬录,根⽬录就是Linux⽂件系统的起点,在根⽬录下按照⽤途不同划分有很多⼦⽬录下⾯是遵循FHS标准的典型⽬录结构:以下是CentOS 7中⼀些常见的⽬录及其作⽤:/boot:存放Linux系统启动所必需的⽂件,Kernel被存放在这个⽬录中/etc:存放Linux系统和各种程序的配置⽂件,Linux中的很多操作和配置都是通过修改配置⽂件实现的(类似于Windows系统中的注册表)/dev:存放Linux系统中的硬盘、光驱和⿏标等硬件设备⽂件/bin:存放Linux系统中常⽤的基本命令,任何⽤户都有权限执⾏/sbin:存放Linux系统基本的管理命令,只有管理员权限才可以执⾏/usr:软件的默认安装位置,类似于Windows系统中的Program Files⽬录/home:普通⽤户家⽬录(也称为主⽬录)/root:超级⽤户root的家⽬录/mnt:⼀般是空的,⽤来临时挂载存储设备/media:⽤于系统⾃动挂载可移动存储设备/tmp:临时⽬录,⽤于存放系统或程序运⾏时产⽣的⼀些临时⽂件,可供所有⽤户执⾏写⼊操作pwd(print working directory)命令:⽤于显⽰⽤户当前所在的⼯作⽬录路径/:是Linux系统的根⽬录,也是其他所有⽬录的起点/root:根⽬录下的⼀个⼦⽬录,⽤途是作为管理员root⽤户的家⽬录,家⽬录主要⽤于存放⽤户的各种数据Linux系统中普通⽤户的家⽬录默认集中存放在/home⽬录中,以⽤户名命名cd(change directory)命令:⽤于切换⼯作⽬录单纯执⾏cd命令,将默认返回到当前⽤户的家⽬录~表⽰当前⽤户的家⽬录cd -可以在最近⼯作过的两个⽬录之间进⾏切换关于路径的⼀些基本概念:绝对路径:以根⽬录/作为起点,可以准确地表⽰⼀个⽂件或⽬录所在的位置相对路径:以当前的⽬录为起点,在开头不使⽤/符号,输⼊的时候更加简单.:表⽰当前⽬录..:表⽰当前⽬录的上⼀级⽬录⽂件和⽬录操作命令ls(list)命令:以列表的⽅式显⽰⼀个⽬录中包含的内容ls显⽰结果以不同的颜⾊来区分⽂件类别,蓝⾊代表⽬录,灰⾊代表普通⽂件,绿⾊代表可执⾏⽂件,红⾊代表压缩⽂件,浅蓝⾊代表链接⽂件touch命令:⽤于创建空⽂件或修改已有⽂件的时间戳mkdir(make directory)命令:⽤于创建新的空⽬录rmdir(remove directory)命令:可以删除指定的⽬录(必须是空⽬录,没有任何⽂件和⼦⽬录)cp(copy)命令:复制⽂件或⽬录cp [选项] 源⽂件或⽬录⽬标⽂件或⽬录mv(move)命令:⽤于移动⽂件或对⽂件重命名mv [选项] 源⽂件或⽬录⽬标⽂件或⽬录rm(remove)命令:删除⽂件或⽬录-f选项:强制删除,⽆须⽤户确认-r选项:递归删除整个⽬录⽂件内容操作命令cat(concatenate)命令:⽤于查看⽂本⽂件内容more命令和less命令:分页显⽰⽂件内容head命令和tail命令:显⽰⽂件开头或末尾的部分内容wc命令:⽤于统计⽂件中的⾏数、单词数和字节数echo命令:⽤于输出指定的字符串或变量的值在变量名称加前导符号$,可以引⽤⼀个变量的值grep命令:⽤于在⽂本⽂件中查找并显⽰包含指定字符串的所有⾏diff命令:⽤于⽐较多个⽂本⽂件之间的差异⽇期和时间的相关命令date命令:显⽰或修改⽇期和时间⽂件查找命令locate命令:简单快速的⽂件查找命令find命令:强⼤的⽂件查找命令,可以实现的⽂件的精确查找xargs命令:find辅助命令内部命令和外部命令Linux系统中的命令总体上分为内部命令和外部命令两⼤类内部命令:指集成在Shell中的命令,属于Shell中的⼀部分,只要Shell被执⾏,内部命令就⾃动载⼊内存,⽤户可以直接使⽤外部命令:很多的Linux命令独⽴于Shell之外,称为外部命令Linux系统中的绝⼤多数命令属于外部命令,⽽每个外部命令都对应了系统中的⼀个可执⾏的⼆进制程序⽂件,这些⼆进制程序⽂件主要存放在下列⽬录中:普通命令:/bin、/usr/bin和/usr/local/bin管理命令:/sbin、/usr/sbin和/usr/local/sbin其中,普通命令是指所有⽤户都可以执⾏的命令,管理命令则只有管理员root才有权限执⾏,Linux系统默认将外部命令程序⽂件的存放路径保存在⼀个名为PATH的环境变量中type命令:判断⼀个命令是内部命令还是外部命令which命令:查找外部命令所对应的的程序⽂件其他辅助命令ln命令:⽤于为⽂件或⽬录建⽴快捷⽅式(Linux系统中称为链接⽂件)alias命令:⽤于设置命令别名系统定义的别名命令:ll(相当于ls -l)unalias命令可以取消所设置的别名命令history命令:查看命令历史记录help命令:查看内部命令帮助信息对于外部命令,可以使⽤通⽤命令选项"--help"man命令:查看命令帮助⼿册clear命令:清除当前终端屏幕的内容ctrl+L也有相同的效果其他技巧通配符和扩展符在Linux系统中执⾏命令时,可以通过⼀些特殊符号对多个⽂件进⾏批量操作,从⽽提⾼操作效率通配符:通⽤的匹配信息的符号*:匹配任意数量的任意字符:在相应的位置上匹配单个字符[]:匹配指定范围内的任意单个字符,如[a,b,c]是表⽰a、b、c任意⼀个字符;[a-z]表⽰任意⼀个⼩写字母扩展符:在扩展符({})中可以包含⼀个以逗号分隔的列表,并将其⾃动展开为多个路径或⽂件名管道符|通过管道符|可以把多个简单的命令连接起来以实现更加复杂的功能,管道符⽤于连接左右两个命令,将|左边命令的执⾏结果作为|右边命令的输⼊命令的换⾏Linux命令⾏需要换⾏可以使⽤\,出现>时可以继续输⼊命令。
菜鸟学习笔记:1.查看各文件夹的大小:du -h --max-depth=22.双引号与单引号区别:双引号可以保留变量的内容,单引号仅能是一般的字符,不保留原来的变量的内容例如:name=xuweizhengecho $name -------结果:xuweizhengecho “$name”----结果:xuweizhengecho ‘$name’----结果:$name3.反引号` `:将反引号内的linux命令先执行,然后将执行结果赋予变量,在linux中起命令替换的作用例如:n1=`ls -l score3.sh`echo $n1----结果:-rwxrwxrwx 1 actian users 180 3月13 17:51 score3.sha=”date” b=’date’c=`date’echo $a $b $c -----结果:date date 2017年03月16日星期四14:19:04 CST4.let命令是bash中用于计算的工具例如:let a=2+2 b=3+4echo $a $b ----结果:4 75.pwd命令显示当前目录的完整路径例如:/home/actian/poc/vxwzecho $(pwd)----结果为:/home/actian/poc/vxwzecho “$(pwd)”---结果同上6.比较运算符-eq == -ge >= -gt > -le <= -lt < -ne !=7.shell脚本变量shell脚本中所有变量都有字符串组成,不需要对变量声明,给变量赋值格式如下:变量名=值注:取变量值可以在变量名前加一个$美元符eg:a=”hello”echo $a 如果执行时提示权限不够需更改权限例如chmod 777 score3.sh 在执行8.ls命令文件列表例如:actian@node3:~/poc/vxwz> lsbaddir score2.sh score4.sh vw_2016.shods_all score3.sh test9.wc -l计算文件行数;wc -w计算文件单词数;wc -c计算文件中的字符数例如: vi n2.shqwertyuiopasdfghjklwc -l n2.sh--结果:3 n2.shwc -w n2.sh--结果:3 n2.shwc -c n2.sh--结果:22 n2.sh10.cp命令拷贝文件例如:cp 源文件目录目标文件位置actian@node3:~/poc/vxwz>cp n2.sh n22.sh10.mv重命名或移动文件例如:mv 就文件新文件名mv n22.sh n222.sh11.删除文件rm12.grep ‘party’ file:在文件中搜索字符串actian@node3:~/poc/vxwz> cat score3.sh#!/bin/shecho -n "please input a score:"read scoreif [ "$score" -lt 60 ]; thenecho "C"elif [ "$score" -lt 80 -a "$score" -ge 60 ]; thenecho "B"elseecho "A"fi例如:grep ‘echo’score3.shjieguo: echo -n "please input a score:"echo "C"echo "B"echo "A"13.cut -b colum file:指定欲显示的文件内容范围,并将它们输出到标准设备actian@node3:~/poc/vxwz> cat n2.shqwertyuiopasdfghjkl例如:输出每行第2个到第4个字符cut -b 2-4 n2.sh结果:weruiosdf-b:以字节为单位进行分割-c:字符为单位进行分割-d:自定义分隔符,默认为制表符-f:与-d 一起使用,指定显示哪个区域例如:提取每一行的第三个字节who:root pts/0 2017-03-16 11:07 (11.203.2.50)root pts/1 2017-03-16 13:35 (11.203.2.103)who | cut -b 3--结果:actian@node3:~/poc/vxwz> who | cut -b 3o14.sed命令是一个基本的查找替换程序,可以从标准输入(比如管道命令)读入文本,并将结果输入到标准输出(屏幕)该命令采用正则表达式进行搜索,注意不予shell中通配符相混淆。
鸟哥的linux私房菜(基础篇)学习笔记鸟哥的linux私房菜(基础篇)是一本非常好的Linux入门教材,它全面介绍了Linux 的基础知识,包括Linux的安装、文件系统、用户管理、进程管理、磁盘管理、文件编辑器、Shell编程以及Linux网络等方面。
本文将简单介绍一些我学习这本书时的笔记和心得,以期为Linux新手提供一些帮助。
1. 操作系统和内核操作系统是由内核和外壳组成的,内核是操作系统最基础的组成部分,它负责处理硬件和软件的交互,包括驱动程序、内存管理、进程管理和文件系统等。
而外壳则是用户和操作系统进行交互的界面,我们可以通过命令行或者图形化界面与系统进行交互。
2.文件系统在Linux系统中,所有资料都以文件的形式保存在文件系统中,文件系统采用树形结构。
在Linux中,根目录是"/",其他目录都是在根目录下面的子目录。
我们可以使用ls 命令来查看文件目录和文件,也可以使用cd命令来进入和退出目录,另外,文件名是区分大小写的。
3.用户管理在Linux中,每个用户都有自己的ID号、用户名和密码。
通过用户管理,我们可以添加、删除或修改用户,另外,我们可以通过权限控制来限制普通用户访问系统的某些文件或命令,使系统更安全。
4.进程管理在Linux中,每个程序都是一个进程,我们可以使用ps命令查看系统中运行的进程,也可以使用kill命令来终止特定的进程。
另外,我们可以使用top命令来查看系统中当前占用CPU资源最多的进程,以便优化系统性能。
5.磁盘管理Linux系统中的磁盘分为硬盘和分区,我们可以使用fdisk命令来分区,也可以使用mkfs命令来格式化分区,以便在系统中进行挂载。
另外,我们可以使用df命令来查看文件系统的使用情况,以便合理管理磁盘空间。
6.文件编辑器在Linux中,有很多种文件编辑器,如vi、vim、nano等。
其中,vi是最常用的编辑器,而vim是vi的增强版,它提供了更多的功能和快捷键。
Linux内核笔记——进程管理之执⾏体内核版本:linux-2.6.11在Linux中,有多种执⾏体(指令流、执⾏单位),它们是CPU调度和分配资源的基本单位,它们是内核态可见的,即内核态下,每⼀种执⾏体都有对应的唯⼀数据结构task_struct来存储它的执⾏上下⽂。
它们分别是进程、轻量级进程、内核线程,创建⼀个执⾏体的⽅法是基于调⽤clone()函数并指定flags参数来完成。
通过指定不同的flags参数,可以规定新建的执⾏体的共享资源量、执⾏状态等,也正是于此来区分不同的执⾏体并控制不同执⾏体的运⾏开销、切换开销。
task_struct在task_struct⾥使⽤⼀个thread_struct结构存储硬件上下⽂,使⽤mm_struct存储内存区,使⽤files_struct存储⽂件描述符,使⽤signal_struct存储信号。
因此在Linux⾥,task_struct是⼀个CPU调度的基本单位也是分配资源的基本单位。
进程、轻量级进程、内核线程都是通过⼀个叫clone的函数创建,任何⼀个新的进程、轻量级进程或内核线程都拥有⾃⼰的task_struct。
在现在的Linux⾥,⽤户态线程跟内核线程是⼀对⼀的,也就是说,每个使⽤pthread库产⽣的线程都是对应了⼀个task_struct的。
现如今些新兴的语⾔对M:N这种多线程模型提供了语⾔级的⽀持(如golang的goroutine),它对⽤户透明了内核线程的产⽣和销毁,⽤户可以肆⽆忌惮的使⽤⽤户级多线程,因为在⽤户态的切换开销仅仅是⼀个跳转指令。
进程正常进程与⽗进程完全独⽴,但由于写时复制技术,仅在两个进程中的任何⼀个对独⽴区进⾏修改时,才进⾏独⽴资源的复制,即延迟且竟可能避免了额外的复制开销(可以避免是因为如果新建⼦进程⼀开始就直接执⾏exec那么之前对独⽴区的复制将做⽆⽤功)。
轻量级进程和内核线程之所以把轻量级进程和内核线程放在⼀起是因为内核线程本质上就是⼀个轻量级进程。
Linux内核设计与实现读书笔记(1) 1-7第二章Linux内核1 内核开发特点1)内核编译时不能访问C库;2)浮点数很难使用;3)内核只有一个定长堆栈;4)注意同步和并发。
第三章进程管理1 current宏:查找当前运行进程的进程描述符。
2 进程状态(5种)TASK_RUNNING :1)正在运行;2)在运行队列中等待执行。
TASK_INTERRUPTIBLE:进程正在睡眠,可以被信号唤醒。
TASK_UNINTERRUPTIBLE:进程正在睡眠,不会收到信号被唤醒。
TASK_ZOMBIE:僵死态,进程已经结束,父进程未使用wait4()。
TASK_STOPPED3 进程上下文进程进入内核空间时,current宏依然有效,内核“代表进程执行”。
4 进程创建1)fork():拷贝当前进程创建一个子进程。
2)exec():读取可执行文件并载入地址空间开始运行。
3)写时拷贝(copy-on-wrtie):推迟数据拷贝,在需要写入数据时,数据才会被复制。
4)vfork():不拷贝父进程的页表项,子进程作为父进程的一个线程在它的地址空间运行,父进程被阻塞直至子进程退出,子进程不能向地址块空间写入数据。
5 线程Linux把所有的线程都当作进程来实现。
6 内核线程:独立运行在内核中的标准进程。
内核线程没有独立的地址空间,只能在内核空间中运行,创建内核线程用kernel_thread()。
7 进程终结1)释放资源;2)进入TASK_ZOMBIE;3)等待wait4()。
第四章进程调度1 多任务系统非抢占式多任务:主动让步抢占式多任务(preemptive):时间片2 进程IO消耗型:常常阻塞处理器消耗型:执行代码3 动态优先级调度方法允许调度程序根据需要加减优先级。
两组优先级范围:1)nice值:-20至+19,默认值为0,nice值越大,优先级越低。
2)实时优先级:0至99,任何实时进程优先级都高于普通进程。
linux 内核知识点
Linux内核知识点:
Linux内核是一个免费、开放源码的操作系统内核,它是Linux系统的核心组件。
在本文中,我将介绍一些关键的Linux内核知识点。
1. 进程管理:Linux内核负责管理系统中的各个进程。
它使用调度算法决定哪个进程获得处理器的时间片,以及进程的优先级和调度策略。
2. 内存管理:Linux内核负责管理系统的内存资源。
它使用虚拟内存管理技术将物理内存映射到进程的虚拟地址空间,并且通过页面置换算法进行内存的分页和置换,以优化系统的性能和资源利用率。
3. 文件系统:Linux内核支持多种文件系统,如ext4、Btrfs等。
它负责管理文件和目录的创建、删除、读取和写入,以及文件权限和访问控制。
4. 设备驱动程序:Linux内核提供了丰富的设备驱动程序来支持各种硬件设备的操作和管理。
设备驱动程序与硬件设备进行通信,并提供统一的接口供用户空间程序访问硬件。
5. 网络协议栈:Linux内核包含TCP/IP网络协议栈,支持各种网络协议和通信标准,如IP、TCP、UDP、ICMP等。
它负责处理网络数据包的传输、路由和协议处理。
6. 系统调用:Linux内核提供了一组系统调用接口供用户空间程序使用,以访问内核功能。
这些系统调用包括文件操作、进程管理、网络通信等,使用户空间程序能够与内核进行交互。
以上是一些关键的Linux内核知识点。
了解这些知识可以帮助开发人员理解和利用Linux系统的底层功能,提高系统的性能和稳定性。
Linux Kernel学习笔记Table of Contents1. 存储器寻址2. 设备驱动程序开发3. 字符设备驱动程序3.1. 设备号3.2. 设备号的分配和释放3.3. 重要的数据结构3.4. 读和写4. PCI设备5. 内核初始化优化宏6. 访问内核参数的接口7. 内核初始化选项8. 内核模块编程8.1. 入门8.2. 为模块添加描述信息8.3. 内核模块处理命令介绍9. 网络子系统9.1. sk_buff结构9.2. sk_buff结构操作函数9.3. net_device结构9.4. 网络设备初始化9.5. 网络设备与内核的沟通方式9.6. 网络设备操作层的初始化9.7. 内核模块加载器9.8. 虚拟设备9.9. 8139too.c源码分析9.10. 内核网络数据流10. 备忘录Chapter 1. 存储器寻址在80x86微处理器中,有三种存储器地址:逻辑地址(logical address),包含在机器语言指令中用来指定一个操作数或一条指令的地址。
每个逻辑地址都由一个段(segment)和一个偏移量(offset)组成。
偏移量指明了从段的开始到实际地址之间的距离。
∙线性地址(linear address)(也称为虚拟地址,virtual address),它是一个32位无符号整数,可用以表达高达4G的地址(2的32次方)。
通常以十六进制数表示,值的范围从0X00000000到0Xffffffff。
∙物理地址(physical address),用于存储器芯片级存储单元寻址,它们与从微处理器的地址引脚发送到存储器总线上的电信号相对应。
物理地址由32位无符号整数表示。
CPU控制单元通过一种称为分段单元(segmentation unit)的硬件电路把一个逻辑地址转换成线性地址;线性地址又通过一个分页单元(paging unit)的硬件电路把一个线性地址转换成物理地址。
逻辑地址由两部份组成,一个段标识符和一个指定段由相对地址的偏移量。
Linux Kernel学习笔记——启动启动当PC启动时,Intel系列的CPU首先进入的是实模式,并开始执行位于地址0xFFFF0处的代码,也就是ROM-BIOS起始位置的代码。
BIOS先进行一系列的系统自检,然后初始化位于地址0的中断向量表。
最后BIOS将启动盘的第一个扇区装入到0x7C00,并开始执行此处的代码.这就是对内核初始化过程的一个最简单的描述。
最初,Linux核心的最开始部分是用8086汇编语言编写的。
当开始运行时,核心将自己装入到绝对地址0x90000,再将其后的2k字节装入到地址0x90200处,最后将核心的其余部分装入到0x10000。
当系统装入时,会显示Loading...信息。
装入完成后,控制转向另一个实模式下的汇编语言代码boot/Setup.S。
Setup部分首先设置一些系统的硬件设备,然后将核心从0x10000处移至0x1000处。
这时系统转入保护模式,开始执行位于0x1000处的代码。
接下来是内核的解压缩。
0x1000处的代码来自于文件Boot/head.S,它用来初始化寄存器和调用decompress_kernel()程序。
decompress_kernel( )程序由Boot/inflate.c, Boot/unzip.c和Boot/misc.c组成。
解压缩后的数据被装入到了0x100000处,这也是Linux不能在内存小于2M的环境下运行的主要原因。
解压后的代码在0x1010000处开始执行,紧接着所有的32位的设置都将完成: IDT、GDT和LDT将被装入,处理器初始化完毕,设置好内存页面,最终调用start_kernel过程。
这大概是整个内核中最为复杂的部分。
[系统开始运行]Linux kernel最早的C代码从汇编标记startup_32开始执行|startup_32:|start_kernel|lock_kernel|trap_init|init_IRQ|sched_init|softirq_init|time_init|console_init|#ifdef CONFIG_MODULES |init_modules|#endif|kmem_cache_init|sti|calibrate_delay|mem_init|kmem_cache_sizes_init |pgtable_cache_init|fork_init|proc_caches_init|vfs_caches_init|buffer_init|page_cache_init|signals_init|#ifdef CONFIG_PROC_FS|proc_root_init|#endif|#if defined(CONFIG_SYSVIPC)|ipc_init|#endif|check_bugs|smp_init|rest_init|kernel_thread|unlock_kernel|cpu_idle·startup_32 [arch/i386/kernel/head.S]·start_kernel [init/main.c]·lock_kernel [include/asm/smplock.h]·trap_init [arch/i386/kernel/traps.c]·init_IRQ [arch/i386/kernel/i8259.c] ·sched_init [kernel/sched.c]·softirq_init [kernel/softirq.c]·time_init [arch/i386/kernel/time.c]·console_init [drivers/char/tty_io.c]·init_modules [kernel/module.c]·kmem_cache_init [mm/slab.c]·sti [include/asm/system.h]·calibrate_delay [init/main.c]·mem_init [arch/i386/mm/init.c]·kmem_cache_sizes_init [mm/slab.c]·pgtable_cache_init [arch/i386/mm/init.c]·fork_init [kernel/fork.c]·proc_caches_init·vfs_caches_init [fs/dcache.c]·buffer_init [fs/buffer.c]·page_cache_init [mm/filemap.c]·signals_init [kernel/signal.c]·proc_root_init [fs/proc/root.c]·ipc_init [ipc/util.c]·check_bugs [include/asm/bugs.h]·smp_init [init/main.c]·rest_init·kernel_thread [arch/i386/kernel/process.c]·unloc k_kernel [include/asm/smplock.h]·cpu_idle [arch/i386/kernel/process.c]start_kernel( )程序用于初始化系统内核的各个部分,包括:*设置内存边界,调用paging_init( )初始化内存页面。
《深入理解Linux内核》读书笔记-----内存寻址题记: 最近在看《深入理解linux内核》这本书,看的时候记了些笔记,主要是书上一些重要知识点的謫录还有就是自己的一些个人理解,其实一些地方我也没大看懂,还需要继续研究,先把东西记在这,一些地方记的也有点乱,主要是为以后自己再回去学习这方面知识做一些线索指导,也希望对大家学习这方面只是有些帮助,有什么不正确的地方还请指正三种地址逻辑地址(logical address):包含机器语言指令中用来指定一个操作数或一条指令的地址每一个逻辑地址都由一个段(segment)和偏移量(offset)组成线性地址(又称虚拟地址):是一个32位的无符号整数,可以用来表示高达4G的地址通常用十六进制数字表示,值的范围从0x00000000到0xffffffff物理地址:与从微处理器的地址引脚发送到内存总线上的电信号有关内存寻址的转换过程:逻辑地址---(分段单元)--->线性地址---(分页单元)--->物理地址硬件分段:GDT:全局描述符LDT:局部描述符逻辑地址由一个16位长的段选择符和32位的偏移量组成为了快速方便的找到段选择符,处理器提供了段寄存器,段寄存器的目的是存放段选择符每个段由1个8字节的段描述符表示,它表述了段的特征,存放在GDT或LDT中我们在寻址的时候,一般是从段选择符找到段描述符,然后从段描述符中取得段基址加上偏移量就形成了我们要访问的地址段选择符(16位)用来表示指向哪个段描述符,即用来在段描述符表(GDT,LDT)中寻址,前13位是地址,能寻从0到2^13-1,因此段描述符表的大小是8192,后三位是一些特权级的限制段描述符是用来表示这个段的一些属性,如段基址和段长之类的段选择符的后三位:index,TI,RPL逻辑机制转换成线性地址的流程:1)先检查段选择符的TI字段,以决定段描述符保存在哪一个描述符表中。
TI字段(0或1)指明描述符是在GDT中还是在LDT中2)从段选择符的index字段计算段描述符的地址,index字段的值乘以8(一个段描述符的大小),这个结果在与gdtr或ldtr寄存器中的内容相加3)把逻辑地址的偏移量与段描述符Base字段的值相加就得到了线性地址Linux中的分段分段可以给每一个进程分配不同的线性地址空间,而分页可以把同一线性地址空间映射到不同的物理空间,与分段相比,linux更喜欢使用分页,因为:1)当所有进程使用相同的段寄存器值时,内存管理变得更简单,也就是说它们能共享同样的一组线性地址2)Linux设计目标之一是可以把他移植到绝大多数流行的处理器平台上。
linux内核知识点总结Linux内核是操作系统的核心,负责管理和控制系统资源的分配和调度,以及提供基本的系统服务和接口。
它是操作系统中最重要的组成部分,直接影响着系统的性能、稳定性和安全性。
本文将对Linux内核的一些重要知识点进行总结,包括内核结构、进程管理、内存管理、文件系统、设备驱动程序等。
一、内核结构Linux内核采用了分层的结构,由多个子系统组成,每个子系统负责不同的功能。
这样的设计使得内核更加模块化和易于扩展。
下面是Linux内核的一些重要子系统:1. 进程管理子系统:负责管理系统中的进程,包括进程的创建、调度、终止等操作。
2. 内存管理子系统:负责管理系统的内存资源,包括内存的分配、回收、映射等操作。
3. 文件系统子系统:负责管理系统中的文件和目录,包括文件的读写、访问控制等操作。
4. 网络子系统:负责管理系统中的网络资源,包括网络连接的建立、维护、以及数据包的路由、转发等操作。
5. 设备驱动子系统:负责管理系统中的设备和设备驱动程序,包括设备的注册、初始化、以及对设备的操作和控制等。
这些子系统之间通过一系列的接口进行通信和协作,从而协同工作完成系统的各项任务。
二、进程管理进程是程序的执行实例,Linux内核对进程的管理是系统中最基本的功能之一。
下面是Linux内核中与进程管理相关的一些重要知识点:1. 进程控制块(PCB):每个进程在内核中都有一个对应的进程控制块,它包含了进程的状态、ID、优先级、上下文等信息,内核通过PCB来管理和控制进程的执行。
2. 调度器:Linux内核通过调度器来确定哪个进程能够获得CPU的执行时间,从而实现进程的调度。
Linux内核中有多种调度器可以选择,例如CFS(Completely Fair Scheduler)、实时调度器等。
3. 进程创建:进程的创建是通过fork系统调用完成的,它会创建一个与父进程相同的新进程,然后通过exec系统调用加载新的可执行程序。
分类: LINUXgfree.wind@gmail博客: 本文的copyleft归gfree.wind@gmail所有,利用GPL发布,能够自由拷贝,转载。
但转载请维持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
===================================================== =================================================如前文的流程,bootloader将kerenel加载到内存中。
全数引导进程是四步1:boot PROM phase2:boot Programs phase3:kernel initialization phase4:init phasesystem初始化,检测和,检查设备和创建设备树,设置consolekernel初始化进程kernel self -initialization 内核自检loading of kernel modules 载入内核模块reading of the kernel configuration file in /etc/system 读内核配置文件staring of the /sbin/init process 运行/sbin/init进程bootblk是用于装载第二个引导程序ufsboot的主引导程序bootblk是被PROM的boot设备的引导扇区装载的ufsboot程序是用了装载两部份核心genunix和unix的installboot是用来在磁盘分区上安装bootblk的genunix is the platform-independent generic kernel file ,while unix is the platform-specific kernel component.整个的引导进程:PROM from the boot sector of the boot device-->bookblk-->ufsboot-->genunix(是一个独立平台的一般内核文件) and unix(是一个特殊平台内核文件)-->其它那个地址加载的kernel镜像,并非是真正的可执行文件,而是一个紧缩的镜像文件。
超经典!工程师嵌入式Linux自学笔记及体会针对初学嵌入式的广大朋友们,以下是我在初学接触嵌入式的过程中整理处的一些资料信息,希望能为大家有所帮助。
一个典型的桌面Linux 系统包括3 个主要的软件层---linux 内核、C 库和应用程序代码。
内核是唯一可以完全控制硬件的层,内核驱动程序代表应用程序与硬件之间进行会话。
内核之上是C 库,负责把POSIX API 转换为内核可以识别的形式,然后调用内核,从应用程序向内核传递参数。
应用程序依靠驱动内核来完成特定的任务。
在设计嵌入式应用的时候,可以不按照这种层次,应用程序越过C 库直接和内核会话,或者把应用和内核捆绑在一起,甚至可以把应用写为内核的一个线程,在内核中运行,虽然这样在移植上带来了困难,但考虑嵌入式系统对尺寸要求小的特点,是完全可行的。
不过我们使用三层软件结构的模式来学习嵌入式linux将会是我们认识更清晰,简单可行并使应用具有弹性。
快速入门最简单的建立嵌入式Linux 应用的方法就是从我们使用的桌面Linux 入手,安装一个喜爱的版本,把我们的某个应用作为初始化的一部分,框架就算完成了。
当然,嵌入式linux 应用远比我们的桌面版本功能简单专一,它也许就是一个用于足彩的终端机,或是一个数码音频播放器,这些系统除了使用嵌入式CPU外,仅仅再需要一个串口,网口等少量的输入输出接口就可以完成它们特定的应用了。
在软件上,它可以按照三层的概念由内核装载器,定制的内核和较少的为特定任务设计的静态连接的应用程序组成。
之所以使用静态连接的应用程序,是因为少量的静态连接程序所要的存储空间,比同样数量的动态连接的程序所占的空间小,这个平衡点需要我们在实际开发中去获取。
也许你正在设计的是个PDA,它的应用程序较多,那么你很可能就要使用动态连接程序来减少存储空间。
在你的/bin 或者/sbin 目录下,用厂列表看看bash,ifconfig,vi...,也许只用几十K,当你运行ldd /bin/bash 时,你会看到它们都和好几个库文件相连。
Linux内核学习经验总结分享
开篇
学习内核,每个人都有自己的学习方法,仁者见仁智者见智。
以下是我在学习过程中总结出来的东西,对自身来说,我认为比较有效率,拿出来跟大家交流一下。
内核学习,一偏之见;疏漏难免,恳请指正。
为什么写这篇博客
刚开始学内核的时候,不要执着于一个方面,不要专注于一个子系统就一头扎到实际的代码行中去,因为这样的话,牵涉的面会很广,会碰到很多困难,容易产生挫败感,一个函数体中(假设刚开始的时候正在学习某个方面的某个具体的功能函数)很可能掺杂着其他各个子系统方面设计理念(多是大量相关的数据结构或者全局变量,用于支撑该子系统的管理工作)下相应的代码实现,这个时候看到这些东西,纷繁芜杂,是没有头绪而且很不理解的,会产生很多很多的疑问,(这个时候如果对这些疑问纠缠不清,刨根问底,那么事实上就是在学习当前子系统的过程中频繁的去涉足其他子系统,这时候注意力就分散了),而事实上等了解了各个子系统后再回头看这些东西的话,就简单多了,而且思路也会比较清晰。
所以,要避免“只见树木,不见森林”,不要急于深入到底层代码中去,不要过早研究底层代码。
我在大二的时候刚开始接触内核,就犯了这个错误,一头扎到内存管理里头,去看非常底层的实现代码,虽然也是建立在内存管理的设计思想的基础上,但是相对来说,比较孤立,因为此时并没有学习其它子系统,应该说无论是视野还是思想,都比较狭隘,所以代码中牵涉到的其它子系统的实现我都直接跳过了,这一点还算聪明,当然也是迫不得已的。
我的学习方法
刚开始,我认为主要的问题在于你知道不知道,而不是理解不理解,某个子系统的实现采用了某种策略、方法,而你在学习中需要做的就是知道有这么一回事儿,然后才是理解所描述的策略或者方法。
《奔跑吧Linux内核入门篇》读书札记一、Linux内核概述Linux内核是Linux操作系统的核心部分,负责管理系统的硬件资源、处理软件与硬件之间的交互、确保系统安全稳定地运行。
内核作为操作系统的中枢系统,对于了解计算机系统的重要性不言而喻。
在Linux生态系统中,内核是构建整个操作系统的基石。
它不仅提供了各种硬件接口和服务,而且协调处理各个应用程序之间的运行关系。
通过控制进程、内存管理、文件系统等关键模块,Linux内核实现了系统的稳定可靠以及高性能。
由于其开源特性,Linux内核的开放性、模块化设计使其可维护性和扩展性得到了极大的提升。
系统资源管理:内核负责管理和分配系统的硬件资源,如CPU、内存等,以确保系统的运行效率和稳定性。
硬件抽象层:通过硬件抽象层,内核实现了应用程序与底层硬件的隔离,提高了系统的可移植性和兼容性。
系统进程管理:内核管理系统的进程创建、终止以及调度,保证各个进程得到合理的资源分配和时间片分配。
文件系统管理:内核负责处理文件系统的创建、删除以及挂载等操作,提供持久性数据的存储和访问机制。
系统安全机制:内核提供系统的安全机制,包括用户权限管理、进程间通信的安全等,保障系统安全运行和用户数据安全。
通过对Linux内核的学习,我们可以深入了解操作系统的内部工作原理,掌握系统资源的管理和调度机制,为后续的软件开发和系统维护打下坚实的基础。
Linux内核的学习也是深入理解计算机科学的重要一环,有助于提升个人在计算机领域的综合素质。
在未来的学习实践中,我将致力于探究Linux内核的工作原理、源码解析、模块开发与调试等方面的知识,通过实际操作和深入实践来提升自身技能水平。
通过系统的学习与实践,相信我可以逐步掌握Linux内核的知识体系,为未来的技术研究和开发工作打下坚实的基础。
1. Linux内核简介Linux内核是Linux操作系统的核心组成部分,它负责硬件管理、系统进程调度、内存分配以及安全等功能。
Linux菜鸟的内核学习笔记by Echoa本次总结内容分三部分:配置文件Makefile等,内核模块和文件系统。
1.Makefile,.config和Kconfig(1)理论部分Makefile,Kconfig和配置工具组成了Linux 2.6内核的配置系统。
其中Makefile定义了Linux内核的编译规则,它是大型项目开发的产物。
Linux环境下的大型项目开发中,系统被分为很多模块,而这些模块一般会经历几次修改,而在修改后的编译过程中,由于某些文件中存在依赖关系,人工编译效率低(有些文件不需要重新编译)且易出错,Makefile文件便应运而生。
Makefile文件定义了模块间的依赖关系,指定文件的编译顺序,以及编译所使用的命令。
它和make命令使得项目的源程序文件可以自动编译,提高了软件开发效率。
到此,再谈一下make,它是用来维护程序模块关系和生成可执行程序的工具,它可以根据程序模块的修改情况重新编译链接生成中间代码或最终的可执行程序,省去那些重复的不必要的编译工作,提高编译效率。
Kconfig给用户提供配置选择的功能。
通常配置内核会有四种方法,make config(字符界面配置),make menuconfig(菜单界面配置),make xconfig(依赖QT),make gconfig(依赖GTK+)。
make config 比较适合专业人员,像初学者比较适合make menuconfig,让我们重点关注一下它。
当我们运行make menuconfig时,配置工具会首先分析与体系结构相对应的/arch/xxx/Kconfig文件(xxx为传入的arch参数),它里面包含了除一些与体系结构相关的配置项和配置菜单外,还通过source语句引入了一系列Kconfig,配置工具依据这些Kconfig包含的菜单和项目就可以描绘出一个分层结构。
例如当我们运行make zImagine、make bzImagine等生成映像的命时,会先检索顶层的Makefie(在arch/xxx/目录下的Makefile为顶层Makefile补充体系结构相关的信息),顶层Makefile的两个主要任务是:产生内核映像文件和内核模块。
接着顶层Makefile会去递归地进入内核的各个子目录,然后分别调用子目录中的Makefile(这些Makefile记录编译目标),而进入哪些子目录取决于内核的配置。
当使用make menuconfig,make config命令时,生成的.config会在源码目录下记录哪些部分被编译入内核,哪些部分被编译为内核模块。
简而言之,它是保存内核配置结果的文件。
当我们装上Linux系统时,第一次查看源码下的所有文件,会发现没有.config文件,那是因为从来没配置过内核。
当你运行make menuconfig保存并退出时,再次查看就有这个文件了。
配置工具,包括配置命令解释器(对配置脚本中使用的命令进行解释)和配置用户界面(提供字符界面和图形界面),配置工具都是用脚本语言编写的。
(2)实践部分在源码目录的drivers目录下新加test目录和其子目录,并将它添加到menuconfig配置菜单中。
这个过程主要有三步:a.创建目录及编写相关的文件b.编写Kconfig文件c.编写Makefile文件Test树形目录结构如下:|--test|--cpu|--cpu.c|--test.c为了在内核菜单中添加它,必须编写相应的Makefile文件和Kconfig 文件,树形目录如下:|--test|--cpu|--cpu.c|--Makefile|--test.c|--Makefile|--KconfigKconfig和Makefile内容详见课本P62,为了使本层的Kconfig文件能起作用,我们需要修改父目录的Kconfig文件,加入source语句,如在test 父目录中加入source“drivers/test/Kconfig”,就可以通知上层配置文件本层的配置。
下面分析一下testx目录下的Kconfig文件1#2#TEST driver configuration/*#表示注释*/3#4menu"TEST Driver"/*配置菜单*/5comment"TEST Driver"67config CONFIG_TEST8bool"Test support"/*bool型变量,只有y或n选项*/ 910config CONFIG_TEST_USER11tristate"TEST user-space interface"/*三态变量,有y,n和M选项*/12depends on CONFIG_TEST/*CONFIG_TEST_USER依赖CONFIG_TEST的选择,只有后者被选为y时才出现此选项*/ 1314endmenu正确配置好后,我们在源码下执行sudo make menuconfig后,在出现的Linux Kernel Configuration图形界面中选择Device Drivers,我们将会看到新加的Test driver菜单,选择后可看到的菜单界面如下:**TEST Driver***[*]Test support<>TEST user-space interface其中[]表示bool型选项,<>表示三态选项,*表示y选项,编译进内核,空表示n选项,M表示编译成模块。
由于有依赖关系,当Test support 被选为n时,显示的菜单界面如下:***TEST Driver***[]Test support2.内核模块(1)一个简单的c语言hello world程序#include<stdio.h>int main(void){printf(“Hello world!\n”);return0;}(2)一个最简单的Linux内核模块1#include<linux/init.h>/*内核头文件*/2#include<linux/module.h>/*内核头文件*/3MODULE_LICENSE("Dual BSD/GPL");/*模块许可证声明*/4static int hello_init(void)/*模块初始化函数*/5{6printk(KERN_ALERT"Hello world enter\n");7return0;8}910static void hello_exit(void)/*模块退出函数*/11{12printk(KERN_ALERT"Hello world exit\n");/*内核中的输出函数*/13}1415module_init(hello_init);/*模块加载函数,必须有*/16module_exit(hello_exit);/*模块卸载函数,一般和加载函数成对出现,完成相反的功能*/1718MODULE_AUTHOR("WU");/*模块作者,可以不写*/19MODULE_DESCRIPTION("A simple Hello world module");/*模块描述,可不写*/20MODULE_ALIAS("a simplest module")/*模块别名,可没有*/由普通c语言程序到内核模块程序的转变:可以看出内核模块程序长了很多,还有printf和printk两个看起来有点相似的函数。
printk函数属于内核中的函数,它只能在内核空间中执行它由输出级别和输出内容构成;而printf函数属于用户态函数,只能在用户空间执行,仅由输出内容构成。
在编译连接时普通C程序会用到usr/include下的头文件如stdio.h,而内核中的头文件都在源码目录下的include下。
printk函数的输出记录级定义在源码下的include/linux/kernel.h头文件中,共有八个记录级,其中KERN_ALERT表示在需要立即操作的情况下使用此消息,这个记录级下,输出内容会在系统日志中。
可以看出一个内核模块主要包括了四个部分:a.模块头文件和模块许可证声明b.模块初始化函数和模块退出函数c.模块加载函数和模块卸载函数d.模块的描述信息,如模块作者,模块功能的描述,模块别名等。
我们知道一般的C普通程序从主函数作为入口开始执行,最后由主函数作为出口退出,而模块的执行就差别很大了。
程序的模块加载函数只是告诉内核当你加载这个模块时从这儿作为入口开始执行,执行时它会调用模块初始化函数。
程序的模块卸载函数的作用是告诉内核当卸载这个模块时从这儿作为入口开始执行,执行时它会调用模块退出函数。
真正的加载和卸载模块是通过insmod./模块名.ko命令和rmmod模块名命令执行的。
具体到上面的模块,加载模块命令insmod hello.ko,卸载模块命令rmmod hello。
我们还可以通过lsmod命令获得系统中已加载的模块和模块间的依赖关系。
我们可以通过dmesg命令查看模块执行结果,其中dmesg为查看系统日志命令。
当然在执行加载模块命令之前,我们须给出编译规则,如下内容的Makefile文件。
1obj-m+=hello.o/*编译规则*/23CURRENT_PATH:=$(shell pwd)/*shell命令显示当前目录,$()为引用变量结果*/45LINUX_KERNEL:=$(shell uname-r)/*shell命令显示系统版本号*/67LINUX_KERNL_PATH:=/usr/src/linux-headers-$(LINUX_KERNEL) /*内核源码目录*/89all:10make-C$(LINUX_KERNL_PATH)M=$(CURRENT_PATH) modules/*编译成模块*/11clean:12make-C$(LINUX_KERNL_PATH)M=$(CURRENT_PATH)clean/*清除编译结果*/其实,我们可以只写第一行,但是这样写有比较好的移植性,make modules直接在Makefile文件中,省去了在终端运行命令的麻烦,而12行的编写也体现了良好的编程规范。
3.file_operation函数的作用和设备文件系统文件系统也算Linux系统实现的一大核心功能,我们可以发现linux 下,一切皆文件,甚至包括磁盘设备,这不能不说是文件系统设计的成功和设计者设计fs时策略的高瞻远瞩。
由上图可以看出,应用程序通过系统调用访问VFS(虚拟文件系统),而VFS则通过file_operation函数访问各种文件,文件通过相应驱动访问到设备中存放的数据。