linux源码中的struct pt_regs数据结构是干什么的?

2024-05-14 02:27

1. linux源码中的struct pt_regs数据结构是干什么的?

该结构体描述了在执行系统调用时,用户态下的CPU寄存器在核心态的栈中的保存情况。
通过这个参数,sys_execve能获得保存在用户空间的以下信息:可执行文件路径的指针(regs.ebx中)、命令行参数的指针(regs.ecx中)和环境变量的指针(regs.edx中)。

linux源码中的struct pt_regs数据结构是干什么的?

2. extern volatile struct GPIO_DATA_REGS GpioDataRegs什么意思

extern volatile struct GPIO_DATA_REGS GpioDataRegs;
分解:
结构体,在代码中某处,肯定会有类似的定义, GPIO_DATA_REGS 是结构名
struct GPIO_DATA_REGS 
{
};
而GpioDataRegs是该结构类型的变量名
extern 是外部声明,就是说GpioDataRegs这个变量已经在其他文件中定义了,你这句只是说,你要用那个全局变量,你这个和那边那个是同一个变量

volatile 这个是告诉编译器不要对你的这个变量做优化, 有时候编译时,如果编译器发现你的变量没有用,或做的是无效操作,它就帮你优化掉了,比如你读一个寄存器的值,但是你又不用,类似于这样的

加了这个volatile之后就不会被优化掉了

3. excel表中标solvefork是什么意思

1、使用fork()或者vfork()函数创建新的进程

2、条用exec函数族修改创建的进程。使用fork()创建出来的进程是当前进程的完全复制,然而我们创建进程是为了让新的进程去执行新的程序,因此,就需要用到exec函数族对创建出来的新进程进行修改,让他拥有和父进程不一样的东西,修改后就可以执行新的程序,当然,修改后的子进程包含了要执行程序的信息。

在Linux中,fork()和vfork()就是用于创建进程的两个函数,他们的相关信息如下:

创建进程函数:

pid_t fork(void)//成功返回0,失败返回-1

fork()用于创建新的进程,所创建进程为当前进程的子进程,可以通过fork()函数的返回质6来控制进程是在父进程中还是在子进程中。如果运行在父进程中,则返回PID为子进程的进程号,如果在子进程中,则返回的PID为0

pid_t vfork(void)//成功返回0,失败返回-1

vfork()函数和fork()函数比较类似,都用于创建子进程。只是其用于创建新的进程,父子进程共享虚拟内存空间。然而在内核中,vfork()的实现任然调用fork()函数,调用函数如下:

sys_vfork(struct pt_regs *regs)
{
        return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gr[30], regs, 0, NULL, NULL);
}

excel表中标solvefork是什么意思

4. linux系统中的中断指令是什么??

什么是中断
Linux 内核需要对连接到计算机上的所有硬件设备进行管理,毫无疑问这是它的份内事。如果要管理这些设备,首先得和它们互相通信才行,一般有两种方案可实现这种功能:
轮询(polling) 让内核定期对设备的状态进行查询,然后做出相应的处理;中断(interrupt) 让硬件在需要的时候向内核发出信号(变内核主动为硬件主动)。
第一种方案会让内核做不少的无用功,因为轮询总会周期性的重复执行,大量地耗用 CPU 时间,因此效率及其低下,所以一般都是采用第二种方案 。
对于中断的理解我们先看一个生活中常见的例子:QQ。第一种情况:你正在工作,然后你的好友突然给你发送了一个窗口抖动,打断你正在进行的工作。第
二种情况:当然你有时候也会每隔 5 分钟就去检查一下 QQ 
看有没有好友找你,虽然这很浪费你的时间。在这里,一次窗口抖动就可以被相当于硬件的中断,而你就相当于 CPU,你的工作就是 CPU 
这在执行的进程。而定时查询就被相当于 CPU 的轮询。在这里可以看到:同样作为 CPU 和硬件沟通的方式,中断是硬件主动的方式,较轮询(CPU 
主动)更有效些,因为我们都不可能一直无聊到每隔几分钟就去查一遍好友列表。
CPU 
有大量的工作需要处理,更不会做这些大量无用功。当然这只是一般情况下。好了,这里又有了一个问题,每个硬件设备都中断,那么如何区分不同硬件呢?不同设
备同时中断如何知道哪个中断是来自硬盘、哪个来自网卡呢?这个很容易,不是每个 QQ 号码都不相同吗?同样的,系统上的每个硬件设备都会被分配一个 
IRQ 号,通过这个唯一的 IRQ 号就能区别张三和李四了。
从物理学的角度看,中断是一种电信号,由硬件设备产生,并直接送入中断控制器(如 
8259A)的输入引脚上,然后再由中断控制器向处理器发送相应的信号。处理器一经检测到该信号,便中断自己当前正在处理的工作,转而去处理中断。此后,
处理器会通知 OS 已经产生中断。这样,OS 
就可以对这个中断进行适当的处理。不同的设备对应的中断不同,而每个中断都通过一个唯一的数字标识,这些值通常被称为中断请求线。

