【操作系统笔记】链接阶段ELF文件

链接阶段:符号解析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

链接阶段主要包含:

  • 符号解析
  • 重定位

一般情况下,每个 C 文件可以看成一个程序模块,比如下边的main.c就是一个程序模块

#include <stdio.h>extern int shared; 
int sum(int *a, int n); int array[2] = {1, 2}; 
static int m = 10;static int swap(int *a, int *b) 
{int tmp = *a;*a = *b;*b = tmp; 
}int main() {static int b = 4;int val = sum(array, 2); swap (&val, &shared);printf("%d, %d\n", val, shared); return val;
}

每个程序模块一般会:

  1. 自己定义一些符号,称为符号定义
  2. 引用其他模块的符号,称为符号引用

符号定义:

  • 全局符号:非静态 C 函数和全局变量,比如上面代码中的 arraymain

  • 局部符号static 修饰的 C 函数和全局变量,相当于 Java/C++ 中的 private 比如上面代码中的 mswap

  • 本地符号:函数内部定义的符号
    1)非静态本地变量,比如上面代码中的val
    2)静态本地变量,比如上面代码中的b

  • 外部符号:引用其他模块定义的全局符号,比如上面代码中的 sharedsum以及 printf

说明:除了非 static 局部符号外,其他符号都是在链接器管理范畴。程序在运行时,函数中本地变量,属于函数调用栈管理。每个程序模块,在编译后,都会有一个符号表,用于记录程序模块中的符号。

上面代码中涉及 3 个外部符号:sharedsumprintf,其中 printf 符号是在 printf.o 程序模块中, gcc 工具会帮你自动找到。sharedsum 符号需要在 sum.o 程序模块中找到。这就是符号解析需要做的工作:输入的其他的程序模块中的符号表中,为每个外部符号,寻找确定的符号定义,并且关联它们。

在这里插入图片描述

链接阶段:重定位(Relocation)

在这里插入图片描述
在这里插入图片描述

  • 汇编后的.o文件中每个指令的位置,只是这条指令在文件中的偏移量,不是内存地址,所以此时.o文件还不能直接加载到内存运行。

  • 在链接阶段,合并所有.o文件中的指令,重新定位这些指令的位置,并为每个指令分配唯一内存地址。还需要重新定位外部符号的内存地址。这就是为什么.o文件称为可重定位目标文件!!!

  • 经过链接之后变成可执行目标文件,这时才可以加载到内存运行。

静态链接库

静态链接:将多个可重定位目标文件,合并成一个可执行目标文件。

在这里插入图片描述

静态库很有用,实现了程序代码的复用。但是,因为静态库的链接属于静态链接,会出现浪费内存的现象。比如,程序 A 和程序 B 都静态链接了 libvector.a 静态库,那么当程序 A 和程序 B 同时在运行时,内存中会有两份 libvector.a 的代码指令。

在这里插入图片描述

将静态链接库编译成动态链接库,就可以解决多份.a文件同时使用会重复浪费内存的问题。

ELF - 可重定位目标文件格式

在这里插入图片描述

一个典型的 ELF 目标文件的格式包含:ELF 头若干个节 (section) 以及描述节的头部表 (节头部表),如下图:

在这里插入图片描述

我们边对照着下面的程序,然后边看看以上每个节都存储些啥。

#include <stdio.h>extern int shared;int sum(int *a, int n);int array[2] = {1, 2};
static int m = 10;
int* arr_p = (int*)&array;int c;static int swap(int *a, int *b)
{int tmp = *a;*a = *b;*b = tmp;
}int main()
{static int b = 4;static int m;int val = sum(array, 2);swap(&val, &shared);printf("%d, %d\n", val, shared);return val;
}
  • .text :用于已编译程序的机器代码,通过下面的命令可以看到 .text 中存储的机器代码
objdump -Dj .text main2.o
// 查看二进制存储
objdump -sj .text main2.o
  • .rodata :用于存储只读数据,比如 printf 语句中的格式串等,通过下面的命令可以查看:
objdump -Dj .rodata main2.o
objdump -sj .rodata main2.o
  • .data :存储已初始化的全局和静态 C 变量,比如 arraym 等。非静态的局部 C 变量在运行的时候被保存在栈中,不会出现在 .data 中,
objdump -Dj .data main2.o
objdump -sj .data main2.o
  • .bss :未初始化的全局和静态 C 变量,以及所有被初始化为 0 的全局或静态变量。
