- 博客(156)
- 资源 (30)
- 收藏
- 关注

原创 博客目录导读
如何创建设备文件如何编写字符设备驱动如何编写杂项设备驱动字符设备驱动接口最方便的字符设备驱动的写法软中断内核源码分析进程相关函数归纳驱动GPIO操作归纳驱动中定时器,taskle,工作队列编程驱动中断编程驱动中的资源共享和临界代码保护驱动等待队列,poll和select编程读操作系统导论记录linux下锁的历史发展tasklet内核源代码分析linux内存管理(一)-内存管理架构linux内存管理(二)-内存数据结构分析linux内存管理(三)-mmap的系统调用linux内
2022-11-19 17:35:33
1324
3

原创 驱动调试工具整理
zz驱动工具备注i2cI2c-toolsi2cdetect:检测挂在系统上的设备总线。i2cI2c-toolsi2cdump:查看寄存器的值i2cI2c-toolsi2cget:读取寄存器值i2cI2c-toolsi2cset:设置寄存器值spispi-tools网口驱动ethtool网口驱动Mii......
2020-12-23 11:16:21
4313
1
原创 内核参数优化记录
在某些情况下,严格的反向路径过滤可能会误杀一些合法的流量,比如通过NAT转换的流量。net.ipv4.tcp_keepalive_intvl 是 Linux 内核中的一个网络配置参数,它定义了在 TCP 连接的 keepalive 探测过程中,内核发送连续的 keepalive 探测包之间的时间间隔。net.ipv4.tcp_max_syn_backlog 是Linux内核中的一个网络配置参数,用于设置TCP协议在三次握手过程中,对于尚未完成握手的连接请求(即处于SYN接收状态的连接)的最大队列长度。
2024-10-22 09:10:24
1002
原创 arm架构Linux5.0内核连接脚本文件vmlinux.lds.S分析
vmlinux.lds.S 是 Linux 内核中用于链接的脚本文件,用于定义内核对象文件的内存布局,即它告诉链接器如何将不同的内核代码段和数据段组合成一个最终的内核映像 vmlinux。编译内核源码生成内核文件的过程分两步,一个是“编译”,另一个是“链接”的过程,vmlinux.lds.S要做的就是告诉编译器如何链接编译好的各个内核.o文件,从而生成vmlinux文件。
2024-04-23 17:23:51
1430
原创 linux内存管理(十七)创建页表流程分析
固定映射是初始化在start_kernel()-> setup_arch()->early_fixmap_init()中,会初始化FIXMAP的起始地址,并建立一个映射框架,但不填充页表条目(PTE)。当然,还有很多函数也是通过__create_pgd_mapping来创建页表的,比如:create_mapping_noalloc、create_pgd_mapping、update_mapping_prot、map_entry_trampoline和arch_add_memory。
2024-04-19 11:14:40
1293
原创 笨叔使用eclipse和gdb调试步骤记录
5.选择C/C++ Attach下面的选项,第三步修改名字为lab,第四步选择刚刚创建的工程lab,第五步选择带调试信息的应用程序elf,第六步选择Disable auto build。6.第一步点击Dubger,第二步选择gdbserver,第三步骤写上gdb-multiarch。3.填写工程名字为lab,然后选择代码路径,最后点击finish。1.创建工程,打开file的New,选择peoject。2.选择c项目下的Makefile,然后点击next。8.在控制台带-s -S参数运行qemu程序。
2024-04-12 10:29:04
555
原创 看linux内核启动流程需要的arm汇编指令学习笔记(二)
0x30ldr x0, =my_label /*把宏的值加载到x0寄存器*/ldr x1, my_label /* PC值 + 宏的值,然后加载这个地址的值到x1寄存器*/
2024-04-09 15:13:07
879
原创 openssl加解密和签名验签步骤操作记录
这里,aes_key.bin 是你的 AES 密钥文件,encrypted_message.bin 是加密后的数据文件。这里,aes_key.bin 是你的 AES 密钥文件,encrypted_message.bin 是加密后的数据文件。此外,确保你的密钥安全存储,并且只在需要时才使用,以防止密钥泄露。这里,signature.bin 是签名文件,message.txt 是你想要签名的文件。-sha256 指定了使用的哈希算法,你可以根据需要选择其他哈希算法,如 -sha1 或 -sha512。
2024-01-23 23:15:36
2771
1
原创 linux进程调度(四)-进程调度分析
不同的是,SCHED_RR会为每个进程分配固定的时间片,一旦时间片耗尽,当前进程便被置于队列的尾部,等待下一轮调度。task_tick_fair函数主要是遍历当前进程到当前进程到根任务组的每级公平调度实体,正常我们没有使用调度分组的话,只有一个调度实体,如果我们使用cgroup控制cpu的使用率,才会有多个调度实体,这些调度实体随着cgroup形成树状,我们只会往上遍历parent节点,针对每一个调度实体,我们会找到对应的cfs_rq后调用函数entity_tick更新进程的调度实体的状态;
2023-11-24 10:41:29
486
原创 linux进程调度(三)-进程终止
当进程退出的时候,根据父进程是否关注子进程退出事件,存在两种可能:第一种,父进程关注子进程的推出事件,那么进程退出时释放各种资源,只留下一个空的进程描述符,变成僵尸进程,发送信号 SIGCHLD通知父进程,父进程在查询进程终止的原因以后回收子进程的进程描述符。第二种,如果父进程不关注子进程退出事件,那么进程退出时释放各种资源,释放进程描述符,自动消失。进程的退出分两种情况:进程主动退出和被动退出。主动退出是指进程已经执行完毕,主动调用exit退出或者main函数执行完毕,编译器会总添加exit函数。
2023-11-24 10:41:10
492
原创 linux进程调度(二)-进程创建
我们可以直观看到kthread_run → kthread_create → kthread_create_on_node → __kthread_create_on_node的调用流程。到目前为止,我们无论是用户态的系统调用还是内核提供的函数,他们都是通过设置struct kernel_clone_args结构体为传入参数,然后调用kernel_clone函数来创建进程的。到这里我们又看到很熟悉的画面了,就是kernel_clone_args和kernel_clone函数。
2023-11-24 10:40:51
222
原创 linux进程调度(一)-进程概述
进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销已有进程、实现进程状态之间的转换等功能。现代操作系统支持多核处理器、多线程和分布式系统等技术,允许进程在不同的计算机上运行,进一步增强了进程的灵活性和可扩展性。在分时系统中,操作系统可以运行多个进程并为它们提供时间片,每个进程只有在它的时间片内获得CPU的控制权。目前,只有CPU的资源管理器能主动发起调度,而其他资源像内存,网络,显卡等资源管理器都是提供申请服务调度的,所以要必须理解我们常说的进程调度都是指调度CPU。
2023-11-24 10:40:37
137
原创 qemu调试linux内核rust驱动程序
把CONFIG_SAMPLE_RUST_PRINT和CONFIG_SAMPLE_RUST_MINIMAL选上。我们使用Rust-for-Linux的rust-dev分支进行学习。上下载 Images for arm64-virt 版本的压缩包。然后修改配置文件,把CONFIG_RUST设置为y。首先生成配置文件.config。
2023-11-09 20:36:21
1073
原创 GIC寄存器详解
GIC(Generic Interrupt Controller)是由ARM公司推出的一种通用中断控制器,用于处理系统中的各种硬件中断。GIC是一种灵活、可扩展的、可编程的中断控制器,可以处理多种类型和来源的中断,并提供了一套完整的中断管理机制。CPU Interface control(CPU接口控制器):CPU接口负责处理CPU核心与中断控制器之间的交互,包括中断请求、中断确认、中断掩码、中断优先级等。CPU接口还支持可编程的中断延迟和预处理功能,以优化中断的响应时间和系统性能。
2023-09-25 15:06:22
2241
原创 使用内核API函数找到I2C和串口控制器发送数据
我们一般操作I2C或者串口都是编写应用程序调用内核硬件提供的设备节点操作这些硬件的,但是在某个项目中,需要在shutdown的时候往i2c和tty发送数据,发送数据给外置的mcu,mcu几秒内就会给cpu断电,所以,这个动作无法在应用层中完成,需要在内核的reboot这个系统调用中实现了,但是在这个时候根文件系统已经umount了,无法使用call_usermodehelpere调用应用层的可执行程序了,会报找不到设备的错误。下面是4个例子:分别是I2C和串口的应用程序和内核程序。
2023-09-07 10:00:03
290
原创 arm64架构的linux中断分析(零)
前面的调用路径都好理解,就是start_kernel一直调用到 of_irq_init这个函数,我们的宏申明了__irqchip_of_table这个段,所以在 of_irq_init这个函数里面会遍历整个设备树,找到所有compatible匹配的节点,并且判断是否为interrupt-controller,是否有data成员,如果都有,则把date成员赋值给desc->irq_init_cb,最后调用desc->irq_init_cb。当异常发生的时候,处理器需要执行异常的处理程序。
2023-09-04 21:24:31
786
原创 warning: ignoring unsupported character ‘问题修复
细看报错内容,一致为解析Kconfig文件异常。查阅资料后发现,在Windows和Linux系统中,存在换行符的差异。windows下换行符为”0x0a0x0d”。Linux(Unix)系统下换行符为”0x0d”。
2023-09-04 21:23:06
1867
原创 Ubuntu22.04使用qemu运行armv8的TFA、optee和linux全过程
【代码】Ubuntu22.04使用qemu运行armv8的TFA、optee和linux全过程。
2023-07-06 20:53:32
667
原创 arm64架构的linux中断分析(四)
在Linux内核中,使用了类似中断控制器的模型,在每个中断控制器中管理多个中断,其中每个中断对应不同的中断处理程序,比如IOAPIC和APIC都是中断控制器的实现。当然,我们还要重点关注irq_generic_chip_ops结构体、irq_chip里面的方法和rockchip_irq_demux这个中断处理函数。中断控制器分为链式中断和层级中断,他们都是多个中断处理程序组成的中断处理链,链式中断适用于任务相对较简单、执行时间短的场景,而层级中断适用于需要更细粒度的控制和响应的场景。
2023-06-20 10:22:33
727
原创 arm64架构的linux中断分析(三)
irq_create_of_mapping函数首先根据irq_data的信息填充irq_fwspec结构体,然后调用函数irq_create_fwspec_mapping创建从fwspec到IRQ号的映射关系。of_irq_to_resource_table函数主要是遍历全部irq,然后调用of_irq_to_resource解析节点中的中断信息,和构造中断资源。translate和xlate都是中断控制器驱动注册的时候写好的,后面会详细说。
2023-06-20 10:22:17
847
原创 arm64架构的linux中断分析(二)
前面的调用路径都好理解,就是start_kernel一直调用到 of_irq_init这个函数,我们的宏申明了__irqchip_of_table这个段,所以在 of_irq_init这个函数里面会遍历整个设备树,找到所有compatible匹配的节点,并且判断是否为interrupt-controller,是否有data成员,如果都有,则把date成员赋值给desc->irq_init_cb,最后调用desc->irq_init_cb。它们是非可屏蔽中断(NMI),具有固定的优先级和中断号。
2023-06-20 10:22:02
1740
原创 arm64架构的linux中断分析(一)
第二组表示异常发生在ELn(n可以为1,2,3),处理异常的特权等级也是ELn(n可以为1,2,3),但是这里是linux内核,所以我们的特权为EL1,我们可以理解为异常发生在EL1,处理异常的特权等级也是EL1。软件中断号,有时候也叫虚拟中断号,是由内核定义的中断号,用于执行内核函数或服务。当触发流程走到cpu后,cpu会跳转到中断异常向量表,执行后面的操作:读取GIC信息,了解到是GPIO触发的中断,再读取GPIO控制器的信息,了解到是某一个GPIO的外设导致的,执行这个外设的中断处理函数。
2023-06-20 10:20:43
2166
原创 linux驱动-gpio
设备驱动层:定义了与硬件无关的GPIO API,包括GPIO的注册、卸载和控制等功能,而实现了某个模块的具体实现,比如led灯、按键等等。gpiolib抽象层:GPIO框架中的核心抽象层,它的作用是为设备驱动层和控制器层提供一致的接口,该层提供了包括上层设备驱动和下层控制器驱动的API接口。控制器层:GPIO控制器的实现和管理,在该层中实现特定GPIO控制器的底层硬件操作和功能实现包括GPIO控制器的初始化、操作和管理等。负责GPIO寄存器的读写操作和GPIO中断的处理等。
2023-05-10 19:54:45
2533
原创 linux内核启动分析(三)
如果不属于任何集群的话,就通过mpidr_cpu_id函数从mpidr中提取出该处理器对应的CPU核心ID,然后将该ID和该处理器的pgtable_hash_node结构体通过hash_add函数添加到wait_for_pgtable_refill哈希表中。首先,在for_each_possible_cpu循环中,遍历了所有可能存在的CPU核心,对于每个CPU核心,都使用per_cpu函数获取其cpu_data结构体,然后判断该处理器是否支持ARM64_HAS_CPUID功能。
2023-04-19 18:30:00
2401
原创 udev使用记录
赋值关键字包括:NAME(创建的设备文件名)、RUN(运行程序)、SYMLINK(符号创建链接名)、OWNER(设置设备的所有者)、GROUP(设置设备的组)、IMPORT(调用外部程序)、MODE(节点访问权限)等。在该目录,一般每个文件都代表某个系列的规则,比如声卡,网卡,usb等等的系列。匹配关键字包括:ACTION(行为)、KERNEL(匹配内核设备名)、BUS(匹配总线类型)、SUBSYSTEM(匹配子系统名)、ATTR(属性)等。在某HDMI声卡的规则,识别到声卡后,需要执行脚本设置音量。
2023-04-19 14:27:35
687
原创 内存-页表结构详细说明
我们知道linux采用了分页机制,通常采用四级页表,页全局目录(PGD),页上级目录(PUD),页中间目录(PMD),页表(PTE)。如下:_AC1
2023-04-18 19:05:19
3085
原创 linux安全-自主访问控制
在计算机安全领域,访问发起者被称为主体,访问动作就是具体的操作,被访问者被称为客体。比如,进程A 读文件 a,进程 A 是主体,读是操作,文件 a 是客体。Linux的主体只能是进程;操作只有读、写或者执行;客体可以是目录和文件{包括管道、设备、IPC(进程间通信)、socket(套接字)、key(密钥)}。备注:目录的执行是进入,文件的执行是运行,只有普通文件可以执行,管道等文件是不可以执行的。自主访问控制的自主是指使用计算机的人可以决定访问策略,比如规定某文件只能读不能写,制造出一种“只读”文件,防止
2023-03-30 17:24:22
1997
原创 linux内核启动分析(二)
set_task_stack_end_magic函数就做了一件事,获取内核栈的末尾地址,然后给这个地址赋值STACK_END_MAGIC。boot_cpu_init主要是设置当前cpu的状态,这些状态保存在全局变量__cpu_online_mask、__cpu_active_mask、__cpu_present_mask、__cpu_possible_mask中。因为启动阶段,ss->early_init为0,cgroup_init_subsys没有执行,先不看。不太能看懂,后续补,先学习一下。
2023-03-29 11:14:35
1532
原创 arm64虚拟化学习笔记
EL2控制virtual CPU interface,这包括打开和关闭virtual CPU interface,读写virtual CPU interface中的寄存器以实现vCPU的调度和上下文切换,配置maintenance中断,控制虚拟中断。ELn处理常规的物理中断,这包括打开和关闭PE的中断处理能力,ack中断,为PE维护一个中断优先级掩码(只响应更高优先级中断),定义中断抢占策略,执行中断降级。6.虚拟机被调度,虚拟机所在的CPU会获取这个VIRTUAL IRQ造成的中断异常。
2023-03-02 14:59:02
1860
原创 linux内核调用用户态程序的方法call_usermodehelpere
在用户态中,我们可以通过execve()直接执行应用程序;那么,在内核态,我们是否可以直接调用用户态程序呢?答案是可以的,内核提供了一个函数:call_usermodehelpere,它可以帮助我们在内核就可以执行用户态的二进制程序。准备好这两个文件,执行make就可以编译出b.ko驱动。
2023-02-28 16:23:41
1411
原创 看linux内核启动流程需要的arm汇编指令学习笔记(一)
MRS 指令: 对状态寄存器CPSR和SPSR进行读操作。MSR指令: 对状态寄存器CPSR和SPSR进行写操作。
2023-02-27 21:28:14
785
原创 linux内核启动分析(一)
最近工作中经常使用飞腾E2000的开发版,也遇到一些启动问题,所以追踪了一下linux内核启动流程。麒麟的代码我们看不了,但是我们可以直接看飞腾的开源内核代码,,我们使用的是5.10分支。飞腾E2000的开发版可以使用uboot和UEFI,无论是uboot还是UEFI加载linux内核,并且启动linux内核都是从arch/arm64/kernel/head.S文件的_head这里开始运行的。
2023-02-27 21:21:29
1720
原创 重写-linux内存管理-伙伴分配器(三)内存回收
申请分配页的时候,页分配器首先尝试使用低水线分配页。如果使用低水线分配失败,说明内存轻微不足,页分配器将会唤醒所有符合分配条件的内存节点的页回收线程,异步回收页,然后尝试使用最低水线分配页。如果分配失败,说明内存严重不足,页分配器将会进行内存碎片整理,整理后尝试使用最低水线分配页。如果分配失败,说明内存不够用了,需要回收一些暂时用不上的内存,页分配器将会直接回收页。后面才会oom等等。也就是说,存在内存异步回收和内存同步回收。
2023-02-20 14:36:09
1017
原创 重写-linux内存管理-伙伴分配器(二)内存碎片整理
内存碎片整理( memory compaction ,直译为“内存压缩”,意译为“内存碎片整理”)的基本思想是:从内存区域的底部扫描已分配的可移动页,从内存区域的顶部扫描空闲页,把底部的可移动页移到顶部的空闲页,在底部形成连续的空闲页。完全同步模式的成本最高,轻量级同步模式的成本其次,异步模式的成本最低。在慢速路径的内存申请过程中,如果条件满足,第一次调用__alloc_pages_direct_compact是使用成本最低的异步模式。
2023-02-15 17:04:43
1158
原创 重写-linux内存管理-伙伴分配器(一)
如果只申请一页,允许从这个区域分配页,返回true。zone_watermark_fast调用函数zone_page_state获取区域空闲物理页数量,如果是0阶,调用__zone_watermark_unusable_free计算不可用的空闲页,最后计算出可用的空闲页,然后判断如果可用空闲页数大于(水线 + 低端内存保留页数),说明内存足够,返回ture;zone_watermark_ok是调用zone_watermark_ok函数判断水位的,zone_watermark_ok函数我们前面讲过了。
2023-02-14 11:29:27
1151
原创 重写-linux内存管理缺页异常分析(下)
触发匿名页的缺页异常的情况:然后看代码:do_anonymous_page首先判断一下匿名页是否是共享的,如果是共享的匿名映射,但是虚拟内存区域没有提供虚拟内存操作集合就返回错误;然后判断一下pte页表是否存在,如果直接页表不存在,那么分配页表;接下来判读缺页异常是由读操作触发的还是写操作触发的,如果是读操作触发的,生成特殊的页表项,映射到专用的零页,设置页表项后返回;如果是写操作触发的,需要初始化vma中的anon_vma_chain和anon_vma,分配物理页用于匿名映射,调用mk_pte函数生成
2023-02-07 16:45:01
1379
RegBit.exe.zip
2024-05-29
glxgears x11perf测试工具.docx
2024-05-07
IOZone硬盘性能测试工具培训.doc
2024-05-07
硬盘测试工具FIO测试方法培训.docx
2024-05-07
LTP测试工具使用.docx
2024-05-07
mymymyprintf.c
2024-04-17
load-monitor.zip
2024-04-17
tcr-reader.zip
2024-04-17
WakeMeOnLan(远程唤醒开机)
2024-03-26
14. 预处理器.docx
2024-03-14
各头部企业嵌入式面经手册
2024-03-07
如何学习Linux下的GPIO
2024-03-05
Linux时间子系统.docx
2024-01-27
eMMC-驱动架构分析
2024-01-23
DIM-SUM操作系统内核开发的一系列问题及其解答
2024-01-11
EPCM3568B-LI系统的系统基本操作手册
2024-01-11
Linux内核设备树介绍
2023-11-01
银河麒麟嵌⼊式操作系统安装教程
2023-11-01
RISC-V的特权规范
2023-11-01
RISCV-伪指令列表
2023-11-01
swap的分析及其使用
2023-11-01
linux使用gdb调试方法详解
2022-04-27
老同学给的入门级驱动开发资料
2022-01-20
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人