OK6410A 开发板 (八) A linux-5.11 OK6410A 文章整理

硬件环境
ARMv6-ARM1176jzfs
硬件资料

核心移植
驱动移植

rootfs及其他用户空间工具的制作

ARM-linux代码分析(这里有些是架构相关的,有些是架构无关的)
静态分析

Makefile Kconfig Kbuild 分析
简易开发环境搭建
汇编启动分析


start_kernel 启动分析
  • start_kernel 运行时的关注点
1.打印
2.内存
3.硬件初始化(设备)
4.进程建立及调度
	4.1 进程的创建(idle及其他)
	4.2 多进程的调度
	4.3 进程通信机制
	4.4 线程同步机制
	
5.异常向量表角度
	5.1 中断
	5.2 其他异常
A.其他
	1. 网络
	2. 文件系统
以打印角度分析 启动


以功能角度分析 启动
以进程角度分析 启动
一开始 是 裸机程序
然后将裸机程序 封装成 idle 进程
然后idle 就开始 fork 出 kernel_init 和 kthreadd
然后调度 开始,混乱的多进程调度开始了
接着 kthreadd fork出了 所有的内核进程
接着 用户进程init及其子进程 fork出了 所有的用户进程

计算机三大抽象之一
	进程对CPU虚拟化 // 进程是对处理器 主存 和IO设备的抽象表示

考虑进程执行的时候(除去考虑竞态)一般不考虑调度
	因为对于该进程来说,它执行的时候占用了整个cpu


  • [调度的需求及历史及整体分析]
为什么需要调度
	因为多进程的需求
为什么需要多进程
	因为 只有一个进程,造成资源浪费
虽然有调度,可指令还是 one by one 执行的
	宏观并行,微观串行
调度的实质
	选中一个进程 (调度的核心,如何发展的?)
	保存当前的进程/恢复选中的进程(架构强相关,因为涉及到寄存器的保存和恢复)

进程创建/调度的性能参数
	???
系统有多少进程?进程是怎么被看见的?
如何遍历进程


以内存角度分析 启动
内存管理的历史
内存管理的性能



1.vmalloc ,一个内存块用vm_area 表示,挂载到了 vmap_area_root 和 vmap_area_list
	vm_struct 结构体是其他模块可见的,vmap_area是动态映射区内部使用的
	全局变量vmap_area_root是红黑树的根节点
	全局变量vmap_area_list用于将vmap_area按地址从小到大排序。
2. mmap  一个内存块用vm_area_struct 表示,挂载到了 进程PCB中的mm_struct中的 mm_rb 和 mmap



kmalloc
vmalloc
malloc
mmap


以文件系统FS角度分析 启动
以 无init_xxx技术 的启动流程为研究对象
start_kernel
	vfs_caches_init_early
	vfs_caches_init
		mnt_init
			init_rootfs  	//注册 rootfs 文件系统
			init_mount_tree
kernel_init
	prepare_namespace
		mount_root		  	//挂载真正的文件系统(在这里以root=/dev/mmcblk0p2中的rootfstype=ext3为例,该文件系统根目录有/linuxrc)
	init_post
		run_init_process(execute_command)	//内核参数为init=/linuxrc



在文件IO时会用 file_operations 中的成员去访问 文件
所有磁盘文件系统中的 文件 都共用一个 file_operations
大部分内存文件系统的 文件 都共用一个 file_operations 
/dev下的 文件系统中的 cdev 文件 每个文件有一个 file_operations 

open流程中,对于 init_special_inode // 例如 /dev 下的 特殊文件系统的文件