objdump -Dj .bss main2.o
objdump -sj .bss main2.o

在上面的程序中,只有静态变量 m.bss 中,未初始化的全局变量 c ,会出现在可执行目标文件中的 .bss 中,在目标文件中,这个 .bss 节不占据实际的空间,它仅仅是一个占位符。

区分初始化和未初始化变量的目的是为了节省空间,未初始化变量不需要占据任何实际的磁盘空间

在运行的时候,给这些变量分配内存,并初始化为 0,所以所有被初始化为 0 的全局或静态变量也放在 .bss 中。

  • .symtab :符号表,存放程序中定义和引用的函数和全局符号的信息
objdump -t main2.o
  • .rel.text :也可以使用 .rela.text 表示,存储 .text 节中需要重定位的条目
objdump -rj .text main2.o

在这里插入图片描述

一般而言,以下两种情况需要重定位:

  1. 引用全局变量 (不管是内部还是外部)
  2. 调用外部函数

可以通过下面的指令来查看哪些指令需要生成重定位条目:

objdump -dx main2.o
  • .rel.data :也可以使用 rela.data 表示,存储 .data 节中需要重定位的条目
objdump -rj .data main2.o

在这里插入图片描述
以上的重定位条目来源于全局变量 arr_p

一般而言,任何已初始化的全局变量,如果它的初始值是一个全局变量地址或者外部定义函数的地址,都需要重定位。

ELF 文件格式详解

对上面的程序编译成可重定位目标文件,我们可以使用 readelf 来查看 ELF 文件的格式

readelf -all main2.o

我们先看看 ELF Headers

ELF Header:Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class:                             ELF64Data:                              2's complement, little endianVersion:                           1 (current)OS/ABI:                            UNIX - System VABI Version:                       0Type:                              REL (Relocatable file)Machine:                           Advanced Micro Devices X86-64Version:                           0x1Entry point address:               0x0Start of program headers:          0 (bytes into file)Start of section headers:          1232 (bytes into file)Flags:                             0x0Size of this header:               64 (bytes)Size of program headers:           0 (bytes)Number of program headers:         0Size of section headers:           64 (bytes)Number of section headers:         14Section header string table index: 11

ELF Headers 是以一个 16 字节的数字开头,然后是生成该文件的字节顺序 (小端序)

还描述了文件的类型,这里是 REL ,表示的是可重定位目标文件,还有可执行目标文件,比如 prog 文件

还描述了机器类型,这里是 x86-64,还有节头部表的的文件偏移 (也就是节头部表在文件中起始位置),还有节头部表的大小和节的数目

接下来看看节头部表 (section header table)

Section Headers:[Nr] Name              Type             Address           OffsetSize              EntSize          Flags  Link  Info  Align[ 0]                   NULL             0000000000000000  000000000000000000000000  0000000000000000           0     0     0[ 1] .text             PROGBITS         0000000000000000  000000400000000000000076  0000000000000000  AX       0     0     1[ 2] .rela.text        RELA             0000000000000000  000003f80000000000000090  0000000000000018   I      12     1     8[ 3] .data             PROGBITS         0000000000000000  000000b8000000000000001c  0000000000000000  WA       0     0     8[ 4] .rela.data        RELA             0000000000000000  000004880000000000000018  0000000000000018   I      12     3     8[ 5] .bss              NOBITS           0000000000000000  000000d40000000000000004  0000000000000000  WA       0     0     4[ 6] .rodata           PROGBITS         0000000000000000  000000d40000000000000008  0000000000000000   A       0     0     1[ 7] .comment          PROGBITS         0000000000000000  000000dc000000000000002e  0000000000000001  MS       0     0     1[ 8] .note.GNU-stack   PROGBITS         0000000000000000  0000010a0000000000000000  0000000000000000           0     0     1[ 9] .eh_frame         PROGBITS         0000000000000000  000001100000000000000058  0000000000000000   A       0     0     8[10] .rela.eh_frame    RELA             0000000000000000  000004a00000000000000030  0000000000000018   I      12     9     8[11] .shstrtab         STRTAB           0000000000000000  000001680000000000000066  0000000000000000           0     0     1[12] .symtab           SYMTAB           0000000000000000  000001d000000000000001e0  0000000000000018          13    13     8[13] .strtab           STRTAB           0000000000000000  000003b00000000000000043  0000000000000000           0     0     1
Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings), l (large)I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)O (extra OS processing required) o (OS specific), p (processor specific)

