`
freesoftman
  • 浏览: 319818 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Linux cpu核心代码set_bit的实现分析

 
阅读更多

在arm系统中,对cpu核的设计。使用了位技术变量来代表每个cpu的使用情况。

但是这里考虑到多核对同一变量的设置,因为有了多核访问,于是乎就需要防止冲突的机制。真样产生了特殊情况的操作位接口--> macro bitop, name, instr。

使用汇编的形式来完成。主要的技术,是arm arch6中的strex, ldrex。

 

STREX指令的英文解释如下:

STREX (Store Register Exclusive) performs a conditional store to memory. The store only occurs if the
executing processor has exclusive access to the memory addressed.

也就是说,这条存储指令具有cpu核的排它性。只有cpu具有独立访问该memor addressed的时候,才可以存储。否则,cpu存储指令失败。接下来就看看具体的使用方式。

 

语法如下:

Syntax
STREX{<cond>} <Rd>, <Rm>, [<Rn>]

where:
<cond> Is the condition under which the instruction is executed. The conditions are defined in The
      condition field on page A3-3. If <cond> is omitted, the AL (always) condition is used.
<Rd> Specifies the destination register for the returned status value. The value returned is:
    0
   if the operation updates memory
  1
 if the operation fails to update memory.
<Rm> Specifies the register containing the word to be stored to memory.
<Rn> Specifies the register containing the address.

Rd是一个返回该存储状态寄存器,这里可以知道这次存储的状况。

Rm保留了需要存储到memory的值。

Rn 指定了将Rm值保存到memory的地址。

 

 

LDREX指令的英文解释如下:

LDREX (Load Register Exclusive) loads a register from memory, and:
• if the address has the Shared memory attribute, marks the physical address as exclusive access for the
   executing processor in a shared monitor
• causes the executing processor to indicate an active inclusive access in the local monitor.

 

语法如下:

LDREX{<cond>} <Rd>, [<Rn>]
where:
<cond> Is the condition under which the instruction is executed. The conditions are defined in The
      condition field on page A3-3. If <cond> is omitted, the AL (always) condition is used.
<Rd> Specifies the destination register for the memory word addressed by <Rd>.
<Rn> Specifies the register containing the address.

操作如下:

MemoryAccess(B-bit, E-bit)
if ConditionPassed(cond) then
processor_id = ExecutingProcessor()
Rd = Memory[Rn,4]
physical_address = TLB(Rn)
if Shared(Rn) == 1 then
MarkExclusiveGlobal(physical_address,processor_id,4)
MarkExclusiveLocal(physical_address,processor_id,4)
/* See Summary of operation on page A2-49 */

 

 

在ARM手册中有如下说明使用STREX与LDREX的范围:

Use STREX in combination with LDREX to implement inter-process communication in multiprocessor and
shared memory systems

Use LDREX in combination with STREX to implement inter-process communication in shared memory
multiprocessor systems. For more information see Synchronization primitives on page A2-44. The
mechanism can also be used locally to ensure that an atomic load-store sequence occurs with no intervening
context switch.

指令总结:

1,这条指令是用于多核处理器中,用于处理多核访问共享内存的排他性而设计的,单核最好不要使用。

因为比一般的存储指令要耗时。

从STREX指令的伪操作可以猜测出:

MemoryAccess(B-bit, E-bit)
processor_id = ExecutingProcessor()
if ConditionPassed(cond) then
if (CP15_reg1_Ubit == 0) then
if address[0] == 0b0 then
Memory[address,2] = Rd[15:0]
else
Memory[address,2] = UNPREDICTABLE
else
/* CP15_reg1_Ubit ==1 */
Memory[address,2] = Rd[15:0]
if Shared(address) then
/* ARMv6 */
physical_address = TLB(address)
ClearExclusiveByAddress(physical_address,processor_id

 

2,LDREX与STREX要一起共同使用构成同步原语。

 

有了这些知识点的普及, 我们在来分析bitop这个宏汇编是如何实现设置一个long数组中的某个位。

 

bitop宏代码如下:

 

	.macro	bitop, name, instr
ENTRY(	\name		)
UNWIND(	.fnstart	)
	ands	ip, r1, #3
	strneb	r1, [ip]		@ assert word-aligned
	mov	r2, #1
	and	r3, r0, #31		@ Get bit offset
	mov	r0, r0, lsr #5
	add	r1, r1, r0, lsl #2	@ Get word offset
	mov	r3, r2, lsl r3
1:	ldrex	r2, [r1]
	\instr	r2, r2, r3
	strex	r0, r2, [r1]
	cmp	r0, #0
	bne	1b
	bx	lr
UNWIND(	.fnend		)
ENDPROC(\name		)
	.endm

 

我们使用实例,

set_bit(cpumask_check(cpu), cpumask_bits(dstp));来分析该汇编代码。

 

化间成:

set_bit(int cpu, long * (maskp)->bits);

所以对于汇编来说:bitop    _set_bit, orr   展开前。

r0 = cpu;

r1 = long型数据的首地址,用于存放位状态的存储器。

instr = orr指令。

 

第一模块: 内存对齐检测

    ands    ip, r1, #3
    strneb    r1, [ip]        @ assert word-aligned

 

主要看一看long型的数据首地址是否位word-aligned, 如果不对齐,去访问0地址空间,引起NULL异常。

 

第二模块:将r0与32位进行mod操作,获取位偏移量,和long数组的偏移量。

    mov    r2, #1
    and    r3, r0, #31        @ Get bit offset
    mov    r0, r0, lsr #5
    add    r1, r1, r0, lsl #2    @ Get word offset
    mov    r3, r2, lsl r3

 

1,将r2 = = 1  (mov    r2, #1)

2,%操作,保留r0中32位中的余数到r3寄存器中,也就是位的偏移量。(and    r3, r0, #31)

3,获得参数中parm0中的word偏移量(mov    r0, r0, lsr #5),这个时候,r0为原始parm0中的long数组偏移量。

4,将指针转到parm1,long数组中的目标long数据地址。(add    r1, r1, r0, lsl #2),r1存放的是param1中相应parm0位的整数偏移量。

5,r3是param0中具体某个long数据的偏移量设置成1(mov    r3, r2, lsl r3)

 

 

第三模块:orr操作,并且保存结果到memory中。

1:    ldrex    r2, [r1]
    \instr    r2, r2, r3
    strex    r0, r2, [r1]
    cmp    r0, #0
    bne    1b

 

1,使用多核同步原语  ldrex, 获取r1地址中的数据。保存到r2中。(ldrex    r2, [r1])

2,使用orr,或操作, 将保存在r3中的设置位与r1地址中的数据进行or操作,完成指定位的操作。(\instr    r2, r2, r3)

3,通过多核同步原语将r2中的新值存储到r1指定的地址。

4,判断该多核存储操作是否完成,如果完成,返回,否则重复进行。

 

到这里, 就完成了arm set_bit的汇编代码分析。   可以看到,这里使用了ldrex与strex同步原语。

避免了多核之间的数据不同步问题。

 

 

 (该博客是原创,转载请注明原创地址。 谢谢!)

 

 

分享到:
评论

相关推荐

    嵌入式linux CAN 应用测试代码

    测试代码会检查错误标志,如OVERLOAD、BIT_ERROR等,确保在异常情况下能正确响应。 5. **CAN过滤器设置**:为了减少不必要的通信开销,可以设置CAN接收过滤器。这可以通过`can_setsockopt()`函数实现,允许只接收...

    Select函数实现原理分析

    `select`函数的核心在于其能够有效地检测多个文件描述符的状态变化,并且在没有状态变化的情况下能够进入休眠状态以避免不必要的CPU消耗。这一机制主要依赖于操作系统级别的支持,特别是通过驱动程序提供的功能实现...

    Fundamentals of Linux System and Programming

    同时,也会涉及文件权限的三位数字表示法和特殊权限如setuid、setgid和sticky bit。 网络和进程管理也是课程的重点。学习者将了解如何查看和管理系统中的进程,如使用ps、top和kill命令。此外,还将探讨网络配置、...

    A10+Linux+SPI设备驱动开发-2012.1.31.pdf

    总结来说,SPI总线是一种高效的串行通信总线,而Linux SPI驱动框架提供了一套完整的工具集来实现SPI设备驱动的开发。了解并掌握SPI总线的工作原理及Linux SPI驱动框架的相关知识,对于从事嵌入式系统开发的技术人员...

    <LINUX奥秘>pdf文档下载

    - **硬件资源分配**:合理规划CPU核心、内存大小等硬件资源的分配。 ### Linux应用开发与服务部署 #### 1. 开发环境搭建 - **编译器与解释器**:安装GCC、Python等编译器或解释器。 - **版本控制系统**:Git是目前...

    LINUX网站建设技术指南目录

    - **概念**: TCP/IP是Internet的核心协议,Linux实现了完整的TCP/IP协议栈,用于实现网络通信。 - **特点**: Linux的TCP/IP实现支持IPv4和IPv6,具备高稳定性和安全性。 ##### 1.3 IPv6 - **IPv6与IPv4对比**: IPv6...

    uboott移植实验手册及技术文档

    4、交叉编译器 arm-softfloat-linux-gnu-gcc-3.4.5 【实验步骤】 一、建立自己的平台类型 (1)解压文件 #tar jxvf u-boot-1.3.1.tar.bz2 (2)进入 U-Boot源码目录 #cd u-boot-1.3.1 (3)创建自己的开发板...

    C语言讲义.doc

    - **内核模式**:操作系统的核心部分运行在此模式下,可以直接访问所有硬件资源。 **示例代码**(伪代码): ```c #include int main() { // 用户模式下的代码 printf("Running in user mode.\n"); // 内核...

    Computer Organization&Design全答案

    - **过程**: 包括词法分析、语法分析、语义分析、代码生成等阶段。 - **应用**: 开发应用程序时必不可少的工具。 ### 23. VLSI (Very Large Scale Integration) - **定义**: VLSI是指在单一芯片上集成大量晶体管的...

    ARM指令缩写整理

    - **应用场景**: MMU在操作系统管理和实现虚拟内存方面扮演着核心角色。 #### 8. AMBA (Advanced Microcontroller Bus Architecture) - **定义**: AMBA是一种用于定义微控制器内部总线结构的标准,主要用于连接...

    计算机组织与设计经典教材习题答案

    - **工作流程**:包括词法分析、语法分析、语义分析、代码生成等阶段。 - **应用**:用于开发应用程序。 **1.2325 极大规模集成电路(Very Large Scale Integration, VLSI)** - **定义**:VLSI是指集成度极高的...

    计算机概论课后习题答案.doc

    1. **个人计算机(PC)**:指供个人使用的独立计算设备,通常包含CPU、内存、硬盘等核心组件。 2. **中央处理器(CPU)**:计算机的核心部件,执行计算机程序中的指令,负责运算和控制任务。 3. **随机访问内存...

    c语言编写单片机技巧

    Transform)、频谱分析、图像处理的分析等领域,DSP正在大量进入嵌入式市场。 18. MCU在射频控制时,MCU的时钟(晶振)、数据线会辐射基频或基频的倍频,被低噪放LNA放大后进入混频,出现带内的Spur,无法滤除...

Global site tag (gtag.js) - Google Analytics