当前位置: 首页 > news >正文

Linux 知识(2)

在这里插入图片描述

系列文章目录


Linux内核学习
Linux 知识(1)
Linux 知识(2)


文章目录

  • 系列文章目录
  • 内核帮助文档生成
  • 内核启动参数
    • 1、引导参数
    • 2、__setup 宏
  • Linux 目录介绍
    • 1、boot 目录
    • 2、/lib/modules
      • 示例
    • 3、sys 目录
  • 设备模型
    • 1、概述
    • 2、uevent
    • 3、字符设备注册相关接口
  • kthread
  • ioremap
  • debugfs


内核帮助文档生成

内核 Doc 文档指南

sudo apt-get update
apt install python3-sphinx# 检查 Sphinx 依赖项
./scripts/sphinx-pre-instal
sudo apt-get install graphviz
sudo apt-get install imagemagick
# 安装GraphViz和ImageMagick包处理图片输出make htmldocs
# 生成的文档放在 Documentation/output 文件夹中

内核启动参数

Linux内核启动配置项
Linux操作系统内核启动参数详解
uboot如何向内核传递参数
内核启动参数详解配合代码分析
U-Boot与kernel之间的参数传递机制完全解析
uboot如何向内核传递参数

# 设置U-Boot环境变量
setenv bootargs 'console=ttyS0,115200 root=/dev/nfs nfsroot=192.168.1.100:/nfsroot/rootfs ip=192.168.1.101:192.168.1.100:192.168.1.1:255.255.255.0::eth0:off'
# 保存环境变量
saveenv
# 启动内核
bootm 0x10000

1、引导参数

  • root:指定根文件系统的位置。例如,root=/dev/sda1表示根文件系统在第一个 SATA 硬盘的第一个分区上。
  • ro/rw:分别表示以只读或读写方式挂载根文件系统。通常在启动过程中先以只读方式挂载,在文件系统检查完成后切换为读写方式。
  • init:设置内核执行的初始化进程名,如果该项没有设置,内核会按顺序尝试 /init , /sbin/init,/etc/init,/bin/init, /bin/sh,如果所有的都没找到,内核会抛出 kernel panic:的错误。
  • console:指定控制台设备。例如,console=ttyS0,115200表示使用串口 0 作为控制台,波特率为 115200。

2、__setup 宏

Linux内核__setup 宏的作用及分析

static int __init root_dev_setup(char *line)
{strscpy(saved_root_name, line, sizeof(saved_root_name));return 1;
}__setup("root=", root_dev_setup);

底软驱动 | Linux内核中ioremap映射的透彻理解
为什么Linux操作寄存器要ioremap
mmap与ioremap

linux设备驱动程序——bus
设备驱动模型–bus_type详解
bus_register

bus_register: 工作就是完成 bus_type_private 的初始化。创建注册的这条总线需要的目录文件。
    在这条总线目录下创建 /device /driver 目录
    初始化这条总线上的设备链表:struct klist klist_devices;
    初始化这条总线上的驱动链表:struct klist klist_drivers;
   
    每次有一个新的设备注册到上面,都会去匹配右边的驱动,看是否能匹配上 。如果匹配成功,则将设备结构的 is_registerd 域置为 0。然后将设备添加到驱动的 p->klist_devices 域 。同理,每注册一个驱动,都会去匹配左边的设备,如果匹配成功,将则设备加到驱动的 p->klist_devices 域 ,再将设备的 is_registerd 置为 0 。

ls /sys/bus/
acpi         container  event_source  mdev    nvmem        platform  serio  virtio
clockevents  cpu        hid           memory  pci          pnp       usb    vmbus
clocksource  dax        i2c           nd      pci_express  scsi      vdpa   workqueue

class_register:
    class_register(&pcibus_class);
    将会在 /sys/class 目录下产生一个 “pci_bus” 的目录。

ls /sys/class/
bdi    devlink  iommu    misc     phy           ptp          scsi_generic  uio           vtconsole
block  drm      ipvtap   nd       power_supply  rtc          scsi_host     vc
bsg    hidraw   macvtap  net      ppp           scsi_device  thermal       vfio
cuse   input    mem      pci_bus  pps           scsi_disk    tty           virtio-ports

linux驱动开发-深入探索linux内核设备驱动模型

Linux 目录介绍

1、boot 目录

Linux中 /boot 目录介绍
Linux中/boot目录

  1. config-4.14.0-kali3-amd64
    当前 Linux 系统的 kernel 配置文件,可以使用下面指令查看。