节头部表描述了每一个节所在的位置和大小。包含了下面的 10 个字段:

  • Name 表示节的名称
  • Type 表示节的类型,NULL 表示无效的节,PROGBITS 表示包含了程序代码的节,RELA 表示包含重定位条目的节,STRTAB 表示包含了字符串表的节
  • Address 表示节在内存中的其实地址,因为可重定位目标文件是不可执行的,所以还没有内存地址,可执行文件中会记录每个节的其实内存地址
  • Offset 表示节的在文件中的偏移,也就是节在文件中存储的位置
  • Size 表示节中存储数据的大小
  • EntSize 表示节中每个条目的大小,前提是节中的条目大小是固定长度的,比如 symtab 符号表等
  • Flags 表示节的一些属性,比如 .text 的 flags 为 AX,表示可重定位且可执行
  • Link 表示当前节关联的其他节
  • Info 表示当前节的一些额外信息
  • Align 表示节中存储数据大小对应字节大小对齐,比如 4 字节对齐,8 字节对齐等

接下来看看 .symtab 符号表

Symbol table '.symtab' contains 20 entries:Num:    Value          Size Type    Bind   Vis      Ndx Name0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS main2.c2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 4: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 5: 0000000000000008     4 OBJECT  LOCAL  DEFAULT    3 m6: 0000000000000000    44 FUNC    LOCAL  DEFAULT    1 swap7: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 8: 0000000000000000     4 OBJECT  LOCAL  DEFAULT    5 m.21929: 0000000000000018     4 OBJECT  LOCAL  DEFAULT    3 b.219110: 0000000000000000     0 SECTION LOCAL  DEFAULT    8 11: 0000000000000000     0 SECTION LOCAL  DEFAULT    9 12: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 13: 0000000000000000     8 OBJECT  GLOBAL DEFAULT    3 array14: 0000000000000010     8 OBJECT  GLOBAL DEFAULT    3 arr_p15: 0000000000000004     4 OBJECT  GLOBAL DEFAULT  COM c16: 000000000000002c    74 FUNC    GLOBAL DEFAULT    1 main17: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND sum18: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND shared19: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND printf

字段解释:

  • Value 表示符号在对应节中的偏移位置
  • Size 表示符号表示的对象的大小
  • Type 表示符号的类型,NOTYPE 表示没有指定类型,FILE 表示文件类型,SECTION 表示一个节类型,FUNC 表示一个函数,OBJECT 表示的是一个变量
  • Bind 表示 LOCAL 和 GLOBAL
  • Vis
  • Ndx 符号所属的节的 index 值,UND 表示未定义的符号,ABS 表示绝对值,不参与重定位,COM 表示属于 COMMON 节,其他数字表示对应的节的 index
  • Name 表示符号的名字

sections 每节在文件中的具体位置

接下来,我们来看看每一节在可重定位目标文件中的具体位置

在文件的开头是 ELF Header:

ELF Header:Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class:                             ELF64Data:                              2's complement, little endianVersion:                           1 (current)OS/ABI:                            UNIX - System VABI Version:                       0Type:                              REL (Relocatable file)Machine:                           Advanced Micro Devices X86-64Version:                           0x1Entry point address:               0x0Start of program headers:          0 (bytes into file)Start of section headers:          1232 (bytes into file)Flags:                             0x0Size of this header:               64 (bytes)Size of program headers:           0 (bytes)Number of program headers:         0Size of section headers:           64 (bytes)Number of section headers:         14Section header string table index: 11

Entry point address 等于 0,表示的就是 ELF Header 位于文件开头,

Size of this header 等于 64 字节,表示的是 ELF Header 的大小是 64 个字节,那么 ELF Header 是从 0 ~ 63

Start of section headers 等于 1232 字节,表示的是 section headers table 也就是节头部表位于文件中第 1232 字节,根据这个,我们可以得到节头部表的内容:

