OK6410A 开发板 (八) 119 linux-5.11 OK6410A arm-linux的栈
2022-08-09 来源:csdn
硬件上:
armv6 有 6个 R13
R13_usr 和 R13_sys 是同一个
还有 R13_svc R13_abt R13_und R13_irq R13_fiq
软件上
linux boot时有一个栈
linux 各种异常处理有栈(5个异常模式,1个system模式)
对应多少个栈?
svc mode 对应每个进程有一个栈?
irq mode 是固定的栈?
abort 呢? und 呢 ? fiq 呢?
system mode 呢?
linux 在 user mode 时 有栈 , (应用程序的栈,每个应用程序有一个栈,有N个应用程序)
boot的栈不管,没啥意思
从线程和异常来说事
1. 线程分类
2. 异常分类
每个线程有两个栈,一个内核(svc)栈,一个用户栈。
异常时,有临时栈(12字节)(irq und abt fiq),然后有长期栈(svc,即用户的内核栈)
临时栈
临时栈的地址及大小
地址 : 位于 全局变量 static struct stack stacks[NR_CPUS]; 中
大小 :12 字节
BOOT过程
boot时的栈
boot栈的地址及大小
地址 : init_stack - init_stack+0x1000
大小 : 4KB
从stext到start_kernel , 没用栈???
从start_kernel 开始, 走在 svc mode???,
start_kernel 运行时的栈, 是 链接出来的(和init_stack 有关),4KB大小
https://blog.csdn.net/u011011827/article/details/116056620
线程分类
idle 内核线程的一个内核栈
内核栈的地址及大小
栈位置: X - X+0x2000 // 'slab task_struct' 中的 stack成员的值为X
栈大小: 8KB
idle 进程的 TCB 分成了 两块
struct task_struct init_task
void *stack; // 用于存放 对应的 thread_info 的 地址
struct thread_info init_thread_info
.task = &init_task // 对于存放 对应的 task_struct 的地址
栈位置: slab task_struct 中的 stack成员的值为栈顶X(X->X+STACK_SIZE为整个栈)
栈大小: 由 arch/arm/include/asm/thread_info.h 中的 THREAD_SIZE 决定 // 8KB 或者16KB
// CONFIG_KASAN=n : 8KB
// CONFIG_KASAN=y : 16KB
init 内核线程的一个内核栈及init用户线程的一个用户栈和内核栈
内核栈的地址及大小
栈位置: X - X+0x2000 // 'slab task_struct' 中的 stack成员的值为X
栈大小: 8KB
用户栈的地址及大小
栈位置: 0xBE80 0000 - 0xBF00 0000
栈大小: 8MB
用户栈的伸缩对于应用程序来说是透明的,应用程序不需要自己去管理栈,这是操作系统提供的功能。
应用程序在刚刚启动的时候(由fork()系统调用复制出新的进程),新的进程其实并不占有任何栈的空间。
当应用程序中调用了函数需要压栈时,会触发一个page fault,内核在处理这个异常里会发现进程需要新的栈空间,于是建立新的VMA并映射内存给用户栈
https://www.tiehichi.site/2020/10/22/Linux%E8%BF%9B%E7%A8%8B%E6%A0%88%E7%A9%BA%E9%97%B4%E5%A4%A7%E5%B0%8F/
栈位置: 0xC0000000-0x01000000 ( 最高处)
load_elf_binary
retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP), executable_stack);
#define CONFIG_PAGE_OFFSET 0xC0000000
#define SZ_16M 0x01000000
#define TASK_SIZE (UL(CONFIG_PAGE_OFFSET) - UL(SZ_16M))
#define TASK_SIZE_26 (UL(1) << 26)
#define STACK_TOP ((current->personality & ADDR_LIMIT_32BIT) ? TASK_SIZE : TASK_SIZE_26)
栈位置: 0xC0000000-0x01000000 ( 最高处)
栈大小: 8MB
ulimit -a看到系统对当前进程的栈size进行了限制,大部分是8M的限制
ulimit -s来修改栈的大小,可以扩充到100M的大小
init_task->signal->rlim
[RLIMIT_STACK] = { _STK_LIM, RLIM_INFINITY },
_STK_LIM即为当前系统中,进程用户栈的虚拟地址空间上限
#define _STK_LIM (8*1024*1024)
异常分类
异常有7个
5+1(rst)+1(swi)
5:
vector_stub 中使用临时栈,然后切换到 swi mode , 使用 swi的栈
1(rst):
直接swi err0
1(swi):
直接使用 swi 的栈
arch/arm/kernel/setup.c
136 /*
137 * Cached cpu_architecture() result for use by assembler code.
138 * C code should use the cpu_architecture() function instead of accessing this
139 * variable directly.
140 */
141 int __cpu_architecture __read_mostly = CPU_ARCH_UNKNOWN;
142
143 struct stack {
144 u32 irq[3];
145 u32 abt[3]; //对应 dabt 和 pabt 异常
146 u32 und[3];
147 u32 fiq[3];
148 } ____cacheline_aligned; // 对应5个异常及其对应的 vector_stub , vector_stub 中 这12个字节 用于 临时 stack .
149
150 #ifndef CONFIG_CPU_V7M
151 static struct stack stacks[NR_CPUS];
152 #endif
start_kernel
setup_arch
setup_processor
cpu_init
setup stacks for re-entrant exception handlers
struct stack *stk = &stacks[cpu];
556 __asm__ (
557 'msr cpsr_c, %1nt'
558 'add r14, %0, %2nt'
559 'mov sp, r14nt'
560 'msr cpsr_c, %3nt'
561 'add r14, %0, %4nt'
562 'mov sp, r14nt'
563 'msr cpsr_c, %5nt'
564 'add r14, %0, %6nt'
565 'mov sp, r14nt'
566 'msr cpsr_c, %7nt'
567 'add r14, %0, %8nt'
568 'mov sp, r14nt'
569 'msr cpsr_c, %9'
570 :
571 : 'r' (stk),
572 PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
573 'I' (offsetof(struct stack, irq[0])),
574 PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
575 'I' (offsetof(struct stack, abt[0])),
576 PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE),
577 'I' (offsetof(struct stack, und[0])),
578 PLC (PSR_F_BIT | PSR_I_BIT | FIQ_MODE),
579 'I' (offsetof(struct stack, fiq[0])),
580 PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
581 : 'r14');
上一篇:OK6410A 开发板 (八) 120 linux-5.11 OK6410A cache 配置
下一篇:OK6410A 开发板 (八) 118 linux-5.11 OK6410A arm异常原因及linux应用场景及结果
- 〖Linux〗OK6410a蜂鸣器的驱动程序编写全程实录
- 开发环境搭建 (一) OK6410A 开发环境 1官方环境 OK
- 开发环境搭建 (一) OK6410A 开发环境 2 更改环境 OK
- 开发环境搭建 (一) OK6410A 开发环境 3 更改环境 FAIL
- 开发环境搭建 (二) OK6410A 开发环境 其他
- 开发环境搭建 (一) OK6410A 开发环境 4 更改环境 OK
- OK6410A 开发板 (二) 环境熟悉
- OK6410A 开发板 (三) u-boot-1.1.6 boot 解析
- OK6410A 开发板 (四) OK6410A 裸机代码
- OK6410A 开发板 (五) u-boot-2021.01 移植 到 ok6410a