![](https://img-blog.csdnimg.cn/20201014180756919.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Linux 源码分析
tiantao2012
这个作者很懒,什么都没留下…
展开
-
cxl协议理解
CXL的全称是Compute Express Link ,CXL是一种东岱的多协议的互联技术总线,提供了类似PCIE的CXL.io协议CXL分为三种子协议,分别是CXL.io, CXL.cache,CXL.mem,这三种协议可以全部使能也可以部分使能,但是CXL.io 必须是能,CXL协议的关键优势就在于访问设备可以做到低延时和高带宽.CXL.cache协议允许设备保存缓存cacheline到本地CXL.mem协议允许设别是全一致性的内存设备,这种设别可以被当作"System RAM and/or原创 2021-09-17 16:03:02 · 5828 阅读 · 2 评论 -
ARM异常等级的切换
系统抵用的异常有三种:SVC,HVC,SMCSVC: 用于被EL0的软件用来申请操作系统上EL1请求特权或者访问系统资源.用于从EL0->EL1的切换HVC: guest os用来请求hypervisor的服务,用于从EL1->EL2的切换.SMC: 全称是secure monitor call,用于从EL2->EL3,用于secure与none-secure的切换....原创 2021-09-11 19:38:36 · 2061 阅读 · 0 评论 -
jump label
这段代码的反汇编如下所示static inline bool test_idle_cores(int cpu, bool def){ struct sched_domain_shared *sds; if (static_branch_unlikely(&sched_smt_present)) { sds = rcu_dereference(per_cpu(sd_llc_shared, cpu)); .原创 2021-04-05 09:14:45 · 799 阅读 · 0 评论 -
通过sysfs判断cpu是否支持smt
在kernel/cpu.c中为smt建立了一个sysfs的入口,代码如下:可以看到支持smt的cpu 有一下五种状态static const char *smt_states[] = { [CPU_SMT_ENABLED] = "on", [CPU_SMT_DISABLED] = "off", [CPU_SMT_FORCE_DISABLED] = "forceoff", [CPU_SMT_NOT_SUPPORTED] = "notsupported", [CPU_SMT_NOT_IM.原创 2021-02-18 14:41:50 · 668 阅读 · 0 评论 -
kernel对支持smt的cpu的启动
有一个疑问,支持smt的cpu,bios 传递给os的cpu的个数是开了smt后的还是没有开smt的呢?这里举个例子,例如支持smt2的cpu,其实还有支持smt4,smt8的cpu,例如ibm的power系列假如支持smt2,没有开smt的时候是16核,开了smt就是32核,那在开了smt后,bios就要告诉kernel 当前的cpu 核数是32,这点可以从下面的函数中发现端倪.static int cpu_up(unsigned int cpu, enum cpuhp_state target.原创 2021-02-18 11:26:05 · 602 阅读 · 0 评论 -
virtio 提供的hw_rng
hwrng 也提供了一种从virtio中获取真随机数的方法,代码在drivers/char/hw_random/virtio-rng.c中,通过前面的分析hw_rng的工作原理都清楚了,那我们看看做核心的read函数的实现vi->hwrng = (struct hwrng) { .read = virtio_read, .cleanup = virtio_cleanup, .priv = (unsigned long)vi, .name = vi->name, .qual.原创 2021-02-10 11:08:56 · 704 阅读 · 0 评论 -
optee 提供的hwrng
如果没有专门的硬件来hwrng,则客户用trustos的optee来产生hwrng,这个是的实现在driver/char/hwrng/optee-rng.c中,前面已经看过hwrng代码的架构,我们重点看看核心函数read的实现static struct optee_rng_private pvt_data = { .optee_rng = { .name = DRIVER_NAME, .init = optee_rng_init, .cleanup = optee_rng_clean.原创 2021-02-05 10:57:36 · 514 阅读 · 1 评论 -
hwrng相关的sysfs
在driver/char/hwrng/core.c中会生成一个文件系统如下:可以查询可以选择的hwrng,可以看当前选择的hwrng,以及手动选择hwrng./sys/devices/virtual/misc/hw_random/rng_current[root@ip134 /]# cd /sys/devices/virtual/misc/hw_random/[root@ip134 hw_random]# lsdev power rng_available rng_current rng.原创 2021-02-04 11:30:33 · 475 阅读 · 0 评论 -
内核硬件随机数/dev/hwrng的一些规则
不管是否支持hwrng 都可以看到/dev/hwrng 这个字符设备,如果有真正的hwrng,则只是增加这个hwrng的随机性而已,同一个hwrng不能重复注册,而且会根据每个hwrng的quality 来选择一个质量最好的hwrng。这里举例如下:drivers\crypto\hisilicon\trng.cprobe 中的核心代码如下:trng->rng.name = pdev->name;#这里提供的读取硬件随机数的方法 trng->rng.read = hisi_trn.原创 2021-02-02 09:58:03 · 2447 阅读 · 0 评论 -
kernel调度域的初始化
kernel 调度支持多级,下面的例子就是支持2级调到,即第一级的MC和第二级的NUMA[root@localhost ~]# sysctl kernel.sched_domain.cpu0.domain0.namekernel.sched_domain.cpu0.domain0.name = MC[root@localhost ~]# sysctl kernel.sched_domain.cpu0.domain1.namekernel.sched_domain.cpu0.domain1.name.原创 2021-01-18 21:45:33 · 524 阅读 · 0 评论 -
内存屏障sy/ld/st的详细解释
在arch/arm64/include/asm/barrier.h 中定义了一些内存屏障#define mb() dsb(sy)#define rmb() dsb(ld)#define wmb() dsb(st)#define dma_mb() dmb(osh)#define dma_rmb() dmb(oshld)#define dma_wmb() dmb(oshst)这里面的sy/ld/st的详细解释如下:https://www.keil.com/support/man/doc.原创 2020-12-18 10:50:13 · 1331 阅读 · 0 评论 -
ACPI的forbidden_id_list
使用ACPI后,在driver/acpi/acpi_platform.c中会为bios 传过来的设备create device. 知道这个后,我们除了可以再grub中添加blacklist来禁止某个驱动外,还可以在driver/acpi/acpi_platform.c中的forbidden_id_list添加,这样kernel 就不会为这个设备创建device在driver/acpi/acpi_platform.c 中已经禁止的device如下static const struct acpi_devi.原创 2020-12-14 09:08:28 · 522 阅读 · 0 评论 -
SPE
SPE是Armv8.2的特性,SPE 是一种使用随机抽样对程序一种动态分析禁止。要使用spe :1: defconfig中必须打开ARM_SPE_PMU 2: 启动命令行参数加kpti=off通过命令perf list | grep arm_spe 就可以确认perf 是否支持speperf record -a -c 1024 -e arm_spe_0/branch_filter=0,ts_enable=0,pa_enable=0,load_filter=0,sotre_filter=0,min.原创 2020-12-01 10:47:10 · 1833 阅读 · 0 评论 -
修改kernel text 段为RW
kernel的text段是RO的,如果想改变text段为RW,可以关掉CONFIG_STRICT_KERNEL_RWX 和 CONFIG_STRICT_MODULE_RWX 这两个配置项#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX)bool rodata_enabled __ro_after_init = true;static int __init set_debug_rodata(char *.原创 2020-11-25 08:56:01 · 1365 阅读 · 0 评论 -
arm64 中的__virt_to_phys
在arm64上的线性映射区还是可以通过__virt_to_phys 来将虚拟地址转成物理地址,我们来看看其在arm64上的实现#define __virt_to_phys(x) __virt_to_phys_nodebug(x)#define __is_lm_address(addr) (!(((u64)addr) & BIT(vabits_actual - 1)))#low memory的虚拟地址到物理转换#define __lm_to_phys(addr) (((addr) &.原创 2020-11-23 10:36:45 · 1325 阅读 · 0 评论 -
强制中断线程化threadirqs
kernel 提供了一个命令行参数threadirqs,这个参数会让irq 中断强制运行在thread context,这个时候不管用户是否设置中断线程化,都强制让中线运行在线程上下文中.static int __init setup_forced_irqthreads(char *arg){ force_irqthreads = true; return 0;}early_param("threadirqs", setup_forced_irqthreads);当命令行加threadir.原创 2020-11-23 09:18:28 · 1040 阅读 · 0 评论 -
spi 发送系统reboot 命令
一台机器上的/dev/spidev2.0 可以相应另外一台机器上spi master发出的命令,从而可以控制slave的机器来进行关机重启等动作。具体源代码在drivers/spi/spi-slave-system-control.c中目前支持的命令有CMD_REBOOT/CMD_POWEROFF/CMD_HALT/CMD_SUSPEND 这四个命令static void spi_slave_system_control_complete(void *arg) { struct spi_slav.原创 2020-10-28 09:59:23 · 545 阅读 · 0 评论 -
通过用户态驱动来读写spi 设备
当有一个spi device的时候,但是不想再内核态写spi_driver的话,可以使能CONFIG_SPI_SPIDEV这样的话会生成一个spidev.ko ,插入这个ko后就可以在用户态open((“/dev/spidev0.0”), O_RDWR)的方式pen 这个设备然后通过SPI_IOC_WR_MODE/SPI_IOC_RD_MODE 设置SPI_MODE_0,设置SPI_IOC_WR_BITS_PER_WORD/SPI_IOC_RD_BITS_PER_WORD为25000000,设置SPI.原创 2020-10-17 14:31:36 · 1604 阅读 · 0 评论 -
kernel.sched_domain.cpu0.domain0.flags
[root@localhost ~]# sysctl kernel.sched_domain.cpu0.domain0.flagskernel.sched_domain.cpu0.domain0.flags = 4655其中4655的十六进制是0x11d6,这个值的含义是啥呢?在linux/sched/topology.h 中通过下面的值组合处理#define SD_BALANCE_NEWIDLE 0x0001 /* Balance when about to become idle */#de.原创 2020-10-12 08:55:54 · 934 阅读 · 0 评论 -
内核加固CONFIG_HARDENED_USERCOPY
如果内核开启CONFIG_HARDENED_USERCOPY,则在从user space copy 数据到kernel space 时做一些检查,如果不是有效数据,则assert这部分代码在mm/usercopy.c 中,即使开启CONFIG_HARDENED_USERCOPY,也可以通过命令行来禁止这个特性来提高部分性能static bool enable_checks __initdata = true;static int __init parse_hardened_usercopy(c.原创 2020-10-10 14:57:32 · 1697 阅读 · 0 评论 -
内核对swi2c的实现
内核中对swI2c 有两个参考,一个是在driver/i2c/bus/i2c-gpio.c 中,要使用这的话,可以像正常使用i2c一样,客户不清楚下面是真的i2c还是用gpio 模拟的,这个直接链接到i2c的框架中国。但是这个需要bios来适配,另外一个实现在drivers/staging/sm750fb/ddk750_swi2c.c 中,这个文件中直接写死gpio,不需要bios 来配置。和i2c的适配层没有关系,i2c的读和写都是自己实现这里以scl的波形如何控制static void sw_i.原创 2020-09-02 14:59:41 · 538 阅读 · 0 评论 -
acpi来模拟dts
通过acpi来模拟dts 的文档在Documentation/firmware-guide/acpi/enumeration.rst 可以看到acpi来模拟dtd的关键是使用drivers/acpi/internal.h:237:#define ACPI_DT_NAMESPACE_HID "PRP0001"static bool __acpi_match_device(struct acpi_device *device, const struct acpi_device_id .原创 2020-09-02 10:38:19 · 1084 阅读 · 0 评论 -
pcie 总线性能调优的mps和mrrs
mps的全称是max-payload-size,它决定了每个TLP报文能够传输的最大净核字节数mrrs的全称是max-read-request-size,它是指每个读请求能读到的最大字节数这两个值可以通过lspci查到:如下所示DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported- RlxdOrd+ ExtTag+ PhantFunc- AuxPwr- NoSnoop- .原创 2020-08-11 09:37:18 · 6096 阅读 · 0 评论 -
usb phy
usb的phy 分为内置phy和外置phy,其中内置phy在控制器里面,内置phy 不需要驱动而外置phy 需要驱动,phy的目录在driver/phy 这个命令下。我们看看phy的主要功能我们以drivers/phy/marvell/phy-pxa-usb.c中的描述的phy为例usb是通过phy_ops 来控制phy的struct phy_ops { int (*init)(struct phy *phy); int (*exit)(struct phy *phy); int (*pow.原创 2020-08-06 13:56:46 · 2628 阅读 · 0 评论 -
CONFIG_ARM64_MODULE_PLTS 的作用
在模块加载的时候会调用module_alloc,从这个函数中可以看到,如果没有使能CONFIG_ARM64_MODULE_PLTS。模块只能使用128M的MODULES_VSIZE,如果是能了CONFIG_ARM64_MODULE_PLTS 且没有使能CONFIG_KASAN 的时候在128M 不够用的时候,将模块申请的size的范围拓展到2Gvoid *module_alloc(unsigned long size){ u64 module_alloc_end = module_alloc_.原创 2020-08-05 09:10:35 · 1293 阅读 · 0 评论 -
判断是否修复了熔断和幽灵
相应的代码driver/base/cpu.c中static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL);static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL);static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL);static DEVICE_ATTR(spec_store_bypass, ..原创 2020-08-03 08:57:59 · 814 阅读 · 0 评论 -
ftpm
ftpm的全称是firmware TPM,基本就是把原本需要外接tpm芯片做的事情放到firmware中其参考实现https://www.microsoft.com/en-us/research/publication/ftpm-software-implementation-tpm-chip/我们重点看看其kernel中驱动的中tpm_class_ops 的实现,char/tpm/tpm_ftpm_tee.cstatic const struct tpm_class_ops ftpm_tee_tp.原创 2020-07-21 19:39:45 · 10255 阅读 · 0 评论 -
tpmrm介绍
tpmrm 的全称是tpm resource manager。这样的tpm设备会带一个spaces,详细的解释如下:https://lwn.net/Articles/716259/This patch set adds support for TPM spaces that provide an isolatedexecution context for transient objects and HMAC and policy sessions. Aspace is swapped into TP.原创 2020-07-21 11:40:35 · 1173 阅读 · 0 评论 -
tpm 支持的命令和发送流程
tpm 的协议分为tpm1和tpm2 这里以tpm2为例tpm2 支持的命令定义在linux-master\include\linux\tpm.h中enum tpm2_command_codes { TPM2_CC_FIRST = 0x011F, TPM2_CC_HIERARCHY_CONTROL = 0x0121, TPM2_CC_HIERARCHY_CHANGE_AUTH = 0x0129, TPM2_CC_CREATE_PRIMARY ..原创 2020-07-21 09:45:46 · 1939 阅读 · 0 评论 -
TPM 设备
TPM的全称是Trusted Platfrom Module ,其是一个微控制器,可以存储密匙,密码和数字证书TPM 目前看有SPI和I2C 两种接口,其一般嵌入到主板上,主要用于低于外部软件攻击和物理偷窃,保证信息存储的安全,目前有tpm1 和 tpm2 两个标准。其代码的路径在drivers\char\tpm,可以看到tpm 至少是一个字符设备.obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o我们以atmel为例来看看如果写tpm的驱动这是一个独立的模块,其入口.原创 2020-07-20 10:06:10 · 3272 阅读 · 0 评论 -
kernel 支持的hugepage size
一般我们通过在命令行中添加参数hugepagesz 来指定大页的size,这部分代码的实现如下:static __init int setup_hugepagesz(char *opt){ unsigned long ps = memparse(opt, &opt); switch (ps) {#ifdef CONFIG_ARM64_4K_PAGES case PUD_SIZE:#endif case CONT_PMD_SIZE: case PMD_...原创 2020-05-14 08:54:50 · 1571 阅读 · 0 评论 -
perf stat 中event和rxx的对应关系
perf event 的实现在linux/arch/arm64/kernel/perf_event.c中例如static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = { PERF_MAP_ALL_UNSUPPORTED, [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR...原创 2020-05-06 18:32:48 · 1054 阅读 · 0 评论 -
CPU Steal time
CPU Steal time 是指虚拟机vm需要执行某个命令但是没有抢到物理cpu来执行的时间.其实现在arch/arm64/kernel/paravirt.c这个特性对应一个kconfig CONFIG_PARAVIRT,开了这个能提高系统性能.开了这个config后,这个特性就使能了,但是这个特性应该只在guest kernel中使用,host的kernel中则可以关掉这个特性sta...原创 2020-04-27 15:15:57 · 2054 阅读 · 0 评论 -
scp pm domain
在spci_pm_domian.c中会为支持power on 和 power off的设备提供scp 的接口。其入口函数是scpi_pm_domain_probestatic int scpi_pm_domain_probe(struct platform_device *pdev){ #每个设备可能有多个power domain ret = of_property_read_u32...原创 2020-04-02 20:45:57 · 1339 阅读 · 0 评论 -
scp 处理clk_get_val 的流程
linux 中怎么使用scp呢?首先在arm_scpi.c中export了 get_scpi_ops 这样其他驱动可以调用get_scpi_ops来使用spcistatic struct scpi_ops scpi_ops = { .get_version = scpi_get_version, .clk_get_range = scpi_clk_get_range, .clk_get...原创 2020-04-02 10:57:55 · 1363 阅读 · 1 评论 -
scp
scp的全称是System Control and Management Interface ,其对应的源码为https://github.com/ARM-software/SCP-firmware其主要功能如下:Initialization of the system to enable application core bootRuntime services:Power dom...原创 2020-04-02 09:04:02 · 2240 阅读 · 0 评论 -
根据dev_name 找到对应的驱动文件
开机的log中打印下面的log,那怎么根据这个log找到对应的驱动呢?00:01: ttyS0 at MMIO 0x3f00002f8 (irq = 15, base_baud = 115200) is a 16550A这段对应的源码如下:static inline voiduart_report_port(struct uart_driver *drv, struct uart_por...原创 2020-03-30 21:05:14 · 1914 阅读 · 0 评论 -
memory-less node
开机log中提示memory-lessnode,所谓的memory-lessnode就是这个node上没有内存对应的numactl -H如下:可见node 0和 2上确实没有内存,这就dmesg中的log对应起来,static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn){ ...原创 2020-03-17 14:12:17 · 1188 阅读 · 0 评论 -
KBUILD_MODNAME
在下面这个代码中KBUILD_MODNAME是在哪里定义的呢static struct virtio_driver virtio_iommu_drv = { .driver.name = KBUILD_MODNAME, .driver.owner = THIS_MODULE, .id_table = id_table, .feature_table = features, ....原创 2020-01-06 14:30:57 · 5476 阅读 · 0 评论 -
cpu_freq之切换governor.
系统中提供五个governor(conservative ondemand userspace powersave performance )策略来选择,但是具体是在哪里选择的呢?不管从哪里选择都是要调用cpufreq_set_policy来设定governor static int cpufreq_set_policy(struct cpufreq_policy *policy, str原创 2016-08-15 15:09:44 · 3921 阅读 · 0 评论