Linux驱动学习——Linux启动流程

news2024/11/24 20:58:03

什么是驱动

驱动,即设备驱动程序,是一种可以使计算机和设备通信的特殊程序。

从作用角度来看,驱动的主要功能是将硬件设备的功能与操作系统进行连接,让操作系统能够识别并正确使用硬件设备。例如,显卡驱动能让操作系统充分发挥显卡的图形处理能力,打印机驱动能使计算机顺利地向打印机发送打印指令。

从组成结构来说,驱动通常包含了硬件设备的各种控制指令、通信协议以及与操作系统交互的接口等。它就像是一个翻译官,在硬件设备和操作系统之间进行信息的转换和传递。

什么是Linux驱动 

Linux 驱动是专门为在 Linux 操作系统下使硬件设备正常工作而编写的软件程序。

在功能方面,它负责在 Linux 系统与硬件设备之间建立通信桥梁。通过驱动程序,Linux 系统能够识别硬件设备、控制其工作状态以及获取设备提供的数据等。例如,网卡驱动使得 Linux 系统能够连接网络,实现数据的收发;磁盘驱动则负责管理存储设备的读写操作。

从结构组成上看,Linux 驱动通常包含与硬件交互的底层代码、设备注册和初始化的模块、中断处理程序以及与 Linux 内核接口的部分等。它既要遵循 Linux 内核的编程规范和接口要求,又要针对特定硬件的特性进行优化设计。

什么是裸机驱动

裸机驱动是在没有操作系统的情况下,直接控制硬件设备的程序。

从功能上讲,裸机驱动主要负责初始化硬件设备、设置设备的工作模式和参数,并实现对设备的基本操作,如读写数据、控制设备状态等。它直接与硬件进行交互,不需要依赖操作系统提供的服务和接口。

在结构组成方面,裸机驱动通常由针对特定硬件的初始化代码、控制逻辑和中断处理程序等组成。由于没有操作系统的支持,裸机驱动需要更加关注硬件的细节和特性,以确保设备能够正确、高效地运行。

对于一些嵌入式系统开发或特定的硬件控制场景,裸机驱动具有重要意义。它可以提供更高效的硬件控制,减少系统资源的占用,并且能够在没有操作系统的环境下实现特定的功能需求

什么是搬移内核到内存

“搬移内核到内存” 是指在系统启动过程中,将存储在非易失性存储设备(如 NandFlash、NorFlash 等)中的 Linux 内核映像文件复制到计算机的内存中。

 

一、为什么要进行内核搬移

 
  1. 提高运行速度
    • 内存的读写速度通常比外部存储设备快得多。将内核加载到内存中运行,可以大大提高内核的启动速度和运行效率。例如,当系统需要快速响应外部事件或执行复杂的计算任务时,内存中的内核能够更快地进行处理。
  2. 直接访问
    • CPU 可以直接访问内存中的数据,而对于外部存储设备的访问通常需要通过特定的接口和控制器,这会增加访问的延迟。将内核搬移到内存中,使得 CPU 能够更快速地获取内核代码和数据,从而提高系统的整体性能。
 

二、搬移的过程

 
  1. 确定内核映像的位置
    • 在启动过程中,引导加载程序(如 U-Boot)首先需要确定内核映像在存储设备中的位置。这通常是通过读取特定的配置信息或预设的地址来实现的。例如,在 NandFlash 启动方式中,引导加载程序可能会根据预先设定的地址范围来查找内核映像。
  2. 读取内核映像
    • 一旦确定了内核映像的位置,引导加载程序会从存储设备中读取内核映像到内存中的特定位置。这个过程可能涉及到对存储设备的读写操作和数据传输。例如,通过特定的总线接口(如 SPI、I2C 等)从 NandFlash 中读取数据,并将其存储到内存的指定地址。
  3. 验证内核映像
    • 在将内核映像搬移到内存后,引导加载程序通常会对内核映像进行验证,以确保其完整性和正确性。这可以通过校验和、数字签名等方式来实现。如果内核映像损坏或不完整,引导加载程序可能会停止启动过程并报告错误。
  4. 启动内核
    • 当内核映像被成功搬移到内存并验证通过后,引导加载程序会将控制权转移到内存中的内核入口点,启动内核的执行。内核会进一步进行初始化和系统配置,最终启动整个操作系统。
 