Section Headers:[Nr] Name              Type             Address           OffsetSize              EntSize          Flags  Link  Info  Align[ 0]                   NULL             0000000000000000  000000000000000000000000  0000000000000000           0     0     0[ 1] .text             PROGBITS         0000000000000000  000000400000000000000076  0000000000000000  AX       0     0     1[ 2] .rela.text        RELA             0000000000000000  000003f80000000000000090  0000000000000018   I      12     1     8[ 3] .data             PROGBITS         0000000000000000  000000b8000000000000001c  0000000000000000  WA       0     0     8[ 4] .rela.data        RELA             0000000000000000  000004880000000000000018  0000000000000018   I      12     3     8[ 5] .bss              NOBITS           0000000000000000  000000d40000000000000004  0000000000000000  WA       0     0     4[ 6] .rodata           PROGBITS         0000000000000000  000000d40000000000000008  0000000000000000   A       0     0     1[ 7] .comment          PROGBITS         0000000000000000  000000dc000000000000002e  0000000000000001  MS       0     0     1[ 8] .note.GNU-stack   PROGBITS         0000000000000000  0000010a0000000000000000  0000000000000000           0     0     1[ 9] .eh_frame         PROGBITS         0000000000000000  000001100000000000000058  0000000000000000   A       0     0     8[10] .rela.eh_frame    RELA             0000000000000000  000004a00000000000000030  0000000000000018   I      12     9     8[11] .shstrtab         STRTAB           0000000000000000  000001680000000000000066  0000000000000000           0     0     1[12] .symtab           SYMTAB           0000000000000000  000001d000000000000001e0  0000000000000018          13    13     8[13] .strtab           STRTAB           0000000000000000  000003b00000000000000043  0000000000000000           0     0     1

从上面可以看到 .text 节的 Offset 等于 0x00000040,也就说 .text 是从第 64 个字节开始,也就是位于 ELF Header 后面,.text 节的 Size 等于 0x0000000000000076,也就是 118 字节

.text 是从 64 ~ 181 字节段,对于 .text 需要 4 字节对齐,也就是 .text 实际大小为 120,那么 .text 就是从 64 ~ 183 字节段

接下来是 .data 节,起始位置为 184 字节,即 0xb8, .data 的大小是 0x1c

接下来是 .bss 和 .rodata 节,它们俩的起始位置都是:0xb8 + 0x1c = 0xd4,但是 .bss 是不占据磁盘空间的,只是作为标记而已

所以 0xd4 开始存储的实际上是 .rodata 节,大小为 0x8,接下来是 0xd4 + 0d8 = 0xdc,存储的是 .comment

按照上面的逻辑,可以将每一个部分定位在文件的具体位置上:

在这里插入图片描述
以上,我们可以通过偏移定位到每一个节的位置

在节的内部,也可以通过偏移定位节内的数据,比如符号表中:

Symbol table '.symtab' contains 20 entries:Num:    Value          Size Type    Bind   Vis      Ndx Name0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS main2.c2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 4: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 5: 0000000000000008     4 OBJECT  LOCAL  DEFAULT    3 m6: 0000000000000000    44 FUNC    LOCAL  DEFAULT    1 swap7: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 8: 0000000000000000     4 OBJECT  LOCAL  DEFAULT    5 m.21929: 0000000000000018     4 OBJECT  LOCAL  DEFAULT    3 b.219110: 0000000000000000     0 SECTION LOCAL  DEFAULT    8 11: 0000000000000000     0 SECTION LOCAL  DEFAULT    9 12: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 13: 0000000000000000     8 OBJECT  GLOBAL DEFAULT    3 array14: 0000000000000010     8 OBJECT  GLOBAL DEFAULT    3 arr_p15: 0000000000000004     4 OBJECT  GLOBAL DEFAULT  COM c16: 000000000000002c    74 FUNC    GLOBAL DEFAULT    1 main17: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND sum18: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND shared19: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND printf

符号 b 的值位于第 3 节,也就是 .data 节,它在 .data 节的 0x18 这个位置上,也就是第 24 个字节,值为 0x04000000,注意二进制是小端序存储的,所以 0x04000000 实际上是等于 0x00000004

objdump -sj .data main2.o

总结

接下来,我们来总结下 ELF 中所有的表,如下图:
在这里插入图片描述

  • 通过 ELF Header 中的信息,可以知道 ELF Header 的大小,以及节索引表的位置
  • 根据节索引表,就可以找到所有的节
  • 根据符号表,我们就可以知道所有的符号在每一个节中的偏移位置
  • 符号表用于链接阶段中符号解析
  • 链接阶段中的重定位需要用到 .rela.text 和 rela.data 等表

ELF - 可执行目标文件格式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

