【ARM 嵌入式 编译系列 10 -- GCC 编译缩减可执行文件 elf 文件大小】
文章目录
- GCC 如何缩减可执行文件size
- 测试代码
上篇文章:ARM 嵌入式 编译系列 9-- GCC 编译符号表(Symbol Table)的详细介绍
下篇文章:ARM 嵌入式 编译系列 10.1 – GCC 编译缩减可执行文件 elf 文件大小
GCC 如何缩减可执行文件size
在开发过程总,总是希望编译出来的可执行文件尽量小,因为这样可以节省更多的磁盘空间,那么有什么方法可以缩小可执行文件的大小的?
A: 通常我们会首先移除了debug信息,移除了符号表信息,同时我们还希望万一出事了,比如coredump了,我们能获取更多的信息。
Linux下是怎么解决这个矛盾的呢?
先看第一个问题,移除debug相关信息的影响。
测试代码
如下实现了测试代码,main
调用了 foo
,foo
调用了 bar
,其中bar
故意访问了非法地址,为了引起 core dump
。
#include<stdio.h>
#include<stdlib.h>static int bar(void)
{char *p = NULL;printf("I am bar,I will core dump\n");printf("%s",p);*p =0x0;return 0;
}static int foo(void)
{int i ;printf("I am foo,I will call bar\n");bar();return 0;
}int main(void)
{printf("I am main, I wll can foo\n");foo();return 0;
}
先编译出一个 debug 版本来,然后我们看到可执行程序的大小为 17464
bytes.
gcc -g test.c -o test
ls -rtl test
-rwxrwxr-x 1 codingcos codingcos 17464 8月 14 09:43 test
再看下 section 信息:
readelf -S test
There are 37 section headers, starting at offset 0x3af8:Section Headers:[Nr] Name Type Address OffsetSize EntSize Flags Link Info Align[ 0] NULL 0000000000000000 000000000000000000000000 0000000000000000 0 0 0[ 1] .interp PROGBITS 0000000000000318 00000318000000000000001c 0000000000000000 A 0 0 1[ 2] .note.gnu.pr[...] NOTE 0000000000000338 000003380000000000000030 0000000000000000 A 0 0 8[ 3] .note.gnu.bu[...] NOTE 0000000000000368 000003680000000000000024 0000000000000000 A 0 0 4[ 4] .note.ABI-tag NOTE 000000000000038c 0000038c0000000000000020 0000000000000000 A 0 0 4[ 5] .gnu.hash GNU_HASH 00000000000003b0 000003b00000000000000024 0000000000000000 A 6 0 8[ 6] .dynsym DYNSYM 00000000000003d8 000003d800000000000000c0 0000000000000018 A 7 1 8[ 7] .dynstr STRTAB 0000000000000498 000004980000000000000094 0000000000000000 A 0 0 1[ 8] .gnu.version VERSYM 000000000000052c 0000052c0000000000000010 0000000000000002 A 6 0 2[ 9] .gnu.version_r VERNEED 0000000000000540 000005400000000000000030 0000000000000000 A 7 1 8[10] .rela.dyn RELA 0000000000000570 0000057000000000000000c0 0000000000000018 A 6 0 8[11] .rela.plt RELA 0000000000000630 000006300000000000000030 0000000000000018 AI 6 24 8[12] .init PROGBITS 0000000000001000 00001000000000000000001b 0000000000000000 AX 0 0 4[13] .plt PROGBITS 0000000000001020 000010200000000000000030 0000000000000010 AX 0 0 16[14] .plt.got PROGBITS 0000000000001050 000010500000000000000010 0000000000000010 AX 0 0 16[15] .plt.sec PROGBITS 0000000000001060 000010600000000000000020 0000000000000010 AX 0 0 16[16] .text PROGBITS 0000000000001080 000010800000000000000174 0000000000000000 AX 0 0 16[17] .fini PROGBITS 00000000000011f4 000011f4000000000000000d 0000000000000000 AX 0 0 4[18] .rodata PROGBITS 0000000000002000 000020000000000000000055 0000000000000000 A 0 0 4[19] .eh_frame_hdr PROGBITS 0000000000002058 000020580000000000000044 0000000000000000 A 0 0 4[20] .eh_frame PROGBITS 00000000000020a0 000020a000000000000000ec 0000000000000000 A 0 0 8[21] .init_array INIT_ARRAY 0000000000003db0 00002db00000000000000008 0000000000000008 WA 0 0 8[22] .fini_array FINI_ARRAY 0000000000003db8 00002db80000000000000008 0000000000000008 WA 0 0 8[23] .dynamic DYNAMIC 0000000000003dc0 00002dc000000000000001f0 0000000000000010 WA 7 0 8[24] .got PROGBITS 0000000000003fb0 00002fb00000000000000050 0000000000000008 WA 0 0 8[25] .data PROGBITS 0000000000004000 000030000000000000000010 0000000000000000 WA 0 0 8[26] .bss NOBITS 0000000000004010 000030100000000000000008 0000000000000000 WA 0 0 1[27] .comment PROGBITS 0000000000000000 00003010000000000000002b 0000000000000001 MS 0 0 1[28] .debug_aranges PROGBITS 0000000000000000 0000303b0000000000000030 0000000000000000 0 0 1[29] .debug_info PROGBITS 0000000000000000 0000306b000000000000011a 0000000000000000 0 0 1[30] .debug_abbrev PROGBITS 0000000000000000 0000318500000000000000cd 0000000000000000 0 0 1[31] .debug_line PROGBITS 0000000000000000 000032520000000000000076 0000000000000000 0 0 1[32] .debug_str PROGBITS 0000000000000000 000032c800000000000000ea 0000000000000001 MS 0 0 1[33] .debug_line_str PROGBITS 0000000000000000 000033b2000000000000003d 0000000000000001 MS 0 0 1[34] .symtab SYMTAB 0000000000000000 000033f000000000000003a8 0000000000000018 35 20 8[35] .strtab STRTAB 0000000000000000 0000379800000000000001f5 0000000000000000 0 0 1[36] .shstrtab STRTAB 0000000000000000 0000398d000000000000016a 0000000000000000 0 0 1
Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings), I (info),L (link order), O (extra OS processing required), G (group), T (TLS),C (compressed), x (unknown), o (OS specific), E (exclude),D (mbind), l (large), p (processor specific)
然后,我们用 strip
命令将 debug info 去除,指令如下:
strip --strip-debug test
ls -rtl test
-rwxrwxr-x 1 codingcos codingcos 15912 8月 14 09:43 test
可执行文件的大小从17464
减小到了15912
。
去除掉 debug info 的 test 和之前的 test 有什么区别呢? 我们看下去除后的 section 信息:
readelf -S test
There are 31 section headers, starting at offset 0x3668:Section Headers:[Nr] Name Type Address OffsetSize EntSize Flags Link Info Align[ 0] NULL 0000000000000000 000000000000000000000000 0000000000000000 0 0 0[ 1] .interp PROGBITS 0000000000000318 00000318000000000000001c 0000000000000000 A 0 0 1[ 2] .note.gnu.pr[...] NOTE 0000000000000338 000003380000000000000030 0000000000000000 A 0 0 8[ 3] .note.gnu.bu[...] NOTE 0000000000000368 000003680000000000000024 0000000000000000 A 0 0 4[ 4] .note.ABI-tag NOTE 000000000000038c 0000038c0000000000000020 0000000000000000 A 0 0 4[ 5] .gnu.hash GNU_HASH 00000000000003b0 000003b00000000000000024 0000000000000000 A 6 0 8[ 6] .dynsym DYNSYM 00000000000003d8 000003d800000000000000c0 0000000000000018 A 7 1 8[ 7] .dynstr STRTAB 0000000000000498 000004980000000000000094 0000000000000000 A 0 0 1[ 8] .gnu.version VERSYM 000000000000052c 0000052c0000000000000010 0000000000000002 A 6 0 2[ 9] .gnu.version_r VERNEED 0000000000000540 000005400000000000000030 0000000000000000 A 7 1 8[10] .rela.dyn RELA 0000000000000570 0000057000000000000000c0 0000000000000018 A 6 0 8[11] .rela.plt RELA 0000000000000630 000006300000000000000030 0000000000000018 AI 6 24 8[12] .init PROGBITS 0000000000001000 00001000000000000000001b 0000000000000000 AX 0 0 4[13] .plt PROGBITS 0000000000001020 000010200000000000000030 0000000000000010 AX 0 0 16[14] .plt.got PROGBITS 0000000000001050 000010500000000000000010 0000000000000010 AX 0 0 16[15] .plt.sec PROGBITS 0000000000001060 000010600000000000000020 0000000000000010 AX 0 0 16[16] .text PROGBITS 0000000000001080 000010800000000000000174 0000000000000000 AX 0 0 16[17] .fini PROGBITS 00000000000011f4 000011f4000000000000000d 0000000000000000 AX 0 0 4[18] .rodata PROGBITS 0000000000002000 000020000000000000000055 0000000000000000 A 0 0 4[19] .eh_frame_hdr PROGBITS 0000000000002058 000020580000000000000044 0000000000000000 A 0 0 4[20] .eh_frame PROGBITS 00000000000020a0 000020a000000000000000ec 0000000000000000 A 0 0 8[21] .init_array INIT_ARRAY 0000000000003db0 00002db00000000000000008 0000000000000008 WA 0 0 8[22] .fini_array FINI_ARRAY 0000000000003db8 00002db80000000000000008 0000000000000008 WA 0 0 8[23] .dynamic DYNAMIC 0000000000003dc0 00002dc000000000000001f0 0000000000000010 WA 7 0 8[24] .got PROGBITS 0000000000003fb0 00002fb00000000000000050 0000000000000008 WA 0 0 8[25] .data PROGBITS 0000000000004000 000030000000000000000010 0000000000000000 WA 0 0 8[26] .bss NOBITS 0000000000004010 000030100000000000000008 0000000000000000 WA 0 0 1[27] .comment PROGBITS 0000000000000000 00003010000000000000002b 0000000000000001 MS 0 0 1[28] .symtab SYMTAB 0000000000000000 000030400000000000000330 0000000000000018 29 15 8[29] .strtab STRTAB 0000000000000000 0000337000000000000001db 0000000000000000 0 0 1[30] .shstrtab STRTAB 0000000000000000 0000354b000000000000011a 0000000000000000 0 0 1
我们可以看到.debug_aranges .debug_info .debug_abbrev .debug_line .debug_str .debug_line_str
debug 相关的 section 都已经不在了,原来的 37个section减少到了31个 sections。
但是我们注意到.symtab .strtab .shstrtab
符号表信息 和 字符串信息还在。此外,可以通过nm
命可以看到它们的具体信息这:
[09:53:16]shiqiang.zhu@selab-ThinkStation-P350 (*^~^*) ~/workbase/test> nm test
000000000000038c r __abi_tag
0000000000001169 t bar
0000000000004010 B __bss_start
0000000000004010 b completed.0w __cxa_finalize@GLIBC_2.2.5
0000000000004000 D __data_start
0000000000004000 W data_start
00000000000010b0 t deregister_tm_clones
0000000000001120 t __do_global_dtors_aux
0000000000003db8 d __do_global_dtors_aux_fini_array_entry
0000000000004008 D __dso_handle
0000000000003dc0 d _DYNAMIC
0000000000004010 D _edata
0000000000004018 B _end
00000000000011f4 T _fini
00000000000011ae t foo
0000000000001160 t frame_dummy
0000000000003db0 d __frame_dummy_init_array_entry
0000000000002188 r __FRAME_END__
0000000000003fb0 d _GLOBAL_OFFSET_TABLE_w __gmon_start__
0000000000002058 r __GNU_EH_FRAME_HDR
0000000000001000 T _init
0000000000002000 R _IO_stdin_usedw _ITM_deregisterTMCloneTablew _ITM_registerTMCloneTableU __libc_start_main@GLIBC_2.34
00000000000011d1 T mainU printf@GLIBC_2.2.5U puts@GLIBC_2.2.5
00000000000010e0 t register_tm_clones
0000000000001080 T _start
0000000000004010 D __TMC_END__
此时如果执行这个 test
可执行程序,会产生coredump
文件,如果使用gdb
调试coredump
文件的时候,我们可以打印出堆栈信息,因为符号表还在。
在往下进行之前我们先学习一个命令: ulimit
:
ulimit
是 如 Linux 中用于控制shell
和其创建的进程可以使用的系统资源。
ulimit -c
选项则用于设置核心文件(core dump
)的最大大小。当一个程序奔溃时,操作系统可以将程序的内存内容和一些调试信息保存到一个核心文件中,以便开发者可以查看这些信息来调试程序。这个文件通常被称为core dump。
使用ulimit -c
命令可以查询或设置 core文件的最大大小。例如:
ulimit -c
:查询当前core文件的最大大小。如果返回的是0,那么表示不会生成core文件;ulimit -c unlimited
:设置core文件的最大大小为无限,即允许core文件的大小不受限制。
注意:
ulimit -c
设置的限制仅对当前shell及其子进程有效,不会影响到其他shell或全局设置。在一些系统中,为了安全考虑,默认可能不启用 core dump,即使你使用ulimit -c unlimited
也不会生成 core文件。在这种情况下,你可能需要修改系统的核心设置或其他配置来启用core dump。1)使用ulimit -c查看core dump是否打开。如果结果为0,则表示此功能处于关闭状态,不会生成core文件, 执行 ulimit -c 1024
2)修改/etc/sysctl.conf文件【sudo vi /etc/sysctl.conf】,添加需要保存的路径【kernel.core_pattern = /tmp/corefile/core.%e.%t】
3)输入 sudo sysctl -p /etc/sysctl.conf 命令即刻生效
由于 symtab .strtab
.shstrtab
符号表信息 和 字符串信息还在,我们仍然可以使用 gdb
进行调试:
ulimit -c unlimited or ulimit -c 1024gdb -c /tmp/corefile/core.test.1691982639.1098584 test
Core was generated by `./test'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x0000560eb28091ab in bar () at test.c:10
10 *p =0x0;
(gdb) bt
#0 0x0000560eb28091ab in bar () at test.c:10
#1 0x0000560eb28091d1 in foo () at test.c:19
#2 0x0000560eb28091f4 in main () at test.c:27
(gdb)
虽然 debug 相关section已经去除,但是还有符号表信息,一旦出了core dump还可以进行debug。大部分的发行版的程序都会将符号表信息删除。如果符号表与可执行程序完全隔离,那将是一种什么样的情况的?请见下篇文章。
上篇文章:ARM 嵌入式 编译系列 9-- GCC 编译符号表(Symbol Table)的详细介绍
下篇文章:ARM 嵌入式 编译系列 10.1 – GCC 编译缩减可执行文件 elf 文件大小
相关文章:
【ARM 嵌入式 编译系列 10 -- GCC 编译缩减可执行文件 elf 文件大小】
文章目录 GCC 如何缩减可执行文件size测试代码 上篇文章:ARM 嵌入式 编译系列 9-- GCC 编译符号表(Symbol Table)的详细介绍 下篇文章:ARM 嵌入式 编译系列 10.1 – GCC 编译缩减可执行文件 elf 文件大小 GCC 如何缩减可执行文件s…...
IDEA启动报错java.nio.charset.MalformedInputException: Input length=2
IDEA启动报错java.nio.charset.MalformedInputException: Input length2 问题解决后记 问题 原本系统运行好好得,一段时间没打开,再次打开重启 IDEA启动报错java.nio.charset.MalformedInputException: Input length2。 解决 百度了 https://blog.csd…...

【Vue-Router】路由传参
1. query 传参 list.json {"data": [{"name": "面","price":300,"id": 1},{"name": "水","price":400,"id": 2},{"name": "菜","price":500,"…...

平板选择什么电容笔比较好?ipad手写笔推荐品牌
在现在的生活上,有了iPad平板,一切都变得简单了许多,也让我们的学习以及工作都更加的便利。这其中,电容笔就起到了很大的作用,很多人都不知道,到底要买什么牌子的电容笔?哪些电容笔的性价比比较…...
什么是数字化车间
一、数字化车间概述 数字化车间是以现代化信息、网络、数据库、自动识别等技术为基础,通过智能化、数字化、MES系统信息化等手段融合建设的数字化生产车间,精细地管理生产资源、生产设备和生产过程。随着工业4.0概念的提出,未来的工业和制造…...
创新零售,京东重新答题?
继新一轮组织架构调整后,京东从低价到下沉动作不断。 新成立的创新零售部在京东老将闫小兵的带领下悄然完成了整合。近日,京喜拼拼已改名为京东拼拼,与七鲜、前置仓等业务共同承载起京东线上线下加速融合的梦想。 同时,拼拼的更…...

面向对象设计与分析40讲(20)消息驱动编程和事件驱动编程模型
文章目录 消息驱动编程事件驱动编程消息驱动和事件驱动的区别 消息驱动编程 消息驱动是一种编程模型,它基于事件和消息的传递来驱动程序的执行流程。在消息驱动的模型中,系统中的各个组件(或对象)通过发送和接收消息进行通信和协…...

【c语言】指针进阶(超详细)
文章目录 ✈ 指向函数指针数组的指针📌指向函数指针数组的指针的定义📌指向函数指针数组的数组指针的使用 ✈回调函数📌 回调函数的定义📌 回调函数的使用 ✈qsort函数📌 qsort函数的作用📌qsort函数的定义…...

C++入门篇8---vector
vecctor是动态顺序表 一、了解vector的相关接口及其功能 1.构造函数相关接口 函数声明功能介绍vector()无参构造vector(size_type n,const value_type& valvalue_type())构造并初始化n个valvector(const value& x)拷贝构造vector(InputIterator first, InputIterato…...

【学会动态规划】最大子数组和(19)
目录 动态规划怎么学? 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 写在最后: 动态规划怎么学? 学习一个算法没有捷径,更何况是学习动态规划, 跟我…...

怎么做Tik Tok海外娱乐公会呢?新加坡市场怎么样?
一、为什么选择TikTok直播 1. 海外市场潜力巨大 • 自2016年始,多家直播平台陆续拓展至东南亚、中东、俄罗斯、日韩、欧美、拉美等地区。 • 海外市场作为直播发展新蓝海,2021年直播行业整申请cmxyci体规模达百亿美元,并维持高速增长。 &a…...

mysql主从复制搭建
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言MySQL复制过程分为三部: 一、准备工作二、配置>主库Master三、配置>从库SlaveSlave_IO_Running: YesSlave_SQL_Running: Yes 四、测试至此&am…...

Java:正则表达式案例:爬数据,重复数据替换,数据分割
使用正则表达式查找一段文本中的内容 需求:请把下面文本中的电话,邮箱,座机号码,热线都爬取出来。 String data "电话:1866668888,18699997777\n" "或者联系邮箱: boniuitcast.cn,\n" "座机…...
CF 765D Artsem and Saunders 构造
CF765D Artsem and Saunders 直接猜一种构造做法, h ( x ) h(x) h(x)的值域一定和 f ( x ) f(x) f(x)的值域一样,我们先满足 h ( g ( x ) ) f ( x ) h(g(x))f(x) h(g(x))f(x)这个条件,遍历 f ( x ) f(x) f(x),每次添加 h ( x ) h…...

DevOps系列文章 之 SpringBoot整合GitLab-CI实现持续集成
在企业开发过程中,我们开发的功能或者是修复的BUG都需要部署到服务器上去,而这部分部署操作又是重复且繁琐的工作,GitLab-CI 持续集成为我们解决了这一痛点,将重复部署的工作自动化,大大的节省了程序员们的宝贵时间。本…...

K8S系列二:实战入门
I. 配置kubectl 1.1 什么是kubectl? 官方文档中介绍kubectl是: Kubectl 是一个命令行接口,用于对 Kubernetes 集群运行命令。Kubectl的配置文件在$HOME/.kube目录。我们可以通过设置KUBECONFIG环境变量或设置命令参数–kubeconfig来指定其他…...

form中表单切换,导致 relus 中的事件无法触发,原因:页面切换不要一直切换DOM,会导致问题,需要都显示出来
修改前,因为重复渲染DOM导致绑定rules失效 修改前代码使用 computed 计算出渲染的DOM,影响rules事件<el-formref"form"inline:model"billDetailCopy":rules"rules"size"small"label-position"right&quo…...

Android Ble蓝牙App(五)数据操作
Ble蓝牙App(五)数据操作 前言正文一、操作内容处理二、读取数据① 概念② 实操 三、写入数据① 概念② 实操 四、打开通知一、概念二、实操三、收到数据 五、源码 前言 关于低功耗蓝牙的服务、特性、属性、描述符都已经讲清楚了,而下面就是使…...

.netcore grpc双向流方法详解
一、双向流处理概述 简单来讲客户端可以向服务端发送消息流,服务端也可以向客户端传输响应流,即客户端和服务端可以互相通讯客户端无需发送消息即可开始双向流式处理调用 。 客户端可选择使用 RequestStream.WriteAsync 发送消息。 使用 ResponseStream…...

【Servlet】(Servlet API HttpServlet 处理请求 HttpServletRequest 打印请求信息 前端给后端传参)
文章目录 Servlet APIHttpServlet处理请求 HttpServletRequest打印请求信息前端给后端传参 Servlet API Servlet中常用的API HttpServlet 实际开发的时候主要重写 doXXX 方法, 很少会重写 init / destory / service destory 服务器终止的时候会调用. //下面的注解把当前类和…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...