三、不同启动方式下的内核搬移

 
  1. 从 NandFlash 启动
    • 在这种启动方式下,系统上电后会自动搬移 NandFlash 前 4KB 的程序到 IRAM 中,并将 0 地址映射到 0x40000000 地址处。引导加载程序在前 4KB 代码中初始化好内存,然后将 NandFlash 中的内核映像搬移到内存的特定地址(如 0x30008000)。最后,引导加载程序启动内存中的内核。
  2. 从 NorFlash 启动
    • 系统上电后,PC 默认指向 0 地址处,直接运行 NorFlash 中的程序。如果内核映像存储在 NorFlash 中,引导加载程序可以直接将内核从 NorFlash 搬移到内存中。或者,如果内核映像存储在其他位置(如通过网络下载),引导加载程序也可以从其他来源获取内核映像并搬移到内存中。
  3. 从网络启动(如通过 TFTP 和 NFS)
    • 在这种启动方式下,引导加载程序通过 TFTP 服务从网络上的服务器(如 Ubuntu 服务器)下载内核映像到内存的特定地址。然后,引导加载程序启动内存中的内核,并通过 NFS 服务挂载网络上的根文件系统。

内存和flash的区别

一、性质与特点

  1. 内存(RAM):
    • 属于易失性存储器,即当电源关闭时,其中存储的数据会立即丢失。
    • 具有高速读写的特点,能够快速响应 CPU 的指令,为 CPU 提供临时的数据存储和快速的数据交换空间。
    • 通常以动态随机存取存储器(DRAM)或静态随机存取存储器(SRAM)的形式存在。
  2. Flash:
    • 是非易失性存储器,即使断电后数据也不会丢失。
    • 读写速度相对较慢,但比传统的机械硬盘要快很多。
    • 常用于存储长期的数据,如操作系统、应用程序和用户文件等。

二、用途

  1. 内存:
    • 主要用于在计算机运行过程中暂时存储正在运行的程序和数据,以便 CPU 能够快速访问。
    • 对于需要频繁读写和快速响应的任务,如运行大型软件、进行多任务处理等,内存的性能至关重要。
  2. Flash:
    • 作为长期存储设备,用于保存操作系统、应用程序、文档、图片、视频等各种数据。
    • 在移动设备如手机、平板电脑和数码相机中,Flash 存储器广泛应用,因为它具有体积小、功耗低和非易失性的优点。

三、存储容量与成本

  1. 内存:
    • 通常存储容量相对较小,一般以 GB 为单位。例如,常见的个人电脑内存容量可能在 4GB 到 32GB 之间。
    • 由于其高速读写的特性和复杂的制造工艺,内存的成本相对较高。
  2. Flash:
    • 存储容量可以从几 GB 到数 TB 不等,适用于存储大量的数据。
    • 随着技术的不断进步,Flash 的成本逐渐降低,但相对于内存来说,仍然较为便宜。

四、数据读写方式

  1. 内存:
    • 可以随机访问任意地址的数据,读写速度非常快。
    • CPU 可以直接对内存进行读写操作,无需经过复杂的寻址过程。
  2. Flash:
    • 一般以块为单位进行读写操作,在写入数据之前可能需要先擦除整个块。
    • 读写速度相对较慢,并且在进行大量写入操作时,可能会因为擦除和写入的过程而导致性能下降。

norflash和nandflash的区别有哪些 

