x86/x86_64处理器提供了4个内存管理寄存器(Memory Management Registers):GDTR、LDTR、IDTR和TR。如下图所示。 Global Descriptor Table Register(GDTR) GDTR寄存器保存GDT的基址和表限(table limit)。基址是GDT的第一个字节的地址,表限(table limit)给出表的大小。 指令LGDT和SGDT是分别用来设置和保存GDTR寄存器的值。上电或重启处理器后,基址默认的值为0,表限(table limit)的值为0FFFFH。在保护模式运行前,作为处理器初始化的一部分,必须在GDTR寄存器中设置新的基址。 在Linux地址映射过程中,会用到GDTR寄存器。在此稍微详细介绍一下指令SGDT,即获取GDTR寄存器的值。SGDT指令的操作如下: Operation IF instruction is SGDT IF OperandSize = 16 THEN DEST[0:15] ← GDTR(Limit); DEST[16:39] ← GDTR(Base); (* 24 bits of base address stored *) DEST[40:47] ← 0; ELSE IF (32-bit Operand Size) DEST[0:15] ← GDTR(Limit); DEST[16:47] ← GDTR(Base); (* Full 32-bit […]
READ MORE »x86/x86_64 CPU控制寄存器(Control Registers)
x86/x86_64 CPU中提供了控制寄存器,来决定CPU的操作模式和当前执行任务的属性。这些寄存器在32位模式下是32bit,在64位模式中,控制寄存器扩展为64位。 CPU架构中共有CR0、CR1、CR2、CR3、CR4、CR8共6个控制寄存器,如下图。 各个控制寄存器的作用如下: CR0:包含当前处理器运行的控制标志。 CR1:保留。 CR2:包含发生页面错误时的线性地址。 CR3:页面目录表(Page Directory Table)的物理地址。 CR4:包含处理器扩展功能的标志位。 CR8:提供对任务优先级寄存器(Task Priority Register)的读写(仅在64位模式下存在)。 对控制寄存器的读写是通过MOV CRn指令来实现 下面代码(注意:本源码是32位系统)可用来读取CRn控制寄存器的值。 #include <linux/module.h> #include <linux/proc_fs.h> static char modname[] = “cr4″; static int cr4; static int my_get_info( char *buf, char **start, off_t off, int count ) { int len = 0; asm(” movl %cr4, %ebx \n movl %ebx, cr4 “); […]
READ MORE »[转]Intel CPU Power Management Overview
Intel处理器电源管理概述PPT,推荐阅读。 •Introduction • Overview of all power states Ø Global States Ø Device States Ø CPU States Ø PCIe Link PM States Ø Sleep States Ø AMT States 点击下载
READ MORE »[转]CPU C-States Power Saving Modes
Everything You Need to Know About the CPU C-States Power Saving Modes http://www.hardwaresecrets.com/article/Everything-You-Need-to-Know-About-the-CPU-C-States-Power-Saving-Modes/611/1 Introduction In order to save energy when the CPU is idle, the CPU can be commanded to enter a low-power mode. Each CPU has several power modes and they are collectively called “C-states” or “C-modes”. In this tutorial we will […]
READ MORE »Linux内核模块加载报错”no symbol version for struct_module”解决办法
编译iscsi_trgt内核模块后,加载模块失败,提示“Invalid module format“,通过dmesg看到内核打印“no symbol version for struct_module“。 [root@xenserver-chen iscsitarget-1.4.20.2]# insmod /root/iscsitarget-1.4.20.2/kernel/iscsi_trgt.ko insmod: error inserting ‘/root/iscsitarget-1.4.20.2/kernel/iscsi_trgt.ko’: -1 Invalid module format
READ MORE »Linux内核死锁(deadlock)检测
业务运行过程中,Linux系统僵死,屏幕无任何有效打印信息,网络中断、键盘鼠标没有任何响应。这种故障现象,可能是因为Linux内核死锁导致。由于无任何有效打印信息,内核日志中也没有记录,就无法定位故障根因。 如何让Linux内核在僵死前打印相关信息,对问题定位尤为关键。其中一个有效手段是打开“Kernel Hacking”选项,然后重新编译内核。 对于Linux内核死锁有帮助的几个配置选项有: [*] Detect Soft Lockups [ ] Panic (Reboot) On Soft Lockups [*] Detect Hung Tasks (120) Default timeout for hung task detection (in seconds) [*] Panic (Reboot) On Hung Tasks [ ] Lock usage statistics [ ] Spinlock debugging: sleep-inside-spinlock checking 下面一个实例是在SLES11.1 2.6.32.12-0.7内核中系统僵死前,检测到内核死锁并panic,打印出了死锁进程和信息。 ftp D ffff88010d7c5978 4472 22481 […]
READ MORE »Linux PCI Express配置空间读写内核实现
在x86/x86_64 CPU中PCI Express扩展配置空间访问 中,我们分析了PCI-E配置空间是如何映射到物理内存地址空间的。 本文介绍Linux内核是如何读写PCI/PCI-E配置空间,包括传统PCI设备256字节配置空间的访问,和PCI-E扩展配置空间如何访问。 点击阅读详细内容
READ MORE »Linux内核空间与用户空间
内核空间(Kernel Space)与用户空间(User Space) 内核空间可以访问所有的CPU指令和所有的内存空间、I/O空间。 用户空间只能访问有限的资源,若需要特殊权限,可以通过系统调用获取相应的资源。 用户空间允许页面中断,而内核空间则不允许。 x86 CPU中用户空间是0-3G的地址范围,内核空间是3G-4G的地址范围。x86_64 CPU用户空间地址范围为0x0000000000000000 – 0x00007fffffffffff,内核地址空间为0xffff880000000000~最大地址。 内核空间和用户空间是针对线性地址空间的。 所有内核进(线)程共用一个地址空间,而用户进程都有各自的地址空间。
READ MORE »x86/x86_64 CPU中PCI Express扩展配置空间访问
PCI Express配置空间 PCI-E是用来互联如计算和通信平台应用中外围设备的第三代高性能I/O总线。PCI-E采用了与PCI相同的使用模型和读写(load-store)通信模型,支持各种常见的事务,如存储器读/写、IO读/写和配置读/写事务。其存储器、IO和配置地址空间与PCI的地址空间相同。PCI Express与PCI系统是软件向后兼容的。
READ MORE »Intel Nehalem服务器中物理内存地址分布
Nehalem架构中系统内存地址空间如下。共有三个基本内存地址区域: (1)低于1MB; (2)1MB~4GB; (3)高于4GB。 TOLM: Top of Low Memory CSR: Control and Status Register
READ MORE »