5. DSP2812编程调试时出现这个错误error: struct "EVA_REGS" has no field "CAPCONA"

这个是EV外设的captureA模块没有地址,看下头文件里有这个寄存器的定义吗?并且引用这个头文件了吗?再就是要在CMD文件中有这个寄存器的地址分配空间。

DSP2812编程调试时出现这个错误error: struct "EVA_REGS" has no field "CAPCONA"

6. ARMv8 Linux内核错误处理过程分析怎么解决

1.1 Linux内核异常处理相关文件
Linux内核中,异常处理主要由两个文件完成,entry.S和traps.c,当然还有一些其它异常处理函数分布于fault.c, memory.c等等。entry.S包含异常的入口、进入异常处理C函数前的压栈、退出C函数前的出栈、一些fork函数相关的处理代码(暂不分析)、任务切换汇编处理过程(cpu_switch_to函数,暂不分析)。traps.c主要包含异常处理C函数。
本文主要分析entry.S,对于traps.c作简要介绍。
1.2 执行kernel_entry之前的栈

1.3 执行kernel_entry时的栈

1.4 执行kernel_exit 时的栈

1.5 entry.s代码分析
/*
 * Low-level exception handling code
 *
 * Copyright (C) 2012 ARM Ltd.
 * Authors:	Catalin Marinas 
 *		Will Deacon 
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */

#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 

/*
 * Bad Abort numbers
 *-----------------
 */
#define BAD_SYNC		0
#define BAD_IRQ		1
#define BAD_FIQ		2
#define BAD_ERROR	3

//根据该结构体内容
/*
struct pt_regs {			
	union {
		struct user_pt_regs user_regs;//结构体user_pt_regs和结构体pt_regs内容一样
		struct {					//共用体存储31个通用寄存器,外加sp,pc,pstate三个特殊寄存器
									//该结构体用于异常处理的压栈弹栈操作
			u64 regs[31];
			u64 sp;
			u64 pc;
			u64 pstate;
		};
	};
	u64 orig_x0;
	u64 syscallno;
};
*/