cat /boot/config-4.14.0-kali3-amd64 | mor
  1. initrd.img-4.14.0-kali3-amd64(cpio格式)
    initrd 全名 initial ram disk,启动系统所需加载的虚拟磁盘。它是 vmlinuz 的映像文件。
  2. vmlinuz-4.14.0-kali3-amd64
    linux 的正式内核。
  3. System.map-4.14.0-kali3-amd64
    内核符号映射表,顾名思义就是将内核中的符号(也就是内核中的函数)和它的地址能联系起来的一个列表。
  4. grub
    引导加载程序相关的文件。

2、/lib/modules

    /lib/modules 目录通常包含了 Linux 内核的模块文件。这些模块可以在需要时动态加载到内核中。自动加载驱动程序通常意味着当某些事件发生时,系统会自动加载相应的内核模块。

    在Linux系统中,可以使用 modprobe 命令来自动加载模块。modprobe 基于内核配置中的依赖关系和模块参数来决定是否自动加载模块。

    如果你需要在系统启动时自动加载特定的内核模块,你可以编辑 /etc/modules-load.d目录下的配置文件或者在 /etc/modules 文件中直接添加模块名。

示例

    例如,如果你想自动加载名为 mymodule 的模块,你可以执行以下步骤之一:

  1. 创建一个新的配置文件 /etc/modules-load.d/mymodule.conf 并在其中写入模块名:
mymodule
  1. 编辑 /etc/modules 文件,在文件末尾添加模块名:
mymodule

    在系统下次启动时,这些模块将会自动通过 modprobe 或 insmod 加载。

系统启动后自动加载 modules


    另外,你也可以通过 udev 规则来管理设备节点,在特定事件(如插入某个设备)发生时自动执行 modprobe 命令。

3、sys 目录

linux驱动开发-深入探索linux内核设备驱动模型

目录意义
block块设备
bus系统中的总线
class设备类型,比如输入设备
dev系统中已注册的设备节点的视图,有两个子目录 char 和 block 。
devices系统中所有设备拓扑结构视图
fireware固件
fs文件系统
kernel内核配置选项和状态信息
module模块
power系统的电源管理数据

设备模型

1、概述

linux设备驱动程序——bus
设备驱动模型–bus_type详解
bus_register
linux驱动开发-深入探索linux内核设备驱动模型

bus_register: 工作就是完成 bus_type_private 的初始化。创建注册的这条总线需要的目录文件。
    在这条总线目录下创建 /device /driver 目录
    初始化这条总线上的设备链表:struct klist klist_devices;
    初始化这条总线上的驱动链表:struct klist klist_drivers;
   
    每次有一个新的设备注册到上面,都会去匹配右边的驱动,看是否能匹配上 。如果匹配成功,则将设备结构的 is_registerd 域置为 0。然后将设备添加到驱动的 p->klist_devices 域 。同理,每注册一个驱动,都会去匹配左边的设备,如果匹配成功,将则设备加到驱动的 p->klist_devices 域 ,再将设备的 is_registerd 置为 0 。

ls /sys/bus/
acpi         container  event_source  mdev    nvmem        platform  serio  virtio
clockevents  cpu        hid           memory  pci          pnp       usb    vmbus
clocksource  dax        i2c           nd      pci_express  scsi      vdpa   workqueue

class_register:
    class_register(&pcibus_class);
    将会在 /sys/class 目录下产生一个 “pci_bus” 的目录。

ls /sys/class/
bdi    devlink  iommu    misc     phy           ptp          scsi_generic  uio           vtconsole
block  drm      ipvtap   nd       power_supply  rtc          scsi_host     vc
bsg    hidraw   macvtap  net      ppp           scsi_device  thermal       vfio
cuse   input    mem      pci_bus  pps           scsi_disk    tty           virtio-ports

2、uevent

Linux设备模型(四) - uevent应用:内核发送uevent,用户空间接收uevent
详解linux内核的uevent机制
linux驱动开发-深入探索linux内核设备驱动模型

3、字符设备注册相关接口

一文搞懂内核中cdev的各种注册函数
《Linux驱动:register_chrdev、alloc_chrdev_region、register_chrdev_region》

Linux 系统中主设备号和次设备号的范围如下‌:

‌1. 主设备号‌:主设备号占据 12 个位,范围从0到4095。主设备号用于区分设备的类别或类型,告诉操作系统应该使用哪个驱动程序来处理这类设备。例如,字符设备、块设备等都有固定的主设备号‌

2‌. 次设备号‌:次设备号占据20个位,范围从0到1048575。次设备号用于区分同一类设备中的不同实例或子设备。例如,同一个SCSI硬盘的不同分区会有相同的主设备号但不同的次设备号‌。

