linux kernel
文章平均质量分 76
kerneler_
做一个有技术追求的人
ps:目前公司太忙,暂没时间更新博客,,大家评论我尽量回复,望大家谅解
展开
-
udev的自定义规则
自2.6 核心开始,就可以使用udev 协助管理系统中各设备名称。例如,磁盘设备排序、网卡设备排序等。udev能动态地在/dev 目录里产生自定义的、标识性强的设备文件或设备链接。本文即以红旗Asianux 3.0 平台,给新加载的U盘设备自定义一个链接为例进行简要说明。一、关于udev2.4 内核使用devfs(设备文件系统)在设备初始化时创建设备文件,设备驱动程序可以指定设备号、所转载 2013-07-18 19:52:47 · 10091 阅读 · 0 评论 -
linux内核sysfs详解
"sysfs is a ram-based filesystem initially based on ramfs. It provides a meansto export kernel data structures, their attributes, and the linkages between them touserspace.” --- documentation/file转载 2013-09-17 18:35:14 · 33875 阅读 · 5 评论 -
linux下sysfs设备模型
设备模型(一)一、概述从2.6内核引入了sysfs文件系统,与proc, devfs, devpty同类别,属于虚拟的文件系统。目的是展示设备驱动模型中各组件的层次关系,第一层目录:block, device, bus, drivers, class, power, firmware.block 块设备;devices 系统所有的设备并根据设备挂接的总线类型组织成层转载 2013-09-25 10:27:07 · 1933 阅读 · 0 评论 -
mips下非对齐访问问题分析
1. 问题RISC 下使用访存指令读取或写入数据单元时,目标地址必须是所访问之数据单元字节数的整数倍,这个叫做地址对齐。比 如在 MIPS 平台上,lh 读取一个半字时,存储器的地址必须是 2 的整数倍; lw 读取一个字时,存储器的地址必须是 4的整数倍; sd 写入一个双字时,存储器的地址必须是 8 的整数倍。倘若访存时,目标地址不对齐,则会引起异常,典型的是系统提示“总线错误转载 2013-12-08 18:59:45 · 7133 阅读 · 0 评论 -
ubuntu下获取对应内核源码的方法
输入:apt-cache search linux-source //查看内核版本输入:apt-get install linux-source-3.0.0 //获取对应版本的内核,默认安装在/usr/src目录下见: ubuntu下编译本机模块是否需要下载内核源码呢?答案是可以的。dmesg | tail -1 命令用于查看载入内核后打印的数转载 2013-12-03 23:03:06 · 2652 阅读 · 0 评论 -
Linux 关于动态链接库以及静态链接库的一些概念
库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀。例如:libhello.so libhello.a 为了在同一系统中使用不同版本的库,可以在库文件名后加上版本号为后缀,例如: libhello.so.1.0,由于程序连接默认以.so为文件后缀名。所以为了使用这些库,通常使用建立符号连接的方式。 ln -s libhello.so.1.0 libhello.so.1 ln转载 2013-12-03 16:52:16 · 1442 阅读 · 0 评论 -
linux内核动态时钟分析
在早期的linux内核版本的时间概念都是由周期时钟提供的。虽然比较有效,但是,对于关注能耗电量的系统上,就不能满足长时间休眠的需求,因为周期系统要求必须在一定的频率下,周期性的处于活动状态。因此,linux提出了tickless system,即无时钟系统。其关键就是判定系统当前是否无事可做,若是则禁用时钟系统。判定系统当前无事可做的依据是:如果运行队列时没有活动进程,内核将选择idle进程来运行转载 2013-12-31 15:45:24 · 2428 阅读 · 0 评论 -
linux内核calibrate_delay函数实现分析
公司使用的死mips处理器,每秒钟jiffs是250个,内核变量HZ值就是250,由此我引发一个疑问,一个jiffs时钟中断耗时4ms,没法做到毫秒微妙甚至纳秒的精度,那么内核延时函数mdelay udelay ndelya是如何实现的呢,于是研究了一下,就找到了linux内核中一个有趣的函数calibrate_delay()。 calibrate_delay()函数可以计算出cpu在一秒钟内原创 2013-11-17 11:04:33 · 6735 阅读 · 0 评论 -
kernel编译生成Image zImage uImage的区别
内核编译(make)之后会生成两个文件,一个Image,一个zImage,其中Image为内核映像文件,而zImage为内核的一种映像压缩文件,Image大约为4M,而zImage不到2M。 那么uImage又是什么的?它是uboot专用的映像文件,它是在zImage之前加上一个长度为64字节的“头”,说明这个内核的版本、加载位置、生成时间、大小等信息;其0x40之后与zImage没区原创 2014-06-27 10:28:21 · 21389 阅读 · 3 评论 -
linux kernel编译生成zImage过程详解
可以看到,在顶层makefile的第278行,包含了scripts/Kbuild.include文件,在这里定义了大量的函数和变量,供顶层makefile和其他makefile文件使用。 在顶层makefile文件的第412行,包含了arch/arm/Makefile。这个是体系结构相关makefile文件。它定义了体系结构相关的一些变量及规则。 当执行”make”时,ar转载 2014-06-27 10:35:07 · 10592 阅读 · 0 评论 -
NAPI处理方式分析
NAPI 的核心在于:在一个繁忙网络,每次有网络数据包到达时,不需要都引发中断,因为高频率的中断可能会影响系统的整体效率,在高流量下,网卡产生的中断可能达到每秒几千次,而如果每次中断都需要系统来处理,是一个很大的压力,而NAPI 使用轮询时是禁止了网卡的接收中断的,这样会减小系统处理中断的压力,NAPI 是Linux 上采用的一种提高网络处理效率的技术,它的核心概念就是不采用中断的方式读取数据,而转载 2013-09-08 18:21:54 · 1605 阅读 · 0 评论 -
mips处理器linux内核添加系统调用
参考文件:arch/mips/kernel/scall32-o32.Ssys_call_table定义了系统调用的函数列表。在这个表中反复引用sys这个汇编宏定义二元组。.macro sys function, nargs PTR /function LONG (/nargs .endm这个表转载 2013-08-18 23:01:03 · 2241 阅读 · 0 评论 -
linux网卡驱动的NAPI技术分析
NAPI 是 Linux 上采用的一种提高网络处理效率的技术,它的核心概念就是不采用中断的方式读取数据,而代之以首先采用中断唤醒数据接收的服务程序,然后 POLL 的方法来轮询数据。随着网络的接收速度的增加,NIC 触发的中断能做到不断减少,目前 NAPI 技术已经在网卡驱动层和网络层得到了广泛的应用,驱动层次上已经有 E1000 系列网卡,RTL8139 系列网卡,3c50X 系列等主流的网转载 2013-08-27 17:50:58 · 3460 阅读 · 1 评论 -
使用udev修改u盘设备文件名
udev的规则的编写,我这里就不说了,大家可以在udev的文档中可以了解,有时间的话我在安排一章在说明udev 的规则了。 下面是我要做的一个测试,我的系统是ubuntu9.10,我有一个usb优盘,是kinston的4G的优盘。 运行: sudo fdisk -l 看下我的优盘的情况,如下图:原创 2013-07-18 19:54:10 · 6208 阅读 · 1 评论 -
linux内核VFS虚拟文件系统总结
最近手里有一个项目需要写一个简单的文件系统,利用周末时间把深入理解linux内核书第十二章虚拟文件系统学习了一下,加深了对vfs的理解,这里也做一下总结,以备后查。 linux成功的关键因素之一就是它与其他操作系统和谐共存的能力,在linux下可以安装挂载很多格式的文件系统,之所以能实现就是通过虚拟文件系统这一中间系统层,虚拟文件系统的主要思想是引入了一个通用文件模型,它能够表示所有的文件系原创 2013-07-21 11:34:19 · 4323 阅读 · 2 评论 -
linux模块参数分析
module_param()理解-------------------------------------------在用户态下编程可以通过main()的来传递命令行参数,而编写一个内核模块则通过module_param()module_param()宏是Linux 2.6内核中新增的,该宏被定义在include/linux/moduleparam.h文件中,具体定义如下:#def转载 2013-07-30 16:43:23 · 1201 阅读 · 0 评论 -
linux内核spin_lock分析
今天我们详细了解一下spin_lock在内核中代码实现,我们总共分析四个项目: 1.spinlock_t的定义分析:首先来看一下spinlock_t的定义:typedef struct { raw_spinlock_t raw_lock;#if defined(CONFIG_PREEMPT) &&defined(CONFIG_SMP) unsig转载 2013-07-25 16:47:31 · 1965 阅读 · 0 评论 -
BUG 和BUG_ON
调试的时候很有用的东西:dump_stack 使用前,先在内核配置中把kernel debug选上:make menuconfig:kernel hacking-->kernel debug 作用:一些内核调用可以用来方便标记bug,提供断言并输出信息。最常用的两个是BUG()和BUG_ON()。当被调用的时候,它们会引发oops,导致栈的回溯和错误信息的打印。为什么这转载 2013-07-25 18:43:50 · 2086 阅读 · 0 评论 -
linux内核SYSCALL_DEFINE分析
CVE-2010-3301是其中一个。这个漏洞的成因是,在64位的内核上执行32位的系统调用时,作为传递系统调用号的%rax高32位未被清零处理,而且在进行比较的时候直接使用的%eax,导致高32位被忽略: cmpl $(IA32_NR_syscalls-1),%eax ja ia32_badsysia32_do_call: IA32_ARG_F原创 2013-08-04 16:34:35 · 6587 阅读 · 0 评论 -
linux系统调用mount全过程分析
系统调用本身是软中断,使用系统调用,内核也陷入内核态,异常处理,找到相应的入口最后就会跳转到sys_mount,跳转到sys_mount之前的这个过程主要是跟系统的异常处理相关,以mips处理器为例,相关代码在arch/mips/kernel/下的traps.c syscall32-o32.S等文件中实现的,过几天有空再缕一遍,今天主要总结的是sys_mount之后的事情,内核是如何实现将文件系统原创 2013-08-04 19:07:50 · 14028 阅读 · 0 评论 -
内核EXPORT_SYMBOL分析
在查看内核驱动代码的时候会经常看到在一些函数后面总会跟EXPORT_SYMBOL()这样的宏定义,通过网上查阅,它的作用大致总结如下:1、定义说明 把内核函数的符号导出,也可以理解成将函数名作为符号导出;符号的意思就是函数的入口地址,或者说是把这些符号和对应的地址保存起来的,在内核运行的过程中,可以找到这些符号对应的地址的。2、相关处理 (1)、对编译所得的.ko进转载 2013-08-07 15:32:10 · 1529 阅读 · 1 评论 -
linux power managment 详解
一.前言在这个对节能要求越来越严格的年代,对设备的电源管理就显的很重要的了,尤其对于可移动设备,在电源有限的情况下,续航能力就显的很重要的。在本文中将介绍linux是如何对设备电源进行管理的。二.睡眠Linux的电源管理的主要几个文件集中在/kernel/power/main.c和/driver/base/power/main.c中。主要以platform设备来看linux的睡眠和唤醒转载 2013-08-23 16:08:17 · 1330 阅读 · 0 评论 -
虚拟网卡与loopback的思想
在linux上卸载了loopback网卡设备之后,本地地址全部不通,这是不应该的吗?所有的本地网卡在配置ip地址的时候会调用fib_add_ifaddr函数:void fib_add_ifaddr(struct in_ifaddr *ifa){... fib_magic(RTM_NEWROUTE, RTN_LOCAL, addr, 32, prim);//如此一来,加入一转载 2014-07-22 16:32:18 · 3195 阅读 · 0 评论 -
ARM过程调用标准---APCS简介
介绍APCS,ARM 过程调用标准(ARM Procedure Call Standard),提供了紧凑的编写例程的一种机制,定义的例程可以与其他例程交织在一起。最显著的一点是对这些例程来自哪里没有明确的限制。它们可以编译自 C、 Pascal、也可以是用汇编语言写成的。APCS 定义了:对寄存器使用的限制。使用栈的惯例。在函数调用之间传递/返回参数。可以被‘回溯’的基原创 2014-07-07 14:27:57 · 6769 阅读 · 1 评论 -
移植linux kernel,应该怎么做
对于移植kernel的思路我觉得还是很有必要总结下,这里总结不涉及具体代码,而只是说说保证kernel能进入console稳定运行这样一个最小系统,我们需要完成哪些部分的移植呢。根据这次移植我的思路,需要以下几个方面的移植:cpu core初始化,内存管理子系统(mmu),硬件时钟系统,早期调试打印机制,异常中断子系统,时间子系统(timer),串口驱动原创 2015-01-31 20:52:37 · 7703 阅读 · 7 评论 -
arm-linux内核start_kernel之前启动分析(1)-接过bootloader的衣钵
如果想运行和链接地址不一致,我能想到的办法,只能是汇编中尽量不去涉及一些绝对地址,使用PIC位置无关代码。联想之前分析的uboot relocation原理,uboot在relocation之后,kernel在开启MMU之前,都实现了链接地址和运行地址不一致,看看它们用的什么方法?(1)uboot在relocation时修改rel.dyn段(存储所有变量地址),实现将所有变量地址重定位到新运行地址(2)kernel在开启MMU之前,计算运行地址(物理地址)与链接地址(虚拟地址)的偏移,对变量寻址时都进原创 2014-11-21 10:05:03 · 13918 阅读 · 5 评论 -
arm-linux内核start_kernel之前启动分析(3)-开启MMU,走进新时代
在第二篇启动分析文章中讲到create pgtable时,对__turn_mmu_on所在的1M地址空间做了平映射,到现在这个阶段就看出其作用了。CPU执行完成“mcr p15, 0, r0, c1, c0,0”指令后开启MMU,接下来CPU取指地址是当前pc+4,由于做了平映射,虽然接下来是虚拟地址,但是该虚拟地址跟之前的物理地址是完全一致的,pc+4可以取到mrc p15, 0, r3, c0, c0, 0指令原创 2015-08-28 16:35:38 · 8768 阅读 · 2 评论 -
arm-linux内核start_kernel之前启动分析(2)- 页表的准备
create_page_table完成了3种地址映射的页表空间填写:(1)turn_mmu_on所在1M空间的平映射(2)kernel image的线性映射(2)bootparams所在1M空间的线性映射原创 2014-11-24 17:17:56 · 9304 阅读 · 7 评论 -
powerpc-linux内核start_kernel之前启动分析(1)-开门见山
公司处理器换核,前期用FPGA仿真板进行了芯片验证和软件移植,借这个机会也学习了powerpc处理器的一些知识,对powerpc的内核启动也有所了解。 完成了arm版本内核start_kernel之前汇编分析,也想尝试写几篇文章对powerpc的启动进行分析,与大家分享。其实不管哪个平台处理器,内核启动之初,因为运行地址无法保证与链接地址一致,都要完成一次地址的配置和跳转来保证内核运行地址与链接地址的一致性。原创 2015-09-16 16:34:06 · 6978 阅读 · 0 评论 -
arm-linux内存管理学习笔记(1)-内存页表的硬件原理
学习内核的内存管理如果脱离了MMU的硬件原理,只去学习其软件逻辑,真的很难懂。说到底,软件代码的逻辑是为硬件服务,只是为了充分发挥硬件的各项功能,因此学习linux的内存管理机制,首先要学习下该处理器架构下MMU的工作原理,这样对我们理解页表机制的逻辑很有帮助原创 2016-04-05 16:40:52 · 8415 阅读 · 1 评论 -
linux kernel的cmdline参数解析原理分析
依据我的思路(时间顺序,如何开始,如何结束),首先看kernel下2种参数的注册。第一种是kernel通用参数,如console=ttyS0,115200 root=/rdinit/init等。这里以console为例。第二种是kernel下各个driver中需要的参数,在写driver中,如果需要一些启动时可变参数。可以在driver最后加入module_param()来注册一个参数,kernel启动时由cmdline指定该参数的值。这里以drivers/usb/gadget/serial.c中原创 2014-11-15 09:43:30 · 49354 阅读 · 3 评论 -
Cortex-A8处理器memcpy的优化方案
uncached区域到uncached区域memcpy提升3倍,uncached区域到cached区域提升3.5倍,cached区域到uncached区域提升13.2倍,连我自己都吓到了!原创 2016-05-24 19:51:04 · 15005 阅读 · 7 评论 -
linux kernel下输入输出console如何实现
kernel和user空间下都有一个console,关系到kernel下printk的方向和user下printf的方向,实现差别还是很大的。kernel下的console是输入输出设备driver中实现的简单的输出console,只实现write函数,并且是直接输出到设备。user空间下的console,实际就是tty的一个例子,所有操作函数都继承与tty,全功能,可以打开 读写 关闭,所以对于console的读写,都是由kernel的tty层来最终发送到设备。kernel的tty层之下还有ldi原创 2014-11-17 17:02:28 · 31409 阅读 · 7 评论 -
arm-linux内存管理学习笔记(3)-页表前戏
我们在arm-linux内核中看到各种相关宏定义都表示,linux看到的arm一级页目录项有2048个,每个页目录项8bytes,二级页表项是512个。不过arm-mmu的硬件机制却是4096个一级页目录项,每个页表有256个页表项。两种软硬件机制是靠把2个相邻页目录项的页表存储空间连续分配实现平滑过渡的。原创 2016-07-24 17:35:38 · 5342 阅读 · 2 评论 -
/dev/mem可没那么简单
这几天研究了下/dev/mem,发现功能很神奇,通过mmap可以将物理地址映射到用户空间的虚拟地址上,在用户空间完成对设备寄存器的操作,于是上网搜了一些/dev/mem的资料。网上的说法也很统一,/dev/mem是物理内存的全映像,可以用来访问物理内存,一般用法是open("/dev/mem",O_RDWR|O_SYNC),接着就可以用mmap来访问物理内存以及外设的IO资源,这就是实现用户空间驱动的一种方法。用户空间驱动听起来很酷,但是对于/dev/mem,我觉得没那么简单,有2个地方引起我的怀疑:(原创 2015-08-13 14:05:07 · 46156 阅读 · 4 评论 -
kernel如何保证cache数据一致性
那么问题就来了,正因为嵌入式处理器软件管理cache,就需要我们代码主动去操作cache,但在内核开发中很少会直接进行cache操作,cache操作到底在哪里进行的,什么时候需要操作cache。首先想明白一点,为什么要进行cache操作,只能说cache是天使也是魔鬼。cache在提高了系统性能同时却导致了数据的不一致性。嵌入式处理器软件管理cache的初衷就是保证数据一致性。那什么地方需要保证数据一致性呢?对于由CPU完全操作的数据,数据是完全一致的。也就是该数据完全由CPU写读操作,没有对CPU不原创 2015-08-27 10:31:21 · 21999 阅读 · 4 评论 -
熟悉又陌生的udelay
内核开发中经常用到延时函数,最熟悉的是mdelay msleep。虽然经常会使用,但是具体实现却不了解,今天来研究下。这2个函数在实现上有着天壤之别。msleep实现是基于调度,延时期间调用schedule_timeout产生调度,待时间到期后继续运行,该函数实现在kernel/timer.c中。由于linux内核不是实时系统,因此涉及调度的msleep肯定不会精确。今天不细说msleep,有时间再来分析它,今天重点来学习mdelay。mdelay是使用最多的延时函数。它的实现是忙循环,利用了内核原创 2015-07-05 16:25:21 · 7818 阅读 · 1 评论 -
USB枚举过程分析
1. 枚举是什么? 枚举就是从设备读取一些信息,知道设备是什么样的设备,如何进行通信,这样主机就可以根据这些信息来加载合适的驱动程序。调试USB设备,很重要的一点就是USB的枚举过程,只要枚举成功了,那么就已经成功大半了。 USB架构中, hub负责检测设备的连接和断开,利用其中断IN端点(Interrupt IN Endpoint)来向主机(Host)报告转载 2014-12-13 22:31:42 · 6782 阅读 · 2 评论 -
对于字节序小端和大端的思考
从网上可以查到的大小端的解释,小端是低端数据存放在低端地址,大端是高端数据存在低端地址。大小端真的就这么简单吗,不是这样的。可以这样理解: 对于小端处理器,如果要寻址一个word型数据,处理器首先由地址总线发出地址,之后对于由32位数据总线(32位处理器)返回的数据,小端处理器认为0-7位数据线是低端数据,而24-31位数据线为高端数据。 相反,对于大端处理器,寻址一个word型数据,处理器对于数据线返回的数据,认为24-31位数据线为低端数据,而0-7位数据线为高端数据。原创 2014-12-21 23:06:42 · 5603 阅读 · 0 评论 -
linux kernel如何处理大端小端字节序
根据之前的理解,字节序可以认为是处理器主观的概念,就像人如何去看待事物一样,处理器分大端和小端,对于内存的读写,只要保证数据类型一致,就不存在字节序的问题。因此我感觉,字节序不同造成的最大差异在于对于寄存器的读写。因为外设寄存器都是小端的(根据kernel代码得出结论,下面还会在详细解释)根据我之前字节序思考的文章,对于寄存器读写差异,有2种方案:(1)从硬件上解决这个问题,对于32位cpu,将32根数据总线反接,但是这样对于寻址小于32位数据可能有问题,并且不能所有模块都反接(如内存),这还涉及到编原创 2015-02-13 10:53:18 · 6941 阅读 · 0 评论