//S_FRAME_SIZE定义在asm-offsets.c中,DEFINE(S_FRAME_SIZE,sizeof(struct pt_regs));
//即结构体pt_regs的大小,结构体pt_regs的定义见上面
//S_LR定义:DEFINE(S_LR,offsetof(struct pt_regs, regs[30]));
//即31号寄存器在结构体pt_regs中的偏移量
//阅读以下内容请参考图1 和图2
	.macro	kernel_entry, el, regsize = 64
	sub	sp, sp, #S_FRAME_SIZE - S_LR	// room for LR, SP, SPSR, ELR,见图2中sp'指向的位置			
	.if	\regsize == 32
	mov	w0, w0				// zero upper 32 bits of x0
	.endif
	/*
	 *.macro	push, xreg1, xreg2	//压栈两个寄存器
	 *stp	\xreg1, \xreg2, [sp, #-16]!	//注意!!!push指令也改变sp的值!!!
	 *.endm
	 */
	push	x28, x29		//进行压栈操作,push也是一个宏定义,因为ARMv8没有push指令,用stp代替
	push	x26, x27	
	push	x24, x25
	push	x22, x23
	push	x20, x21
	push	x18, x19
	push	x16, x17
	push	x14, x15
	push	x12, x13
	push	x10, x11
	push	x8, x9
	push	x6, x7
	push	x4, x5
	push	x2, x3
	push	x0, x1		//此时sp指向位置见图2中sp''
	.if	\el == 0		//如果异常级是el0,把el0的sp栈指针给x21寄存器
	mrs	x21, sp_el0
	.else
	add	x21, sp, #S_FRAME_SIZE	//如果异常级不是el0,把sp指针指向的地方加上pt_regs大小后的地址放入x21,
								//即指向没进入kernel_entry函数钱的sp指向的位置,见图2中x21指向的地址
	.endif
	mrs	x22, elr_el1			//把el1的lr寄存器给x22
	mrs	x23, spsr_el1			//把spsr给x23
	stp	lr, x21, [sp, #S_LR]	//把lr,x21寄存器存入sp+S_LR指向的地方
	stp	x22, x23, [sp, #S_PC]	//把lr,存入sp+s_PC指向的位置,用于异常返回

	/*
	 * Set syscallno to -1 by default (overridden later if real syscall).
	 */
	.if	\el == 0
	mvn	x21, xzr
	str	x21, [sp, #S_SYSCALLNO]
	.endif
	/*
	 * Registers that may be useful after this macro is invoked:
	 *
	 * x21 - aborted SP
	 * x22 - aborted PC
	 * x23 - aborted PSTATE
	*/
	.endm

	
	.macro	kernel_exit, el, ret = 0
	//把此时sp(即图2中sp'')+S_PC位置处开始的16字节内容分别给x21,x22
	//即把栈中存的x21和x22内容取出来
	ldp	x21, x22, [sp, #S_PC]		// load ELR, SPSR
	.if	\el == 0
	ldr	x23, [sp, #S_SP]		// load return stack pointer,取出
	.endif
	.if	\ret
	ldr	x1, [sp, #S_X1]			// preserve x0 (syscall return),如果ret=1,则保存x0,用于系统调用,暂不分析
	add	sp, sp, S_X2
	.else
	pop	x0, x1				//如果ret=0,弹出x0,x1
	.endif
	pop	x2, x3				// load the rest of the registers
	pop	x4, x5
	pop	x6, x7
	pop	x8, x9
	msr	elr_el1, x21			// set up the return data,把前面弹出的x21,x22分别赋值给elr_el1,spsr_el1
	msr	spsr_el1, x22
	.if	\el == 0
	msr	sp_el0, x23
	.endif
	pop	x10, x11
	pop	x12, x13
	pop	x14, x15
	pop	x16, x17
	pop	x18, x19
	pop	x20, x21
	pop	x22, x23
	pop	x24, x25
	pop	x26, x27
	pop	x28, x29
	ldr	lr, [sp], #S_FRAME_SIZE - S_LR	// load LR and restore SP,把lr弹出
	eret					// return to kernel,异常返回,该指令会把lr给pc,完成跳转
	.endm

	.macro	get_thread_info, rd
	mov	\rd, sp
	and	\rd, \rd, #~((1 << 13) - 1)	// top of 8K stack
	.endm

/*
 * These are the registers used in the syscall handler, and allow us to
 * have in theory up to 7 arguments to a function - x0 to x6.
 *
 * x7 is reserved for the system call number in 32-bit mode.
 */
sc_nr	.req	x25		// number of system calls
scno	.req	x26		// syscall number
stbl	.req	x27		// syscall table pointer
tsk	.req	x28		// current thread_info

/*
 * Interrupt handling.
 */
	.macro	irq_handler
	ldr	x1, handle_arch_irq
	mov	x0, sp
	blr	x1
	.endm

	.text

/*
 * Exception vectors.
 */
	.macro	ventry	label	//这里是2^7对齐,即对齐到内存地址的0x80
	.align	7
	b	\label
	.endm

	.align	11
	
/* ENTRY也是一个宏,定义在include/linkage.h中
* #ifndef ENTRY
* #define ENTRY(name) \
* .globl name; \
* ALIGN; \
* name:
* #endif

7. Linux下通过哪个命令怎么查看中断

与Linux设备驱动中中断处理相关的首先是申请与释放IRQ的API request_irq()和free_irq()。
C++是一种面向对象的计算机程序设计语言,由美国AT&T贝尔实验室的本贾尼·斯特劳斯特卢普博士在20世纪80年代初期发明并实现,最初它被称作“C with Classes”(包含类的C语言)。
它是一种静态数据类型检查的、支持多重编程范式的通用程序设计语言,支持过程化程序设计、数据抽象、面向对象程序设计、泛型程序设计等多种程序设计风格。

在C基础上,一九八三年又由贝尔实验室的Bjarne Strou-strup推出了C++,C++进一步扩充和完善了C语言,成为一种面向 对象的程序设计语言。
C++目前流行的编译器最新版本是Borland C++ 4.5,Symantec C++ 6.1,和Microsoft Visual C++ 2012。

Linux下通过哪个命令怎么查看中断

8. Linux内核数据结构有哪些

Linux内核中的基本数据结构和算法
网页链接