kthread

linux内核kthread_create
再探 kernel_threads-1
再探Kernel Threads -2

ioremap

底软驱动 | Linux内核中ioremap映射的透彻理解
为什么Linux操作寄存器要ioremap
mmap与ioremap

    在将I/O内存资源的物理地址映射成核心虚地址后,理论上讲我们就可以象读写RAM那样直接读写I/O内存资源了。为了保证驱动程序的跨平台的可移植性,我们应该使用Linux中特定的函数来访问I/O内存资源,而不应该通过指向核心虚地址的指针来访问。如在x86平台上,读写I/O的函数如下所示:

#define readb(addr) (*(volatile unsigned char *) __io_virt(addr))
#define readw(addr) (*(volatile unsigned short *) __io_virt(addr))
#define readl(addr) (*(volatile unsigned int *) __io_virt(addr))#define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b))
#define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b))
#define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b))#define memset_io(a,b,c) memset(__io_virt(a),(b),(c))
#define memcpy_fromio(a,b,c) memcpy((a),__io_virt(b),(c))
#define memcpy_toio(a,b,c) memcpy(__io_virt(a),(b),(c))// =========================================
// 一个调试示例代码
static inline __attribute__((__gnu_inline__)) __attribute__((__unused__))
__attribute__((no_instrument_function)) unsigned int
readl(const volatile void *addr)
{unsigned int ret;asm volatile("mov""l"" %1,%0": "=r"(ret): "m"(*(volatile unsigned int *)addr): "memory");return ret;
}

debugfs

debugfs文件系统
Linux内核之debugfs_create_dir与debugfs_create_file实例与调用栈流程(三十二)

debugfs 文件系统一般挂在 /sys/kernel/debug 目录上。

debugfs的相关操作函数:

  1. 创建和销毁文件
    debugfs_create_file(): 用于在 debugfs 中创建一个新的文件。
    debugfs_create_u32(), debugfs_create_u64(): 用于创建一个包含 32 位或 64 位整数的文件。
    debugfs_create_bool(): 用于创建一个布尔类型的文件。
  2. 创建目录
    debugfs_create_dir(): 用于在 debugfs 中创建一个新的目录。
  3. 读写文件内容
    simple_read_from_buffer(), simple_write_to_buffer(): 用于读取和写入文件的内容。
  4. 注册和注销
    debugfs_create_regset32(), debugfs_create_regset64(): 用于创建一个寄存器集合,允许用户空间读写内核寄存器的值。
    debugfs_remove(): 用于从 debugfs 中删除文件或目录。
  5. 其他
    debugfs_create_blob(): 用于创建一个二进制数据的文件。
    debugfs_create_symlink(): 用于创建一个符号链接。


   
 

Ctrl + Alt + V


http://www.mrgr.cn/news/82829.html

相关文章:

  • unity学习14:unity里的C#脚本的几个基本生命周期方法, 脚本次序order等
  • 1.07 标准IO
  • 引领实时数据分析新时代:阿里云实时数仓 Hologres
  • 解密Navicat密码(Java)
  • uniapp 导入uview-plus,使用组件出现,页面出现<up-parse>元素不存在,请检查你的代码
  • C# XPTable 带图片的增删改查(XPTable控件使用说明十三)
  • 《Vue3 七》插槽 Slot
  • 神经网络第一课
  • c++ thread线程join、detach、joinable方法
  • Java(1)入门基础
  • 数据结构-栈与队列笔记
  • 快速入门Spring Cloud Alibaba,轻松玩转微服务
  • 设计模式与游戏完美开发(3)
  • QT实现 端口扫描暂停和继续功能 3
  • 30、论文阅读:基于小波的傅里叶信息交互与频率扩散调整的水下图像恢复
  • 【HarmonyOS】鸿蒙应用点9图的处理(draw9patch)
  • Github提交Pull Request教程 Git基础扫盲(零基础易懂)
  • imageio 图片转mp4 保存mp4
  • 【FTP 协议】FTP主动模式
  • 【TextIn—智能文档解析与DocFlow票据AI自动化处理:赋能企业文档数字化管理与数据治理的双重利器】
  • 【学Rust开发CAD】1 环境搭建
  • WebRtc02: WebRtc架构、目录结构、运行机制
  • unity3d-搞个场景漫游如何实现Alpha
  • Java内存模型与线程
  • 《异步编程之美》— 全栈修仙《Java 8 CompletableFuture 对比 ES6 Promise 以及Spring @Async》
  • 2024年AI图像生成热门模型回顾