NorFlash 和 NandFlash 的区别主要体现在以下几个方面:

  1. 物理结构5:
    • NorFlash:采用并行连接的存储单元结构,每个存储单元都有独立的访问线。这使得它可以直接按字节读取,就像访问传统的存储器一样,能够同时读取和写入存储器中的每个字节。
    • NandFlash:采用串行连接的存储单元结构,多个存储单元被组合成一个页(page),多个页再组合成一个块(block),形成存储数组。读取和写入是以页为单位进行的,而非单个字节。
  2. 性能表现
    • 读取速度:NorFlash 的读取速度相对较快,可支持随机读取,适合快速获取代码指令等小数据量的随机读取操作16。NandFlash 的读取速度整体比 NorFlash 稍慢,但随着技术发展,差距在逐渐缩小。
    • 写入速度:NandFlash 的写入速度比 NorFlash 快很多。NorFlash 在写入前需要先将目标块内所有的位写为 0(擦除操作),且擦除是以较大的块为单位进行,导致写入效率较低;而 NandFlash 的写入操作相对简单,擦除单元也更小14。
    • 擦除速度:NandFlash 的擦除速度远快于 NorFlash。NorFlash 擦除一个块的时间可能需要 5s 左右,而 NandFlash 擦除一个块通常不超过 4ms1。
  3. 接口与使用方式3:
    • 接口:NorFlash 带有 SRAM 接口,有足够的地址引脚来寻址,可以直接和 CPU 相连,CPU 可以直接通过地址总线对 NorFlash 进行访问,存取其内部的每一个字节,接口较为简单。NandFlash 器件使用复杂的 I/O 口来串行地存取数据,8 个引脚用来传送控制、地址和数据信息,各个产品或厂商的方法可能各不相同,接口相对复杂。
    • 使用方式:NorFlash 可以在片内直接运行代码,应用程序可以直接在 NorFlash 闪存内运行,不必先把代码读到系统 RAM 中。NandFlash 不能在片内运行程序,使用时必须先写入驱动程序,才能进行其他操作3。
  4. 容量与成本
    • 容量:NorFlash 的容量相对较小,常见的有 128KB、256KB、1MB、2MB 等,一般在 1-16MB 左右。NandFlash 的容量较大,目前市面上的 NandFlash 产品容量可以从几 GB 到数 TB 不等23。
    • 成本:NorFlash 的成本相对较高,因为其生产工艺复杂、容量小。NandFlash 由于生产过程相对简单、存储密度高,在大容量的情况下成本更低3。
  5. 可靠性与耐用性3:
    • 可靠性:NorFlash 的可靠性较高,接口简单,数据操作少,位交换操作少,极少出现坏区块,一般用在对可靠性要求高的地方。NandFlash 的接口和操作相对复杂,位交换操作较多,出现问题的几率相对较大。
    • 耐用性:NandFlash 中每个块的最大擦写次数一般是一百万次,而 NorFlash 的擦写次数是十万次左右。但是由于 NandFlash 通常是整块擦写,块内的页面中如果有一位失效整个块就会失效,而且擦写过程复杂,失败的概率相对较高14。
  6. 应用场景
    • NorFlash:常用于存储代码和关键数据,如用于 BIOS 芯片、嵌入式系统中存放启动代码等对数据读取速度要求高、容量需求不大且对可靠性要求高的场景5。
    • NandFlash:适合于数据存储,如在固态硬盘(SSD)、U 盘、存储卡等需要大容量存储的设备中广泛应用。

Linux启动流程

Linux 的启动是一个复杂而有序的过程,主要包括启动 bootloader、启动内核以及加载(挂载)根文件系统三个关键阶段。