ELF - 可执行目标文件也是由ELF头节头部表以及若干个节组成。

  • .text.rodata.data.bss这 些节已经被重定位到它们最终的运行时内存地址

  • init 节定义了一个小函数,叫做_init,程序的初始化代码会调用它

  • 因为文件是完全链接的(已被重定位),所以它不再需要 .rela 节了

为了使得 ELF 可执行目标文件更加容易加载到内存,根据指令和数据的特点,将可执行文件连续的节映射到连续的内存段中。

段头部表维护了这层映射关系:

在这里插入图片描述

总结

在这里插入图片描述
在这里插入图片描述

ELF 可执行目标文件格式跟 ELF 可重定位目标文件格式其实是差不多类似的,只不过多了一个 段头部表,另外每个部分的偏移地址被映射成了真实的内存地址。

也就是说,可重定位目标文件(.o文件)中每条指令和数据只有在文件中的相对偏移位置,到了链接阶段,才会真正的为每条指令和数据分配内存地址,因此才能加载到内存中执行,所以此时叫可执行目标文件。

一个程序的内存布局

一个程序需要的内存:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springcloud3 分布式事务-seata的四种模式总结以及异地容灾

一 seata四种模式比较 1.1 seata的4种模式比较 二 seata的高可用 2.1架构 1.建TC服务集群非常简单&#xff0c;启动多个TC服务&#xff0c;注册到nacos即可。 2.做异地多机房容灾&#xff0c;比如一个TC集群在上海&#xff0c;另一个TC集群在杭州&#xff0c; 3.微服务基…

TuyaLink 快速入门教程

通过本入门教程&#xff0c;大家能了解到如何在涂鸦 IoT 开发平台上使用 TuyaLink 完成智能设备接入。并通过 Java 程序&#xff0c;在 IntelliJ IDEA 中使用 TuyaLink 的 GitHub Demo 工程&#xff0c;对一个电工开关设备&#xff0c;实现基本的数据上报下发功能。 准备工作 …

jmeter基础压力教程

Jmeter基础压力测试教程 一、安装Jmeter&#xff1b; 安装需求&#xff1a;1. JDK 8.0.91安装包&#xff08;最新即可&#xff0c;配置环境变量&#xff09; 2. Badboy2.25脚本录制工具&#xff08;注&#xff1a;Jmeter3.0与badboy2.0不兼容&#xff09; Jmerter安装包…

【数据库系统概论】关系数据库中的关系数据结构

前言关系关系模式关系数据库关系模型的存储结构感谢 &#x1f496; 前言 上一篇文章【数据库系统概论】数据模型介绍了数据库系统中的数据模型的基本概念。其中提到了关系模型是最重要的一种数据模型。下面将介绍支持关系模型的数据库系统——关系数据库。 按照数据模型的三大…

