有以下两者查看命令:
1、# cat /proc/version (Linux查看当前 *** 作系统版本信息)
Linux version 2420-8 (bhcompile@porkydevelredhatcom)
(gcc version 322 20030222 (Red Hat Linux 322-5)) #1 Thu Mar 13 17:54:28 EST 2003
2、# cat /etc/issue 或cat /etc/redhat-release(Linux查看版本当前 *** 作系统发行版信息)
Red Hat Linux release 9 (Shrike)
扩展资料:
Linux来历:
Linux是一个诞生于网络、成长于网络且成熟于网络的奇特的 *** 作系统。1991年,芬兰大学生Linus Torvalds萌发了开发一个自由的UNIX *** 作系统的想法,当年,Linux就诞生了,为了不让这个羽毛未丰的 *** 作系统夭折,Linus将自已的作品Linux通过Internet发布。
从此一大批知名的、不知名的电脑黑客、编程人员加入到开发过程中来,Linux逐渐成长起来。
Linux一开始是要求所有的源码必须公开,并且任何人均不得从Linux交易中获利。然而这种纯粹的自由软件的理想对于Linux的普及和发展是不利的,于是Linux开始转向GPL,成为GNU阵营中的主要一员。
Linux凭借优秀的设计,不凡的性能,加上IBM、INTEL、CA、CORE、ORACLE等国际知名企业的大力支持,市场份额逐步扩大,逐渐成为主流 *** 作系统之一。
各位,知道kernel里获取系统时间的函数吗?
#ifdef __KERNEL__
#define OS_GET_TIME(pTimer) { get_fast_time(pTimer); }
#else
#include <sys/timeh>
#include <WW/ISUtilsh>
#define OS_GET_TIME(pTimer) { gettimeofday(pTimer,NULL); }
#endif / KERNEL /
显示 warning: implicit declaration of function ‘get_fast_time’ [-Wimplicit-function-declaration]
var isIE=navigatoruserAgenttoUpperCase()indexOf("MSIE")true:false; 类似的可以写 var isFirefox=navigatoruserAgenttoUpperCase()indexOf("Firefox")true:false; 之类的东西 然后你再用JS设置abc这个元素的样式 display:none;之类的
主要用到navigatoruserAgent
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
function myBrowser(){
var userAgent = navigatoruserAgent; //取得浏览器的userAgent字符串
consolelog(userAgent);
var isOpera = userAgentindexOf("Opera") > -1;
if (isOpera) {
return "Opera"
}; //判断是否Opera浏览器
if (userAgentindexOf("Firefox") > -1) {
return "FF";
} //判断是否Firefox浏览器
if (userAgentindexOf("Chrome") > -1){
return "Chrome";
}
if (userAgentindexOf("compatible") > -1 && userAgentindexOf("MSIE") > -1 && !isOpera) {
return "IE";
}; //判断是否IE浏览器
}
var cc = myBrowser();
if(cc == "Chrome"){
alert("当前是Chrome浏览器")
}
if(cc == "IE"){
alert("当前是IE浏览器")
}
</script>
</body>
</html>
页表用来把虚拟页映射到物理页,并且存放页的保护位(即访问权限)。
在Linux411版本以前,Linux内核把页表分为4级:
页全局目录表(PGD)、页上层目录(PUD)、页中间目录(PMD)、直接页表(PT) 。
411版本把页表扩展到5级,在页全局目录和页上层目录之间增加了 页四级目录(P4D) 。
各处处理器架构可以选择使用5级,4级,3级或者2级页表,同一种处理器在页长度不同的情况可能选择不同的页表级数。可以使用配置宏CONFIG_PGTABLE_LEVELS配置页表的级数,一般使用默认值。
如果选择4级页表,那么使用PGD,PUD,PMD,PT;如果使用3级页表,那么使用PGD,PMD,PT;如果选择2级页表,那么使用PGD和PT。 如果不使用页中间目录 ,那么内核模拟页中间目录,调用函数pmd_offset 根据页上层目录表项和虚拟地址获取页中间目录表项时 , 直接把页上层目录表项指针强制转换成页中间目录表项 。
每个进程有独立的页表,进程的mm_struct实例的成员pgd指向页全局目录,前面四级页表的表项存放下一级页表的起始地址,直接页表的页表项存放页帧号(PFN) 。
内核也有一个页表, 0号内核线程的进程描述符init_task的成员active_mm指向内存描述符init_mm,内存描述符init_mm的成员pgd指向内核的页全局目录swapper_pg_dir 。
ARM64处理器把页表称为转换表,最多4级。ARM64处理器支持三种页长度:4KB,16KB,64KB。页长度和虚拟地址的宽度决定了转换表的级数,在虚拟地址的宽度为48位的条件下,页长度和转换表级数的关系如下所示:
ARM64处理器把表项称为描述符,使用64位的长描述符格式。描述符的0bit指示描述符是不是有效的:0表示无效,1表示有效。第1位指定描述符类型。
在块描述符和页描述符中,内存属性被拆分为一个高属性和一个低属性块。
处理器的MMU负责把虚拟地址转换成物理地址,为了改进虚拟地址到物理地址的转换速度,避免每次转换都需要查询内存中的页表,处理器厂商在管理单元里加了称为TLB的高速缓存,TLB直译为转换后备缓冲区,意译为页表缓存。
页表缓存用来缓存最近使用过的页表项, 有些处理器使用两级页表缓存 : 第一级TLB分为指令TLB和数据TLB,好处是取指令和取数据可以并行;第二级TLB是统一TLB,即指令和数据共用的TLB 。
不同处理器架构的TLB表项的格式不同。ARM64处理器的每条TLB表项不仅包含虚拟地址和物理地址,也包含属性:内存类型、缓存策略、访问权限、地址空间标识符(ASID)和虚拟机标识符(VMID)。 地址空间标识符区分不同进程的页表项 , 虚拟机标识符区分不同虚拟机的页表项 。
如果内核修改了可能缓存在TLB里面的页表项,那么内核必须负责使旧的TLB表项失效,内核定义了每种处理器架构必须实现的函数。
当TLB没有命中的时候,ARM64处理器的MMU自动遍历内存中的页表,把页表项复制到TLB,不需要软件把页表项写到TLB,所以ARM64架构没有提供写TLB的指令。
为了减少在进程切换时清空页表缓存的需要,ARM64处理器的页表缓存使用非全局位区分内核和进程的页表项(nG位为0表示内核的页表项), 使用地址空间标识符(ASID)区分不同进程的页表项 。
ARM64处理器的ASID长度是由具体实现定义的,可以选择8位或者16位。寄存器TTBR0_EL1或者TTBR1_EL1都可以用来存放当前进程的ASID,通常使用寄存器TCR_EL1的A1位决定使用哪个寄存器存放当前进程的ASID,通常使用寄存器 TTBR0_EL1 。寄存器TTBR0_EL1的位[63:48]或者[63:56]存放当前进程的ASID,位[47:1]存放当前进程的页全局目录的物理地址。
在SMP系统中,ARM64架构要求ASID在处理器的所有核是唯一的。假设ASID为8位,ASID只有256个值,其中0是保留值,可分配的ASID范围1~255,进程的数量可能超过255,两个进程的ASID可能相同,内核引入ASID版本号解决这个问题。
(1)每个进程有一个64位的软件ASID, 低8位存放硬件ASID,高56位存放ASID版本号 。
(2) 64位全局变量asid_generation的高56位保存全局ASID版本号 。
(3) 当进程被调度时,比较进程的ASID版本号和全局版本号 。如果版本号相同,那么直接使用上次分配的ASID,否则需要给进程重新分配硬件ASID。
存在空闲ASID,那么选择一个分配给进程。不存在空闲ASID时,把全局ASID版本号加1,重新从1开始分配硬件ASID,即硬件ASID从255回绕到1。因为刚分配的硬件ASID可能和某个进程的ASID相同,只是ASID版本号不同,页表缓存可能包含了这个进程的页表项,所以必须把所有处理器的页表缓存清空。
引入ASID版本号的好处是:避免每次进程切换都需要清空页表缓存,只需要在硬件ASID回环时把处理器的页表缓存清空 。
虚拟机里面运行的客户 *** 作系统的虚拟地址转物理地址分两个阶段:
(1) 把虚拟地址转换成中间物理地址,由客户 *** 作系统的内核控制 ,和非虚拟化的转换过程相同。
(2) 把中间物理地址转换成物理地址,由虚拟机监控器控制 ,虚拟机监控器为每个虚拟机维护一个转换表,分配一个虚拟机标识符,寄存器 VTTBR_EL2 存放当前虚拟机的阶段2转换表的物理地址。
每个虚拟机有独立的ASID空间 ,页表缓存使用 虚拟机标识符 区分不同虚拟机的转换表项,避免每次虚拟机切换都要清空页表缓存,在虚拟机标识符回绕时把处理器的页表缓存清空。
/dev/root是Linux内核生成的一个虚拟设备文件,它是指根文件系统的设备文件,用于挂载根文件系统。它是内核启动时自动创建的,用于指向根文件系统的设备,它是一个特殊的设备文件,不能被删除,也不能被更改。/dev/root是Linux内核在启动时自动创建的,它是指向根文件系统的设备文件,用于挂载根文件系统,它是一个特殊的设备文件,不能被删除,也不能被更改。/dev/root是Linux内核在启动时自动创建的,它是指向根文件系统的设备文件,用于挂载根文件系统,它是一个特殊的设备文件,它的作用是指向根文件系统,是系统启动时必须挂载的,它指定了系统启动时要挂载的文件系统,它是系统启动时必不可少的一部分,它是Linux内核启动时自动创建的,用于指向根文件系统的设备文件,它是一个特殊的设备文件,不能被删除,也不能被更改,它是Linux内核启动时必须创建的,用于指向根文件系统的设备文件,用于挂载根文件系统。
我们都知道Nodejs是异步的,那么Nodejs为什么会是异步的呢?这是因为Nodejs使用了LIBUV做为它的跨平台抽象层。具体请看 nodejs运行机制
select、poll、epoll是Linux平台下的IO多路复用机制,用来管理大量的文件描述符。但是select/poll相对于epoll来说效率是低下的。
1、linux内核在select的每次返回前都要对所有的描述符 循环遍历 ,将有事件发生的文件描述符放在一个集合里返回。在描述符不多的时候对性能影响不大,但是当描述符达到数十万甚至更多的时候,这种处理方式造成大量的浪费和资源开销,select的效率会急剧下降。这是因为每次select的时候,会将所有的文件描述符从用户态拷贝的内核态,在内核态进行循环,查看是否有事件发生。2、select默认的管理的最大文件描述符是1024个,当然可以对linux内核从新编译来改变这个限制。
原理和select相似也是使用循环遍历的方式管理文件描述符,不同的是管理的文件最大文件描述符的数量没有限制(根据系统限制来定)。
下文讲解epoll实现原理
epoll改进了select的两个缺点,从而能够在管理大量的描述符的情况下,对系统资源的使用并没有急剧的增加,而只是对内存的使用有所增加(毕竟存储大量的描述符的数据结构会占用大量内存)。epoll在实现上的三个核心点是:1、mmap,2、红黑树,3、rdlist(就绪描述符链表)接下来一一解释这三个并且解释为什么会高效。
mmap是共享内存,用户进程和内核有一段地址(虚拟存储器地址)映射到了同一块物理地址上,这样当内核要对描述符上的事件进行检查的时候就不用来回的拷贝了。
红黑树是用来存储这些描述符的。当内核初始化epoll的时候(当调用epoll_create的时候内核也是个epoll描述符创建了一个文件,毕竟在Linux中一切都是文件,而epoll面对的是一个特殊的文件,和普通文件不同),会开辟出一块内核缓冲区,这块区域用来存储我们要监管的所有的socket描述符,当然在这里面存储有一个数据结构,这就是红黑树,由于红黑树的接近平衡的查找,插入,删除能力,在这里显著的提高了对描述符的管理。
rdlist就绪描述符链表这是一个双链表,epoll_wait()函数返回的也是这个就绪链表。当内核创建了红黑树之后,同时也会建立一个双向链表rdlist,用于存储准备就绪的描述符,当调用epoll_wait的时候在timeout时间内,只是简单的去管理这个rdlist中是否有数据,如果没有则睡眠至超时,如果有数据则立即返回并将链表中的数据赋值到events数组中。这样就能够高效的管理就绪的描述符,而不用去轮询所有的描述符。
当执行epoll_ctl时除了把socket描述符放入到红黑树中之外,还会给内核中断处理程序注册一个回调函数,告诉内核,当这个描述符上有事件到达(或者说中断了)的时候就调用这个回调函数。这个回调函数的作用就是将描述符放入到rdlist中,所以当一个socket上的数据到达的时候内核就会把网卡上的数据复制到内核,然后把socket描述符插入就绪链表rdlist中。
Epoll的两种模式:
1 水平触发(LT):使用此种模式,当数据可读的时候,epoll_wait()将会一直返回就绪事件。如果你没有处理完全部数据,并且再次在该epoll实例上调用epoll_wait()才监听描述符的时候,它将会再次返回就绪事件,因为有数据可读。
2 边缘触发(ET):使用此种模式,只能获取一次就绪通知,如果没有处理完全部数据,并且再次调用epoll_wait()的时候,它将会阻塞,因为就绪事件已经释放出来了。
ET的效能更高,但是对程序员的要求也更高。在ET模式下,我们必须一次干净而彻底地处理完所有事件。
epoll的linux实现
以上就是关于怎么查看Linux的内核kernel版本全部的内容,包括:怎么查看Linux的内核kernel版本、各位,知道kernel里获取系统时间的函数吗、js怎么判断浏览器内核是否为chrome或者Firefox,如果不是就跳转到同目录下的bg.html等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)