一、启动 bootloader

  1. 功能与性质
    • Bootloader 是一段裸机程序,其主要职责是为内核启动精心准备适宜的环境。一旦内核成功启动,CPU 的控制权便彻底移交至内核,此后 bootloader 不再被启动。任何具备此类功能的程序均可称为 bootloader。
  2. 具体操作步骤
    • 初始化 CPU:合理设置 CPU 的工作模式,确保其处于适合系统启动的最佳状态。
    • 初始化堆栈:为程序的运行构建临时数据存储区域,保障程序执行过程中数据存储和调用栈的稳定运作。
    • 初始化异常向量表:为系统处理各类异常情况(如中断、故障等)设定入口地址,确保在异常发生时能够准确地进行处理。
    • 初始化时钟:为系统提供精准的时间基准,保证各种与时间相关的操作(如定时器设置、任务调度等)得以正常进行。
    • 初始化内存:对系统内存进行检测和配置,为后续程序的加载和运行开辟可用的内存空间。
    • 关看门狗:防止程序运行过程中因看门狗超时而导致系统意外复位,确保系统稳定运行。
    • 关 Cache:在启动初期,为了确保对内存的直接操作准确无误,避免 Cache 可能带来的不一致性。Cache 作为一种高速缓存,能够加速 CPU 对内存的访问,但在某些特定情况下,尤其是在系统启动初期,需要直接操作物理内存,此时关闭 Cache 可以有效确保操作的准确性。
    • 关 MMU:MMU(内存管理单元)负责将虚拟地址转换为物理地址。然而在启动初期,需要直接操作物理地址,因此关闭 MMU 能够避免地址转换带来的复杂性。
    • 初始化相关硬件设备:包括调试串口、网口、LED 等。调试串口用于输出启动过程中的调试信息,为开发者进行问题排查提供便利;网口为系统提供网络连接功能,以便进行网络通信和文件下载等操作;LED 可以作为启动状态的指示,方便用户直观了解系统的运行情况。
    • 集成相关通信协议:若要进行通信操作,必须借助通信协议来定义帧格式。例如,在网络启动过程中,可能需要集成 TCP/IP 等通信协议,以确保与其他设备进行准确的数据传输。
    • 搬移内核到内存:将内核映像从存储设备(如 NandFlash 或通过网络从 Ubuntu 等服务器)搬移到内存中,以便 CPU 能够快速访问和执行内核代码。
    • 向内核传参:向内核传递重要的参数,如根文件系统的位置和调试端口等。根文件系统的位置信息告知内核在哪里能够找到文件系统,以便进行加载和挂载操作;调试端口信息则用于在开发和调试过程中输出调试信息。
  3. 启动方式
    • 在 NandFlash 上:对于s3c2440芯片来说,系统上电后,会自动搬移 NandFlash 前 4KB 的程序到 IRAM(内部随机存取存储器)中(这是一个自动的过程,但这个过程并不是每个处理器都支持),并将 0 地址映射到 0x40000000 地址处,程序就从这个地址开始跑。如果bootloader 程序大于4KB,在这前 4KB 代码中,bootloader 初始化好内存,并将自己剩余的部分搬移到内存中运行。
    • 在 NorFlash 中:系统上电后,PC(程序计数器)默认指向 0 地址处(norflash连接0地址处),直接运行 NorFlash 中的程序。

二、启动内核

  1. 内核的性质与功能
    • 内核(kernel)是一个复杂的程序,负责操作系统的核心功能,涵盖文件管理、进程管理、内存管理、网络管理和设备管理等多个重要方面。
  2. 获取、启动内核的方式
    • 在 NandFlash 上:bootloader 启动的最后阶段将 NandFlash 中的内核搬移到内存的 0x30008000 地址处(内存是被接到0x30000000地址处,从0x30000000到0x30008000之间的这一段内存放的是页表(用于记录虚拟地址和物理地址之间的关系)和参数),然后启动该地址处的内核。
    • 在 Ubuntu 上:bootloader 通过 TFTP(Trivial File Transfer Protocol)服务将 Ubuntu 上的内核下载到内存的 0x30008000 地址处,随后启动该地址处的内核。                (下载:tftp 0x30008000 uImage)

 