const struct file_operations def_chr_fops = {
	.open = chrdev_open,

SyS_open->do_sys_open->do_filp_open->path_openat->do_last->vfs_open->do_dentry_open->chrdev_open
	chrdev_open 
		fops = fops_get(p->ops);
		replace_fops(filp, fops);
		filp->f_op->open(inode, filp);


当读写(write read,非mmap),我们将磁盘数据缓存到 内存的物理页(物理页由struct page描述) 
address_space 是用来管理 这些 struct apge 的
	address_space 直接挂在了 file结构体下,不用复杂管理
	page 由 radix_tree 管理

  • [文件的访问技术]
	1. 直接读写磁盘 				// 缺点是每次读写都要陷入内核空间,都要转动磁盘
	2. 页缓存技术	  			// 缺点是每次读写都要陷入内核空间
	3. 页缓存技术+fread/fwrite 	// 缺点是增加了数据在不同缓冲区复制的次数
	4. mmap技术 	  			// 优点 : 减少系统调用和内存复制的次数

通过fd 访问 内存(保存内核信息) 的方式 共分以下几种
	1. open mmap
	2. open write read close
	3. userfaultfd
	4. memfd_create和fd跨进程共享
通过fd 访问 文件(保存在硬盘上) 的方式 共分为以下几种
	1. open mmap
	2. open write read close
ARCH相关代码分析
arch/arm export 的函数与宏
arch/arm 页表
不同arch下的"boot到start_kernel"

文件系统
从文件系统到存储设备的数据流图解析
IO 的同步和异步
  • [IO 同步/异步 阻塞/非阻塞 概念]
  • [read & write 阻塞IO]
  • [read & write 非阻塞IO]
  • [select,pselect,poll,epoll 多路复用]
  • [信号驱动式IO]
  • [异步非阻塞 IO]

真实文件系统分析
磁盘文件系统比较好理解
网络文件系统暂时可以不用理解
但是内存文件系统类别比较多,各种内存文件系统都有,不知道为什么要分这么多类别
其中有 shmem tmpfs ramfs devtmpfs sysfs kernfs  udevfs procfs debugfs devpts tracefs
cgroup pstore systemd-1 hugetlbfs mqueue sunrpc fusectl configfs nfsd binfmt_misc gvfsd-fuse 
shmem tmpfs ramfs devtmfps 比较混乱

devtmpfs 的底层实现 用了 ramfs 和 shmem
tmpfs    的底层实现 用了 ramfs 和 shmem



系统启动过程中,挂载了
	1. tmpfs
	2. rootfs
	3. bdev_cache_init
	4. nsfs_init
	5. devtmpfs
异常
ARM异常分析
单核心的soc 的话,其实运行流程很单纯
包含
	1. A进程代码
	2. B进程代码
	3. AB 系统调用(异常3)
	4. AB 系统调用后进入内核的代码
	5. 调度
	6. 其他异常(异常1 2 4 5 6 7 8)
其他的就没了 // (由于会有异常及调度,所有会有竞态,所以需要同步)

多核心的soc,其实和这个一样
	但是 多核心 相比 单核心,多了
		1. 核间通信(应该归入异常范畴)
		2. 核间同步
		3. 多核boot
	另外,会在 增加 调度方面的功能: cpu绑定,cpu间调度之类




linux对ARM异常的处理总体分析
linux对ARM中断的处理总体分析
  • 中断亲和性
  • 中断抢占
  • [异常之中断的处理方式-顶半部和底半部]
fiq 在linux中是不处理的
irq ,是由外设引起的,linux 会用 底半部来处理

每次中断后会一个domain,一个domain的来处理
	每个domain内部 查询 status , 如果有bit置1,就处理.
	直到处理完成后,再次查询一轮没有 bit置位1,handle_one_vic才返回0
	所以如果一个中断线状态是 pending&active , 则会在一次中断发生时,都处理完该中断线的所有中断.

中断上下文有哪些代码
软中断上下文有哪些代码
中断处理函数中处理了 软中断,软中断处理时是开中断的, 界限一定要分清楚
同种softirq,tasklet,工作队列,因为有多个工作者线程,都可并发
	但是 tasklet 做了处理,只能串行,不会并发
中断线程化,因为只有一个工作者线程,不会并发
  • [底半部机制的区别
			中断底半部执行延迟		对实时进程的影响 		处理函数可花费时间	底半部并行
工作队列		慢 						无影响 					可以很多				并行
中断线程化   中 						与实时进程共同竞争  		可以较多				串行
软中断 		快 						比实时进程优先级高		尽量少 				并行
tasklet 	快 						比实时进程优先级高		尽量少				串行


软中断 就是 软件模拟 的中断,谈起中断

有几个方面是 必不可少的
	硬件 和 软件 分别 该 如何 模拟?
	中断有几根线 // 10
	中断线的状态(pending) 
	中断什么时候处理,如何返回

  • [底半部实现方式3-tasklet
  • [底半部实现方式4-中断线程化
以前用work来线程化的处理内核,一个worker线程只能由一个CPU执行,多个中断的work都由同一个worker线程来处理,在单CPU系统中也只能忍着了。但是在SMP系统中,明明有那么多CPU空着,你偏偏让多个中断挤在这个CPU上?

新技术threaded irq,为每一个中断都创建一个内核线程;多个中断的内核线程可以分配到多个CPU上执行,这提高了效率。
------------------------------
实时进程运行,突然来了中断,中断后执行软中断,实时进程的实时性不可控
------------------------------

中断线程化(减少对软中断的使用),会优化对 实时进程 的处理
中断线程化(减少对workqueue的使用),会增加对底半部的实时处理
中断线程化 是 介于 workqueue 和 软中断 两种底半部技术的 一种技术

异常之后,会返回吗?
应用程序会被杀掉吗?内核会崩溃吗?
gic 还会一直中断吗?
linux 异常分析
0							: SIGFPE
未对齐的数据访问				: 
空指针的读写、写rodata section : SIGSEGV
prefetch abort

同步与通信
竞态与(内核)同步
事件的同步
进程通信分析
linux 提供几种通信方式
	1. 信号
	2. 管道
	3. 有名管道
	4. 套接字
	5. 信号量
	6. 消息队列
	7. 共享内存
	A.dbus // dbus 基于 套接字
	B.signalfd timerfd eventfd // 基于 anon inode fs

其中 信号量 消息队列 共享内存 posix 提供一套 , XSI(systemv) 提供一套

共享内存的实现 有很多种
	1.posix mmap && open mmap
	2.XSI(systemv)
	3.memfd_create和fd跨进程共享
	4.dma-buf


linux内核调试&性能调试
1. printk
2. syslog
3. console 
4. syslogd 
5. klogd 
6. kmesg
7. 动态打印
8. dump_stack
---
9. 内核参数& CONFIG
---
10. procfs
11. sysctl
12. sysfs 
13. debugfs
14. top/htop free
---
15. gdb-with-jtag
16. kdb
17. kgdb
10.kgtp
---
10.BUG&BUG_ON
11.oops&panic 
10.kdump(based on kexec)&crash & kcore
10.SysRq magic key
---
11.kprobe & systemtap
12.ftrace(trace-cmd)
13.perf & eBPF
14.LTTng
15.分析工具:火焰图 https://github.com/brendangregg/FlameGraph
其他
linux中的栈
系统调用
文件格式
文件系统负责管理 文件,而不负责 解析文件里面的内容
arm-linux-gnueabi-gcc 	  -E 			   		main.c 			-o 	main.i
arm-linux-gnueabi-gcc 	  -S 			   		main.i			-o 	main.s
arm-linux-gnueabi-gcc 	  -c 			   		main.s 		 	-o 	main.o
arm-linux-gnueabi-gcc 					   		main.o    		-o 	main
arm-linux-gnueabi-objcopy -O 	srec       		main 				main.srec
arm-linux-gnueabi-objcopy -O 	binary     		main 				main.bin
arm-linux-gnueabi-objdump -D 			   		main          	> 	main.elf.asm
arm-linux-gnueabi-objdump -D -b binary 	-m arm 	main.bin  		> 	main.bin.asm
arm-linux-gnueabi-objdump -D -b srec 	-m arm 	main.srec   	> 	main.srec.asm
hexdump 										main  			> 	main.hex
LKM 的实现
总线设备驱动模型及设备驱动及设备管理
总线设备驱动模型中的总线和实际总线(例如i2c的sda和sck) 是 不同的.
在 内核中,可以认为总线是  两个链表,一个用于挂驱动,一个用于挂设备
至于 设备挂到哪里
// 例如, 这个就挂到了 platform 上
dev.bus = &platform_bus_type;
device_add(&dev);
// 例如, 这个驱动就挂到了 platform上.
driver.bus = &platform_bus_type;
driver_register(&driver);
然后就需要 platform_bus_type中的 platform_match 来匹配驱动和设备
匹配成功就执行probe
总线 可以用  物理上不存在的东西命令,例如 platform总线,hid总线
总线 也可以用物理上存在的东西命令,例如 i2c总线,usb总线. // 但 内核中的usb总线和硬件中的usb总线并不相同.
SMP 启动
CPU配置 : cache
上下文切换
计算机系统体系基础 第三版 胡伟武
第 4 章 软硬件协同 /4. 2 六种常见的上下文切换场景
arm64的linux情况
arm32在linux应用上的问题
	1.ATM32 32bit虚拟地址导致无法全映射,从而存在高端内存的问题
	2.ARM32 TTBR0无法使用的问题
	3.ARM32 页表无dirty和access位的问题
	4.ARM32 异常处理入口复杂的问题
arm64都会解决
	arm32 的硬件问题,导致了 linux 用一些复杂的架构相关代码来做了处理
	而arm64对arm32做了升级
	arm64-linux 在这几块的架构相关代码,显得简单了许多
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值