C++之std::holds_alternative、std::get、std::variant应用实例(二百一十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

阿里云产品试用系列-Serverless 应用引擎 SAE

Serverless 应用引擎 SAE&#xff08;Serverless App Engine&#xff09;是一个全托管、免运维、高弹性的通用 PaaS平台。SAE 支持 Spring Boot、Spring Cloud、Dubbo、HSF、Web 应用和 XXL-JOB、ElasticJob任务的全托管&#xff0c;零改造迁移、无门槛容器化、并提供了开源侧诸…

VUE3写后台管理(3)

VUE3写后台管理&#xff08;3&#xff09; 1.环境1.node2.vite3.Element-plus4.vue-router5.element icon6.less7.vuex8.vue-demi9.mockjs10.axios11.echarts 2.首页1.布局Main2.头部导航栏CommonHeader3.左侧菜单栏CommonLeft4.首页Home1.从后端获取数据显示到前端table的三种…

vue动态修改浏览器title和icon图标

vue动态修改浏览器title和icon图标 实例代码 setTitleIcon(){var link document.querySelector("link[rel*icon]") || document.createElement(link);link.type image/x-icon;link.rel shortcut icon;link.href /002.png; // 图片放public目录document.getElem…

SSM - Springboot - MyBatis-Plus 全栈体系(十)

第二章 SpringFramework 五、Spring AOP 面向切面编程 4. Spring AOP 框架介绍和关系梳理 AOP是一种区别于OOP的编程思维&#xff0c;用来完善和解决OOP的非核心代码冗余和不方便统一维护问题&#xff01;代理技术&#xff08;动态代理|静态代理&#xff09;是实现AOP思维编…

红黑树的定义和性质以及插入、删除操作

1.红黑树发明的原因 分析二叉排序树&#xff0c;平衡二叉树&#xff0c;红黑树的算法效率&#xff1a; BSTAVL TreeRed-Black Tree时间196019621972时间复杂度&#xff08;增删查&#xff09; O ( n ) O(n) O(n) O ( l o g 2 n ) O(log_2n) O(log2​n) O ( l o g 2 n ) O(log…

激光雷达录制pcap类型的包

查看IP 上图中的eno1就是网卡名&#xff0c;就可以使用如下命令录制 sudo tcpdump -i eno1 host 192.168.1.200 -w lidar.pcap-i 后面是网卡名&#xff0c;host 后面是ip&#xff0c;-w后是pcap包名称。

Ubuntu 22.04安装过程

iso下载地址 Ubuntu Releases 1.进入引导菜单 选择Try or Install Ubuntu Server安装 2.选择安装语言 默认选择English 3.选择键盘布局 默认即可 4.选择安装服务器版本 最小化安装 5.配置网络 选择ipv4 选择自定义 DHCP也可 6.配置代理 有需要可以配置 这里跳过 7.软件源 …

群晖 Docker版qbittorrent 下载显示错误 解决方法

这些天在折腾AIO玩&#xff0c;PVE虚拟机底层&#xff0c;核显直通&#xff0c;群晖安装&#xff0c;免不了踩些坑。 今天写篇博客&#xff0c;讲述一下群晖 Docker版qbittorrent 下载显示错误的解决方法&#xff0c;顺便记录一下配置&#xff0c;以便日后折腾可以参考。 直接…

几个国内可用的强大的GPT工具

前言&#xff1a; 人工智能发布至今&#xff0c;过去了九个多月&#xff0c;已经成为了我们不管是工作还是生活中一个重要的辅助工具&#xff0c;大大提升了效率&#xff0c;作为一个人工智能的自然语言处理工具&#xff0c;它给各大行业的提供了一个巨大的生产工具&#xff0c…

机器学习算法基础--逻辑回归

目录 1.数据收集及处理 2.数据提取及可视化 3.逻辑回归训练样本并且测试 4.绘制散点决策边界 逻辑回归的方法已经在数学建模里面讲过了&#xff0c;这里就不多讲了。 本篇我们主要是利用逻辑回归的方法来求解分类问题。 1.数据获取及处理 import pandas as pd from sklearn…

【深度学习框架格式转化】【CPU】Pytorch模型转ONNX模型格式流程详解【入门】

【深度学习框架格式转化】【GPU】Pytorch模型转ONNX模型格式流程详解【入门】 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【深度学习框架格式转化】【GPU】Pytorch模型转ONNX模型格式流程详解【入门】前言PyTorch模型环境搭建(CPU)安装onn…

中国汽车供应商远赴德国,中国智驾方案能否远渡重洋?

作者|Amy 编辑|德新 今年的上海车展&#xff0c;中国智能汽车的进步有目共睹&#xff0c;吸引了大批外企高管和研发人员的关注&#xff0c;甚至引发了海外车企一系列的动作和调整。 而在刚刚结束的慕尼黑车展&#xff0c;中国车企及汽车供应链把「肌肉」秀到了现代汽车起源地…

大模型如何赋能智能客服

2022年&#xff0c;大模型技术的出色表现让人们瞩目。随着深度学习和大数据技术的发展&#xff0c;大模型在很多领域的应用已经成为可能。许多公司开始探索如何将大模型技术应用于自己的业务中&#xff0c;智能客服也不例外。 智能客服是现代企业中非常重要的一部分&#xff0…

Python 图形化界面基础篇:创建工具栏

Python 图形化界面基础篇&#xff1a;创建工具栏 引言 Tkinter 库简介步骤1&#xff1a;导入 Tkinter 模块步骤2&#xff1a;创建 Tkinter 窗口步骤3&#xff1a;创建工具栏步骤4&#xff1a;向工具栏添加工具按钮步骤5&#xff1a;处理工具按钮的点击事件步骤6&#xff1a;启动…

基于matlab实现的卡尔曼滤波匀加速直线运动仿真

完整程序&#xff1a; clear clc %% 初始化参数 delta_t 0.1; %采样时间 T 8; %总运行时长 t 0:delta_t:T; %时间序列 N length(t); %序列的长度 x0 0; %初始位置 u0 0; %初速度 U 10; %控制量、加速度 F [1 delta_t 0 1]; %状态转移矩阵 B …