三、加载(挂载)根文件系统

  1. 根文件系统的组成与作用
    • 根文件系统(rootfs)是一堆文件的集合,其中包括配置文件、系统命令 / 用户程序以及普通文件等。配置文件用于设置系统的各种参数和选项,如网络配置、用户权限等;系统命令和用户程序是系统运行所必需的工具和应用程序;普通文件则包含各种数据文件和文档等。
  2. 启动方式
    • 在 NandFlash 上:直接挂载 NandFlash 的 mtdblock3 分区(人为的对存储空间的区域划分)上的根文件系统。
    • 在 Ubuntu 上:通过 NFS(Network File System)服务挂载 Ubuntu 上的根文件系统。在这种方式下,bootloader 通过网络从 Ubuntu 服务器下载内核,并将其加载到内存中启动。然后,通过 NFS 服务将 Ubuntu 上的根文件系统挂载到本地系统中,使得本地系统可以像访问本地文件系统一样访问 Ubuntu 上的文件。

 

以网络启动(通过 TFTP 和 NFS)的方式启动内核


首先向开发板的 NorFlash 中下载 uboot.bin。U-Boot(Universal Boot Loader)是一种广泛应用于嵌入式系统的引导加载程序,它负责初始化硬件设备、加载内核等重要任务。将 U-Boot 下载到 NorFlash 中,确保系统在启动时能够首先执行 U-Boot 程序。

在 Ubuntu 中安装 TFTP 服务并将 uImage(内核映像文件)拷贝到 TFTP 服务目录下。TFTP(Trivial File Transfer Protocol)是一种简单的文件传输协议,常用于嵌入式系统中快速传输小文件。通过 TFTP 服务,开发板可以从 Ubuntu 服务器上下载内核映像到特定的内存地址。

查看tftp服务是否已经安装

 

通过tftp服务,从tftpboot中下载文件到当前目录下(在哪个目录下使用tftp,文件就下载到哪个目录下) 

 

在 Ubuntu 中安装 NFS 服务,并将 rootfs.tar.gz(根文件系统压缩包)拷贝到 NFS 服务目录下并解压。NFS(Network File System)允许网络中的计算机之间共享文件系统。在这种启动方式中,开发板将通过 NFS 挂载 Ubuntu 服务器上的根文件系统,以便访问系统运行所需的各种文件和程序。

启动 minicom,这是一个用于串口通信的工具。通过 minicom,可以查看开发板的输出信息,进行调试和交互操作。

输入 “print” 查看环境变量。环境变量包含了系统启动时的各种参数和配置信息,通过查看环境变量可以了解当前系统的设置情况。

baudrate=115200:
定义了串口通信的波特率为 115200bps。

bootargs=root=/dev/nfs nfsroot=192.168.1.17:/home/linux/nfs/rootfs ip=192.168.1.100 console=ttySAC0,115200 init=/linuxrc:
root=/dev/nfs:指定根文件系统通过网络文件系统(NFS)挂载。
nfsroot=192.168.1.17:/home/linux/nfs/rootfs:指定 NFS 服务器的地址和共享的根文件系统路径。
ip=192.168.1.100:设置设备的 IP 地址。
console=ttySAC0,115200:将控制台输出重定向到串口ttySAC0,并使用与前面定义一致的波特率 115200。
init=/linuxrc:指定系统启动时执行的初始化程序为/linuxrc。

bootcmd=nand read 30000000 kernel;bootm 30000000:
nand read 30000000 kernel:从 NAND 闪存读取内核到内存地址 30000000。
bootm 30000000:从内存地址 30000000 启动内核。

bootdelay=5:
设置启动延迟为 5 秒,在此期间可以中断启动过程进入 U-Boot 命令行界面。

ethact=dm9000:
指定网络控制器为dm9000。

ethaddr=00:0c:29:4d:e4:f4:
设置设备的以太网 MAC 地址。

ipaddr=192.168.1.27:
设置设备的 IP 地址,与前面bootargs中的ip参数可能有不同的用途,具体取决于系统的启动流程。

mtddevname=u-boot:
指定 MTD(Memory Technology Device)设备名称为u-boot。

mtddevnum=0:
设置 MTD 设备编号为 0。

mtdids=nand0=jz2440-0:

定义 NAND 闪存的设备 ID,这里将其命名为nand0,对应型号为jz2440-0。

