在《Linux内存地址映射》(http://ilinuxkernel.com/?p=1276),详细介绍了在32位x86 CPU中Linux内核地址映射过程,并且给出实验验证整个地址映射过程。 64位CPU中,地址映射稍微复杂,本文介绍Linux内核在x86_64 CPU中地址映射过程,同样给出实验和源码,验证整个地址映射过程。 完整文档下载地址:Linux内核在x86_64 CPU中地址映射 实验源码下载地址:Memory_Address_Mapping_x86-64
READ MORE »Posts in category 内核基础
Linux内存地址映射
在Intel体系结构的CPU中,现代操作系统如Linux都采用内存保护模式来管理内存。我们看Linux内核中的内存管理相关内容时,会遇到一个基本问题:普通用户程序中的地址是如何转换到内存上的物理地址的?IA-32架构的CPU规定地址映射过程是逻辑地址–>线性地址–>物理地址。Linux既然能在Intel架构的CPU上运行,就要遵守这个规定,那么Linux又是如何进行地址映射的?
READ MORE »Linux CPU占用率原理与精确度分析
Linux系统中CPU占用率是如何计算的?内核如何统计和更新CPU使用信息?Linux系统 计算CPU占用率方法是否准确? 本文将较为详细分析这些内容。文档内容目录如下: 1 CPU占用率计算原理… 3 1.1 相关概念… 3 1.2 CPU占用率计算… 4 2 CPU占用率内核实现… 6 3 Linux CPU占用率精确性分析… 10 3.1 /proc/stat中的数据单位精度… 10 3.2 CPU利用率统计信息更新… 11 3.3 CPU利用率精确性分析… 12 4 Linux CPU占用率是否准确?… 12 4.1 Linux CPU占用率不准确情形… 13 4.2 top命令CPU使用率准确吗?… 13 4.2.1 进程调度时机… 14 4.2.2 进程调度次数观察… 14 点击下载完整文章:Linux CPU占用率原理与精确度分析
READ MORE »Linux用户程序如何访问物理内存
用户态的程序都是在内存保护模式下使用内存,无法直接访问物理内存。同时用户程序使用的地址,也并不是物理地址,而是逻辑地址。至于这些逻辑地址对应的物理内存在哪里,用户进程本身并不知道。 通过用户程序若想访问物理内存,我们需要通过内核才能实现。本文介绍基于内核模块的方式,实现在Linux中用户态程序访问所有物理内存。 1、内核模块编写 通过文件读写的方式,实现物理地址访问。将物理地址,作为参数pos传递。 ssize_t my_read( struct file *file, char *buf, size_t count, loff_t *pos ) 在内核代码中,是无法直接访问物理地址的,代码能访问的都是逻辑地址。此时我们需要先将物理地址转换成逻辑地址,才能在代码中对地址读写。 物理地址转换成逻辑地址方法: 1)根据物理地址,计算出对应的页面号和页内偏移 page_number = *pos / PAGE_SIZE; page_indent = *pos % PAGE_SIZE; 2)将页面号找到对应的页面指针 注意在2.6.32及以上内核中,没有导出mem_map符号,只能通过 pfn_to_page()来找到对应的页面指针。 #if 0 pp = pfn_to_page( page_number); #else […]
READ MORE »Linux内核报错“No irq handler for vector (irq -1)”原因
系统运行过程中,报告错误“kernel:do_IRQ: 5.218 No irq handler for vector (irq -1)”。从错误打印来看,是中断向量-1没有中断处理程序。 我们来看一下该错误语句来源,在Linux中断处理函数do_IRQ()函数中打印(243~244行)。 00226: unsigned int __irq_entry do_IRQ(struct pt_regs *regs) 00227: { 00228: struct pt_regs *old_regs = set_irq_regs(regs); 00229: 00230: /* high bit used in ret_from_ code*/ 00231: unsigned vector = ~regs->orig_ax; 00232: unsigned irq; 00233: 00234: exit_idle(); 00235: irq_enter(); 00236: 00237: irq = __get_cpu_var(vector_irq)[vector]; 00238: […]
READ MORE »[转]Embedded Linux kernel and driver development
非常好的Linux内核和驱动开发参考资料,强烈推荐。 来源:http://freeelectrons.com/docs/kernel 点击:下载 Loadable kernel modules Memory management I/O memory and ports Character drivers Processes and scheduling Sleeping, Interrupt management Handling concurrency Debugging mmap Device and driver model
READ MORE »Linux内核原子操作
本文基linux内核版本 2.6.32-131.17.1.el6.i686源码。 1、原子读、赋值 00016: /** 00017: *atomic_read-readatomicvariable 00018: * @v:pointeroftypeatomic_t 00019: * 00020: *Atomicallyreadsthevalueof @v. 00021: */ 00022: staticinlineint atomic_read(constatomic_t*v) 00023: { 00024: returnv–>counter; 00025: } 00026: 00027: /** 00028: *atomic_set-setatomicvariable 00029: * @v:pointeroftypeatomic_t 00030: * @i:requiredvalue 00031: * 00032: *Atomicallysetsthevalueof @vto @i. 00033: */ 00034: staticinlinevoid atomic_set(atomic_t*v,inti) 00035: { 00036: v–>counter= […]
READ MORE »Linux内核加载mptsas驱动栈信息
内核启动时,加载基于LSISAS1068E控制器mptsas动栈信息,对了解驱动有帮助。该内核栈信息基于2.6.32-71.el6内核。 scsi0 : ioc0: LSISAS1068E B3, FwRev=011a0000h, Ports=1, MaxQ=266, IRQ=32 **************************************** tie the class to the device device: ‘host0’: device_add Pid: 419, comm: modprobe Not tainted 2.6.32-71.el6.debug #7 Call Trace: [<ffffffff8132bf53>] device_add+0x5b3/0x690 [<ffffffff813434e6>] scsi_add_host_with_dma+0xc6/0x240 [<ffffffffa0048b6c>] mptsas_probe+0x37c/0x510 [mptsas] [<ffffffff812765c7>] local_pci_probe+0x17/0x20 [<ffffffff812777b1>] pci_device_probe+0x101/0x120 [<ffffffff8132ec92>] ? driver_sysfs_add+0x62/0x90 [<ffffffff8132ee30>] driver_probe_device+0xa0/0x2a0 [<ffffffff8132f0db>] __driver_attach+0xab/0xb0 [<ffffffff8132f030>] ? __driver_attach+0x0/0xb0 [<ffffffff8132e094>] bus_for_each_dev+0x64/0x90 [<ffffffff8132ebce>] driver_attach+0x1e/0x20 […]
READ MORE »Linux内核启动设备加载栈信息
内核启动时,加载设备栈信息,对了解驱动有帮助。该内核栈信息基于2.6.32-71.el6内核。 **************************************** tie the class to the device device: ‘tty35’: device_add Pid: 1, comm: swapper Not tainted 2.6.32-71.el6.debug #7 Call Trace: [<ffffffff8132bf53>] device_add+0x5b3/0x690 [<ffffffff8133519b>] ? pm_runtime_init+0xcb/0xe0 [<ffffffff8132c04e>] device_register+0x1e/0x30 [<ffffffff8132c278>] device_create_vargs+0x108/0x180 [<ffffffff8132c321>] device_create+0x31/0x40 [<ffffffff812f39ae>] tty_register_device+0x9e/0x140 [<ffffffff8116ff10>] ? exact_lock+0x0/0x20 [<ffffffff8116fd20>] ? exact_match+0x0/0x10 [<ffffffff812f3b5d>] tty_register_driver+0x10d/0x230 [<ffffffff818f5400>] ? tty_init+0x0/0xfa [<ffffffff818f5cd7>] vty_init+0x15d/0x17d [<ffffffff818f54f6>] tty_init+0xf6/0xfa [<ffffffff8100a04c>] do_one_initcall+0x3c/0x1d0 [<ffffffff818c1839>] kernel_init+0x252/0x2a8 [<ffffffff810141ca>] child_rip+0xa/0x20 […]
READ MORE »Linux内核双链表
1 定义 双链表的定义在文件<include/linux/list.h>中。 00019: struct list_head{ 00020: structlist_head*next,*prev; 00021: };
READ MORE »