Linux多核CPU启动内核调试(详细)总结

news2024/12/30 3:03:37

目录

    • 一、综述
    • 二、调试流程简介
      • 2.1 大体流程
      • 2.2 spin-table简介
    • 三、uboot和内核配置
      • 3.1 uboot配置
      • 3.2 timer配置
      • 3.3 GIC中断配置
      • 3.4 驱动确认
      • 3.5 SMP配置
      • 3.6 内核config配置
    • 四、其他相关链接
      • 1、[交叉编译linux内核总结](https://blog.csdn.net/Luckiers/article/details/124531266)
      • 2、[uboot方式启动硬盘手动制作的根文件系统方案](https://blog.csdn.net/Luckiers/article/details/122476023)
      • 3、[Linux下设备树dts内容总结](https://blog.csdn.net/Luckiers/article/details/124772722)

一、综述

本文主要工作中围绕ARM A55的EVB版多核启动问题进行分析,涉及到timer、gic中断模块,详细整理了整个过程。
目标机器:ARM A55 8核CPU
交叉编译环境:Ubuntu 22.04.2 LTS
内核版本:5.15.79

二、调试流程简介

2.1 大体流程

本文重点讲述内核调试过程,uboot部分讲述相关配置,本次使用spin-table方式启动多核、涉及ARM通用时钟模块,GIC500中断,整体过程如下:
1、uboot编译;
2、内核相关配置打开;
3、内核相关模块驱动确认;
4、内核编译;
5、linux系统定制;

在这里插入图片描述

2.2 spin-table简介

spin-table方式的多核启动方式,顾名思义在于自旋,主处理器和从处理器上电都会启动,主处理器先启动,从处理器在spin_table_secondary_jump处wfe睡眠,主处理器通过修改设备树的cpu节点的cpu-release-addr属性为spin_table_cpu_release_addr,这是从处理器的释放地址所在的地方,主处理器进入内核后,会通过smp_prepare_cpus函数调用spin-table 对应的cpu操作集的cpu_prepare方法从而在smp_spin_table_cpu_prepare函数中设置从处理器的释放地址为secondary_holding_pen这个内核函数,然后通过sev指令唤醒从处理器,从处理器继续从secondary_holding_pen开始执行(从处理器来到了内核的世界),发现secondary_holding_pen_release不是自己的处理编号,然后通过wfe继续睡眠,当主处理器完成了大多数的内核组件的初始化之后,调用smp_init来来开始真正的启动从处理器,最终调用spin-table 对应的cpu操作集的cpu_boot方法从而在smp_spin_table_cpu_boot将需要启动的处理器的编号写入secondary_holding_pen_release中,然后再次sev指令唤醒从处理器,从处理器得以继续执行(设置自己异常向量表,初始化mmu等),最终在idle线程中执行wfi睡眠。其他从处理器也是同样的方式启动起来,同样最后进入各种idle进程执行wfi睡眠,主处理器继续往下进行内核初始化,直到启动init进程,后面多个处理器都被启动起来,都可以调度进程,多进程还会被均衡到多核。

三、uboot和内核配置

3.1 uboot配置

1、配置时钟频率,影响uboot中uart时钟和启动linux内核timer时钟
#define SCFG_SYS_CLOCK 100000000
在这里插入图片描述

#define COUNTER_FREQUENCY 200000000 // 200 MHz generic timer clock
在这里插入图片描述

2、设置CPU_RELEASE_ADDR地址
该地址为DDR中一段地址即可,不可与uboot、内核加载地址重合,建议放在内存的后面部分
/* #define CPU_RELEASE_ADDR infa_slave_cores_halt */
#define CPU_RELEASE_ADDR 0x9b0000000
uboot在启动后将该值存放在X1寄存器中,后续传给内核。

该地址的作用:
芯片上电后primary cpu开始执行启动流程,而secondary cpu则将自身设置为WFE睡眠状态,并且为内核准备了一块内存,用于填写secondary cpu的入口地址。
uboot负责将这块内存的地址写入devicetree中,当内核初始化完成,需要启动secondary cpu时,就将其内核入口地址写到那块内存中,然后唤醒cpu。
secondary cpu被唤醒后,检查该内存的内容,确认内核已经向其写入了启动地址,就跳转到该地址执行启动流程。
在这里插入图片描述
注:因为该芯片为公司基于ARM自研的芯片,部分配置进行了定制,配置信息可参考相应修改。

3、config配置

CONFIG_ARMV8_MULTIENTRY=y

3.2 timer配置

1、修改dts

		timer {
			compatible = "arm,armv8-timer";

			interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>,
						 <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH>,
						 <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>,
						 <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH>;
		};

2、确定驱动
该timer驱动为ARM通用驱动模块,中断号一般都是固定的
在这里插入图片描述

3.3 GIC中断配置

1、dts配置

		gic: interrupt-controller@3A000000 {
			compatible = "arm,gic-v3";
			#interrupt-cells = <3>;
			interrupt-controller;

			reg = <0x0 0x3A000000 0x0 0x020000>,  /* GICD */
			      <0x0 0x3A100000 0x0 0x100000>;  /* GICR */
			
			#address-cells = <2>;
			#size-cells = <2>;
			ranges;
			gic_its: gic-its@3A400000{
				compatible = "arm,gic-v3-its";
				reg = <0x0 0x3A020000 0x0 0x10000>;
				socionext,synquacer-pre-its = <0x3A400000 0x400000>;
				msi-controller;
				#msi-cells = <1>;
			};

注:该gic中断对应的基地址与具体芯片有关。

3.4 驱动确认

在这里插入图片描述

3.5 SMP配置

1、修改dts新增多核CPU配置

主要是cpu-release-addr = <0x9 0xb0000000>要与uboot下设置的值一致,同时reg = <0x0 0x0>;中通过MPIDR方式记录cpu核的id,本块板子是用MPIDR[23:8]进行记录,所以cpu1是偏移8bit从0x100开始的。
在这里插入图片描述
dts内容如下:

	cpus {
		#address-cells = <2>;
		#size-cells    = <0>;

		cpu0: cpu@0 {
			device_type = "cpu";
			compatible = "arm,armv8";
			reg = <0x0 0x0>;
			enable-method = "spin-table";
			cpu-release-addr = <0x9 0xb0000000>;
			next-level-cache = <&l2_cluster0>;
			clock-frequency = <1600000000>;
		};

		cpu1: cpu@1 {
			device_type = "cpu";
			compatible = "arm,armv8";
			reg = <0x0 0x100>; /*should be 0x100,0x200.....MPIDR[23:8] is ID*/
			enable-method = "spin-table";
			cpu-release-addr = <0x9 0xb0000000>; /*just used to save Secondary CPU Start Addr*/
			next-level-cache = <&l2_cluster0>;
			clock-frequency = <1600000000>;
		};
		cpu2: cpu@2 {
			device_type = "cpu";
			compatible = "arm,armv8";
			reg = <0x0 0x200>; /*should be 0x100,0x200.....MPIDR[23:8] is ID*/
			enable-method = "spin-table";
			cpu-release-addr = <0x9 0xb0000000>; /*just used to save Secondary CPU Start Addr*/
			next-level-cache = <&l2_cluster0>;
			clock-frequency = <1600000000>;
		};
		cpu3: cpu@3 {
			device_type = "cpu";
			compatible = "arm,armv8";
			reg = <0x0 0x300>;
			enable-method = "spin-table";
			cpu-release-addr = <0x9 0xb0000000>;
			next-level-cache = <&l2_cluster0>;
			clock-frequency = <1600000000>;
		};

		cpu4: cpu@4 {
			device_type = "cpu";
			compatible = "arm,armv8";
			reg = <0x0 0x400>; /*should be 0x100,0x200.....MPIDR[23:8] is ID*/
			enable-method = "spin-table";
			cpu-release-addr = <0x9 0xb0000000>; /*just used to save Secondary CPU Start Addr*/
			next-level-cache = <&l2_cluster0>;
			clock-frequency = <1600000000>;
		};
		cpu5: cpu@5 {
			device_type = "cpu";
			compatible = "arm,armv8";
			reg = <0x0 0x500>; /*should be 0x100,0x200.....MPIDR[23:8] is ID*/
			enable-method = "spin-table";
			cpu-release-addr = <0x9 0xb0000000>; /*just used to save Secondary CPU Start Addr*/
			next-level-cache = <&l2_cluster0>;
			clock-frequency = <1600000000>;
		};
		cpu6: cpu@6 {
			device_type = "cpu";
			compatible = "arm,armv8";
			reg = <0x0 0x600>; /*should be 0x100,0x200.....MPIDR[23:8] is ID*/
			enable-method = "spin-table";
			cpu-release-addr = <0x9 0xb0000000>; /*just used to save Secondary CPU Start Addr*/
			next-level-cache = <&l2_cluster0>;
			clock-frequency = <1600000000>;
		};

		cpu7: cpu@7 {
			device_type = "cpu";
			compatible = "arm,armv8";
			reg = <0x0 0x700>; /*should be 0x100,0x200.....MPIDR[23:8] is ID*/
			enable-method = "spin-table";
			cpu-release-addr = <0x9 0xb0000000>; /*just used to save Secondary CPU Start Addr*/
			next-level-cache = <&l2_cluster0>;
			clock-frequency = <1600000000>;
		};

3.6 内核config配置

CONFIG_SMP=y
CONFIG_NR_CPUS=8

四、其他相关链接

1、交叉编译linux内核总结

2、uboot方式启动硬盘手动制作的根文件系统方案

3、Linux下设备树dts内容总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1147508.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Apache服务的搭建与配置(超详细版)

前言 Apache是一种常见的Web服务器软件&#xff0c;广泛用于Linux和其他UNIX操作系统上。它是自由软件&#xff0c;可以通过开放源代码的方式进行自由分发和修改。Apache提供了处理静态和动态内容的能力&#xff0c;而且还支持多种编程语言和脚本&#xff0c;如PHP、Python和P…

Doremy‘s Connecting Plan(cf 906 div2)

Doremy生活在一个由编号从1到n的n个城市组成的国家&#xff0c;第二个城市居住着ai人。它可以被建模为具有n节点的无向图。最初&#xff0c;图形中没有边。现在Doremy想要使图连通。 要做到这一点&#xff0c;她可以在i和j之间添加一条边,并且满足以下条件 其中S是当前在i或j的…

分类预测 | Matlab实现KOA-CNN-BiGRU-selfAttention多特征分类预测(自注意力机制)

分类预测 | Matlab实现KOA-CNN-BiGRU-selfAttention多特征分类预测&#xff08;自注意力机制&#xff09; 目录 分类预测 | Matlab实现KOA-CNN-BiGRU-selfAttention多特征分类预测&#xff08;自注意力机制&#xff09;分类效果基本描述程序设计参考资料 分类效果 基本描述 1.M…

基于UDP/TCP的网络通信编程实现

小王学习录 今日鸡汤Socket套接字基于UDP来实现一个网络通信程序DatagramSocket类DatagramPacket类基于UDP的服务器端代码基于UDP的客户端代码基于TCP来实现一个网络通信程序ServerSocket类Socket类基于TCP的服务器端代码基于TCP的客户端代码优化之后的服务器端代码补充TCP长短…

RabbitMQ学习04

文章目录 发布确认1. 发布确认的原理2. 发布确认的策略2.1.开启发布确认的方法2.2.单个确认2.3.批量确认发布2.4.异步确认发布2.5.如何处理异步未确认消息2.6 总结&#xff1a; 发布确认 1. 发布确认的原理 生产者将信道设置成 confirm 模式&#xff0c;一旦信道进入 confirm …

Spring Cloud Alibaba 教程 Fegin 篇

Spring Cloud Alibaba 教程 | Feign 篇 写在前面的话&#xff1a; 本笔记在参考网上视频以及博客的基础上&#xff0c;只作为个人学习笔记&#xff0c;如有侵权联系删除&#xff0c;谢谢&#xff01; 1、Feign替代RestTemplate ​ 1.1 引入依赖 <!-- Feign 客户端依赖 --&…

StringBuffer类提供针对字符的操作方法

StringBuffer类是Java中用于操作字符串的一个类&#xff0c;提供了许多针对字符的操作方法&#xff0c;例如&#xff1a; append()&#xff1a;用于在字符串末尾添加字符或字符串。 insert()&#xff1a;用于在字符串的指定位置插入字符或字符串。 delete()&#xff1a;用于删…

Spring中简单的获取Bean对象(对象装配)

获取Bean对象也叫做对象装配&#xff0c;是把对象取出来放到某个类中&#xff0c;有时候也叫对象注入&#xff01; 对象装配&#xff08;对象注入&#xff09;更加简单的读取Bean&#xff08;是从Spring容器中读取某个对象放到当前类里面&#xff09;的实现方法有以下3种&…

06 MIT线性代数-线性无关,基和维数Independence, basis, and dimension

1. 线性无关 Independence Suppose A is m by n with m<n (more unknowns than equations) Then there are nonzero solutions to Ax0 Reason: there will be free variables! A中具有至少一个自由变量&#xff0c;那么Ax0一定具有非零解。A的列向量可以线性组合得到零向…

【AD9361 数字接口CMOS LVDSSPI】C 并行数据之LVDS

接上一部分&#xff0c;AD9361 数字接口CMOS &LVDS&SPI 目录 一、LVDS模式数据路径和时钟信号LVDS模式数据通路信号[1] DATA_CLK[2] FB_CLK[3] Rx_FRAME[4] Rx_D[5&#xff1a;0][5] Tx_FRAME[6]Tx_D[5&#xff1a;0][7] ENABLE[8] TXNRX系列 二、LVDS最大时钟速率和信…

附录B 其他第三方软件移植(FTP、OpenSSH、GDB)

目录 开发板 FTP 服务器移植与搭建vsftpd 源码下载vsftpd 移植vsftpd 服务器测试配置vsftpd添加新用户Filezilla 连接测试 开发板 OpenSSH 移植与使用OpenSSH 简介OpenSSH 移植OpenSSH 源码获取移植zlib 库移植openssl 库移植openssh 库 openssh 设置openssh 使用ssh 登录scp 命…

opencv4.x通过cmake编译带cuda

首选确定目标&#xff0c;需要编译的是opencv4.5.5带第三方库&#xff0c;带cuda的版本&#xff0c;使用vs编译器&#xff0c;编译releasedebug版本。 需要先安装好cmake cuda cudnn等基础依赖&#xff0c;并且确保安装好vs的编译器&#xff0c;并且大小版本都符合实际要求。 …

【C++的OpenCV】第十四课-OpenCV基础强化(三):Mat元素的访问之data和step属性

&#x1f389;&#x1f389;&#x1f389; 欢迎来到小白 p i a o 的学习空间&#xff01; \color{red}{欢迎来到小白piao的学习空间&#xff01;} 欢迎来到小白piao的学习空间&#xff01;&#x1f389;&#x1f389;&#x1f389; &#x1f496; C\Python所有的入门技术皆在 我…

信息系统项目管理师教程 第四版【第4章-信息系统管理-思维导图】

信息系统项目管理师教程 第四版【第4章-信息系统管理-思维导图】

由一个单例模式引发的思考-holder类方式

前言&#xff1a; 最近在看《Java并发编程实践》&#xff0c;里面提到了一种实现单例模式的方式&#xff0c;并大致说明了机制&#xff0c;但仍不是很清晰&#xff0c;今日有空&#xff0c;查阅相关书籍&#xff0c;尝试解释其中道理。 单例模式&#xff1a; 单例模式是一种常…

队列(8.6)

目录 2.队列 2.1队列的概念及结构 2.2队列的实现 2.2.1初始化队列 2.2.2队尾入队列 2.2.3队头出队列 2.2.4获取队列头部元素 2.2.5 销毁队列 3.栈和队列面试题 225. 用队列实现栈 - 力扣&#xff08;LeetCode&#xff09; 232. 用栈实现队列 - 力扣&#xff08;LeetC…

【送书福利-第二十一期】《ChatGPT进阶:提示工程入门》

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公粽号&#xff1a;程序员洲洲。 &#x1f388; 本文专栏&#xff1a;本文…

正点原子嵌入式linux驱动开发——Linux 多点电容触摸屏

随着智能手机的发展&#xff0c;电容触摸屏也得到了飞速的发展。相比电阻触摸屏&#xff0c;电容触摸屏有很多的优势&#xff0c;比如支持多点触控、不需要按压&#xff0c;只需要轻轻触摸就有反应。ALIENTEK的三款RGB LCD屏幕都支持多点电容触摸&#xff0c;本章就以ATK7016这…

Spring Cloud Alibaba Seata 实现 SAGA 事物

Seata 是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式&#xff0c;为用户打造一站式的分布式解决方案 Seata 官网&#xff1a;https://seata.io/zh-cn/ Spring Cloud Alibaba 官…

【Java网络原理】 六

本文主要介绍了网络层的IP协议/NAT机制/IPv6的由来以及在数据链路层涉及到的以太网协议和DNS域名解析系统 一.网络层 1.IP协议 各个字段所表示的含义 >4位版本号 用来表示IP协议的版本&#xff0c;现在只有两个版本IPv4 &#xff0c;IPv6 >4位首部长度 IP报头可变&…