mtdparts=mtdparts=jz2440-0:256k(u-boot),128k(params),2m(kernel),-(rootfs):

定义 MTD 分区,对于jz2440-0设备,划分出不同大小的分区,分别用于存储 U-Boot(256KB)、参数(128KB)、内核(2MB)和根文件系统(剩余空间)。

netmask=255.255.255.0:

设置子网掩码为 255.255.255.0。

partition=nand0,0:

指定要使用的分区为nand0的第一个分区,可能是 U-Boot 分区。

serverip=192.168.1.17:

设置 NFS 服务器的 IP 地址。

stderr=serial、stdin=serial、stdout=serial:

将标准错误、标准输入和标准输出重定向到串口。

修改环境变量,设置启动参数。其中,“setenv bootargs root=/dev/nfs nfsroot=192.168.1.3:/home/linux/nfs/rootfs ip=192.168.1.99 console=ttySAC0,115200 init=/linuxrc” 这条命令设置了根文件系统的位置为 NFS 服务器上的特定目录,指定了开发板的 IP 地址、控制台设备和初始化程序等参数。

“ping serverip” 检查网络是否连通。确保开发板能够与 Ubuntu 服务器进行网络通信是成功启动的关键步骤之一。如果网络不通,可能会导致内核下载和根文件系统挂载失败。

“tftp 0x30008000 uImage” 下载 uImage 到内存的 0x30008000 地址处。这一步骤利用 TFTP 服务将内核映像从 Ubuntu 服务器下载到开发板的内存中,为启动内核做准备。

“bootm 0x30008000” 启动 0x30008000 地址处的内核。这是最后一步,通过引导加载程序(U-Boot)启动位于特定内存地址的内核,从而启动整个 Linux 系统。

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

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

相关文章

Java SE-object类和里面的3个主要方法解读

文章目录 1.object类2.toString方法调用过程2.1具体案例2.2源代码查看2.3方法的重写2.4重写效果 3.equals方法调用过程3.1现象的描述3.2方法的重写3.3IDEA自动填充 4.hashcode方法 1.object类 java里面除了object类,所有的类都是存在继承关系的,object类…

【Docker】03-自制镜像

1. 自制镜像 2. Dockerfile # 基础镜像 FROM openjdk:11.0-jre-buster # 设定时区 ENV TZAsia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # 拷贝jar包 COPY docker-demo.jar /app.jar # 入口 ENTRYPOINT ["ja…

javaweb-请求和响应

1.http协议 1.1请求 1.2.响应 常见响应状态码: 状态码大全:https://cloud.tencent.com/developer/chapter/13553 常见的响应头: 2.请求和响应 2.1.请求 2.1.1postman 作用:常用于接口测试 使用:官网安装-->注册…

电脑手机下载小米xiaomi redmi刷机包太慢 解决办法

文章目录 修改前下载速度修改后下载速度修改方法(修改host) 修改前下载速度 一开始笔者以为是迅雷没开会员的问题,在淘宝上买了一个临时会员后下载速度依然最高才100KB/s 修改后下载速度 修改方法(修改host) host文…

【星汇极客】STM32 HAL库各种模块开发之DHT11模块

前言 本人是一名嵌入式学习者,在大学期间也参加了不少的竞赛并获奖,包括:江苏省电子设计竞赛省一、睿抗机器人国二、中国高校智能机器人国二、嵌入式设计竞赛国三、光电设计竞赛国三、节能减排竞赛国三等。 暑假的时候参加了太多的比赛&#…

nacos启动报错:Unable to start embedded Tomcat

报错截图: 解决方法:编辑启动脚本/nacos/bin/startup.sh,指定模式为standalone即可 修改后启动成功~

vscode配置golang

1.安装golang解释器 从网址https://go.dev/dl/下载对应的golang解释器 2.配置环境 Extensions中搜索安装go 2.配置settings.json {"go.autocompleteUnimportedPackages": true,"go.gocodeAutoBuild": false,"explorer.confirmPasteNative"…

若依权限设计与自定义新增用户

前言 若依 系统的权限设计是基于RBAC(Role-Based Access Control),即基于角色的访问控制模型,允许通过角色来管理用户的权限。 每个用户可以分配一个或多个角色。用户的权限来自于其所分配的角色。用户与角色的对应关系保存在 sys…

llama3中文版微调

🏆本文收录于《全栈Bug调优(实战版)》专栏,主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&am…

数据结构--List的介绍

目录 1. 什么是List Collection中有那些方法? add(E e)方法 addAll(Collection c)方法 clear()方法 contains(Object o)方法 containsAll(Collection c)方法 equals(Object o)方法 hashCode()方法 isEmpty()方法 iterator()方法 remove(Object o)方法 …

[OS] 编译 Linux 内核

编译 Linux 内核:详细教程与 Kthreads 入门结合 我们将学习如何编译 Linux 内核,同时结合 Kthreads 的知识来理解各个步骤的目的。对于虚拟环境下的开发环境配置,本文将为你提供逐步指导。 1. 下载内核源代码 首先,我们需要从官…

数据结构——栈与队列的实现(全码)

一 栈的概念 栈是一种特殊的线性表,栈内数据遵循先进后出(LIFO)的原则,对于栈,只能在同一侧进行入栈和出栈操作。 入栈操作和出栈操作是在栈的同一侧进行的,如图示: 对于栈这种数据类型,我们可以采用链表或…

自动驾驶系列—揭秘毫米波雷达:自动驾驶的眼睛如何看穿复杂环境?

🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…

Linux:无法为立即文档创建临时文件: 设备上没有空间

虚拟机磁盘空间不足解决记录 1、问题描述2、问题解决 1、问题描述 在命令行输入命令按Tab键时出现如下报错: 很明显,设备上没有空间,即磁盘空间不足。通过命令查看具体情况如下: df -h2、问题解决 首先想到的是虚拟机扩容。关机虚…

【技术白皮书】内功心法 | 第一部分 | 数据结构与算法基础(数据结构)

数据结构与算法基础 内容简介数据结构数据模型数据结构的表现形式 基本概念数据(Data)数据元素(data element)数据结构的定义物理结构和逻辑结构逻辑结构逻辑结构表现形式二元组模型集合结构模型线性结构模型树结构模型图结构模型…

Python从0到100(六十):机器学习-模型选择与交叉验证

前言: 零基础学Python:Python从0到100最新最全教程。 想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Python爬虫、Web开发、 计算机视觉、机器学习、神经网络以及人工智能…

有限差分方法 - 拉普拉斯算子第二部分

Finite difference method - Laplacian part 2 — ROCm Blogs (amd.com) 2023年1月4日 作者:Justin Chang, Rajat Arora, Thomas Gibson, Sean Miller, Ossian O’Reilly 在之前的拉普拉斯算子文章中,我们开发了一种基于HIP实现的有限差分模板代码&#…

springboot车位预约小程序-计算机毕业设计源码42655

摘要 随着社会发展和人口增加,城市交通压力越来越大,停车位资源的分配和管理成为一个重要问题。传统的停车位和车位预约管理方式存在信息不对称、效率低下等问题,给用户带来不便。而基于微信小程序的车位预约系统可以通过智能化、数字化、便…

布尔莎公式推导

问题的提出 原始的围绕x轴、y轴、z轴进行旋转矩阵的公式为 但是最近需要将船体坐标系转换到相应的世界坐标系之中,在查看相关论文时,看到一个三维点公式转换模型 这里的旋转矩阵为,和我之前见到的旋转矩阵是不一样的。我一开始先是看到的202…

计算机网络-------重传、TCP流量控制、拥塞控制

重传、滑动窗口、流量控制、拥塞避免 重传机制 超时重传 发送方在发送数据时会启动一个定时器,当超过指定的时间之后,还没接收到接收方的ACK确认应答报文,就会重传该数据 快重传 当发送方收到接收方三个连续的ack之后说明发送方发送的报…