3-EMMC命令使用

在调试emmc的过程,我们需要用到命令读写emmc,烧录,查看emmc寄存器,设置寄存器等功能,所以uboot和linux下都有各自的命令可以使用。

1、 uboot下mmc命令

1.1、mmc信息

查看mmc信息:mmc info

描述了emmc的速率、大小、块大小等

MT7622> mmc info
Device: mmc@11230000
Manufacturer ID: 1
OEM: 100
Name: S4000 
Bus Speed: 48000000
Mode: MMC DDR52 (52MHz)
Rd Block Len: 512
MMC version 5.1
High Capacity: Yes
Capacity: 3.6 GiB
Bus Width: 8-bit DDR
Erase Group Size: 512 KiB
HC WP Group Size: 8 MiB
User Capacity: 3.6 GiB WRREL
Boot Capacity: 4 MiB ENH
RPMB Capacity: 4 MiB ENH
Boot area 0 is not write protected
Boot area 1 is not write protected

如果有多个mmc设备的时候,比如一个emmc、一个SD卡,这时候我们操作emmc之前需要先选择emmc设备

MT7622> mmc dev 0
mtk_sd mmc@11230000: sclk: 255319, timing: 0
mtk_sd mmc@11230000: sclk: 24000000, timing: 0
mtk_sd mmc@11230000: sclk: 12000000, timing: 4
switch to partitions #0, OK
mmc0(part 0) is current device
1.2、GPT分区表读取

查看gpt的分区地址后,这样我们收到操作emmc的时候,也知道每个分区的内容,避免写错。

MT7622> mmc partPartition Map for MMC device 0  --   Partition Type: EFIPart    Start LBA       End LBA         NameAttributesType GUIDPartition GUID1     0x00001000      0x00001fff      "fip"attrs:  0x0000000000000005type:   c12a7328-f81f-11d2-ba4b-00a0c93ec93bguid:   5452574f-2211-4433-5566-778899aabb012     0x00002000      0x000027ff      "ubootenv"attrs:  0x0000000000000001type:   0fc63daf-8483-4772-8e79-3d69d8477de4guid:   5452574f-2211-4433-5566-778899aabb023     0x00003000      0x0001afff      "firmware"attrs:  0x0000000000000000type:   cae9be83-b15f-49cc-863f-081b744a2d93guid:   5452574f-2211-4433-5566-778899aabb034     0x0001b000      0x00032fff      "firmware2"attrs:  0x0000000000000000type:   cae9be83-b15f-49cc-863f-081b744a2d93guid:   5452574f-2211-4433-5566-778899aabb045     0x00033000      0x000333ff      "zbootconfig"attrs:  0x0000000000000000type:   0fc63daf-8483-4772-8e79-3d69d8477de4guid:   5452574f-2211-4433-5566-778899aabb05

烧录的时候可以直接解析gpt中的firmware地址进行烧录

gpt_partition_list=fip ubootenv firmware firmware2 zbootconfig mmcsda1
1.3、读、写、擦

mmc 的读写擦都是使用块为单位,上面的mmc info可以知道一个block的大小是512KB

mmc read addr blk# cnt
mmc write addr blk# cnt
mmc erase blk# cnt

mmc读操作:

mmc read 0x4007FF28 0x600 0x10

读操作说明:从mmc设备块上1536*512个字节处开始(1536是0x600的十进制),读取16×512个字节(16是10的10进制)到内存0x10800000 处。

这边的512是根据mmc的块特性决定,上面mmcinfo里面的Block Len:512

以kernel为例,若前面的分区为94M(也就是kernel的分区从94M的地方开始),那么,0x600的地方的值应为:9421024的十六进制0x2F000。

读到这个地址后,可以用md.b打印内存信息 md 内存地址 长度

md.b 0x4007FF28 0x1000

MT7622> md.b 0x4007FF28
4007ff28: 88 16 88 58 90 29 04 00 55 2d 42 6f 6f 74 00 00    ...X.)..U-Boot..
4007ff38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
4007ff48: 00 00 00 00 00 00 00 00 00 00 e0 41 ff ff ff ff    ...........A....
4007ff58: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007ff68: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007ff78: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007ff88: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007ff98: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007ffa8: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007ffb8: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007ffc8: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007ffd8: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007ffe8: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007fff8: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
40080008: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
40080018: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................

写操作:

mmc write 0x90000000 0x600 0x10 

写操作说明:把内存0x90000000开始,长度为16x512大小的数据,写入到mmc设备块偏移位置为0x600处。

擦除操作:

mmc erase 0x600 0x10

擦除操作说明:从mmc设备块上1536*512个字节处开始(1536是0x600的十进制),擦除16×512个字节(16是10的10进制)。

1.4、固件升级

环境参数里面有很多命令参数

MT7622> printenv 
boot_default=run boot_firmware
boot_firmware=led $bootled_pwr on ; run emmc_read_firmware && bootm $loadaddr#$bootconf ; led $bootled_pwr off
boot_tftp_firmware=tftpboot $loadaddr $bootfile_firmware && env exists replacevol && iminfo $loadaddr && run emmc_write_firmware ; if env exists noboot ; then else bootm $loadaddr#$bootconf ; fi
boot_tftp_write_bl2=tftpboot $loadaddr $bootfile_bl2 && run emmc_write_bl2
boot_tftp_write_fip=tftpboot $loadaddr $bootfile_fip && run emmc_write_fip
bootcmd=run boot_firmware
bootconf=config@1
bootdelay=3
bootfile_bl2=openwrt-mediatek-mt7622-ZH-A0501-EMMC-squashfs-emmc-1ddr-preloader.bin
bootfile_fip=ZH-A0501-u-boot.fip
bootfile_firmware=openwrt-mediatek-mt7622-ZH-A0501-EMMC-squashfs-sysupgrade.bin
bootled_pwr=zihome:blue
bootled_rec=zihome:yellow
bootmenu_0=Default boot command.=run boot_default
bootmenu_1=Boot firmware system from eMMC.=run boot_firmware ; run bootmenu_confirm_return
bootmenu_2=Load firmware system via TFTP then write to eMMC.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_firmware ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return
bootmenu_3=Load BL31+U-Boot FIP via TFTP then write to eMMC.=run boot_tftp_write_fip ; run bootmenu_confirm_return
bootmenu_4=Load BL2 preloader via TFTP then write to eMMC.=run boot_tftp_write_bl2 ; run bootmenu_confirm_return
bootmenu_5=Reboot.=reset
bootmenu_6=Reset all settings to factory defaults.=run reset_factory ; reset
bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60
bootmenu_delay=3
bootmenu_title=      ( ( ( OpenWrt ) ) )  [eMMC]
emmc_read_firmware=mmc dev 0 && part start mmc 0 $part_firmware part_addr && part size mmc 0 $part_firmware part_size && run mmc_read_vol
emmc_write_bl2=mmc dev 0 1 && mmc partconf 0 1 1 1 && mmc erase 0x0 0x400 && mmc write $loadaddr 0x0 0x100 ; mmc partconf 0 1 1 0
emmc_write_fip=mmc dev 0 0 && mmc erase 0x1000 0x1000 && mmc write $loadaddr 0x1000 0x1000 && mmc erase 0x2000 0x800
emmc_write_firmware=mmc dev 0 && part start mmc 0 $part_firmware part_addr && part size mmc 0 $part_firmware part_size && run mmc_write_vol
ethact=ethernet@1b100000
gpt_partition_list=fip ubootenv firmware firmware2 zbootconfig mmcsda1
ipaddr=192.168.2.119
loadaddr=0x4007ff28
mmc_read_vol=mmc read $loadaddr $part_addr 0x8 && imszb $loadaddr image_size && test 0x$image_size -le 0x$part_size && mmc read $loadaddr 0x$part_addr 0x$image_size
mmc_write_vol=imszb $fileaddr image_size && test 0x$image_size -le 0x$part_size && mmc erase 0x$part_addr 0x$part_size && mmc write $fileaddr 0x$part_addr 0x$fileblk
part_firmware=firmware
reset_factory=eraseenv && reset
reset_type=0
serverip=192.168.2.88
ver=U-Boot 2021.10 (Feb 18 2022 - 06:51:54 +0000)Environment size: 2778/524283 bytes

升级的话我们可以使用上诉命令拆解,比如要升级fip文件。

正常我们是选择3进行升级

bootmenu_3=Load BL31+U-Boot FIP via TFTP then write to eMMC.=run boot_tftp_write_fip ; run bootmenu_confirm_return

3的实际命令就是boot_tftp_write_fip命令,这个命令实际又是两个命令组成

boot_tftp_write_fip=tftpboot $loadaddr $bootfile_fip && run emmc_write_fip

emmc_write_fip命令实际又是多个命令组成,所以我们可以一步一步自己执行

emmc_write_fip=mmc dev 0 0 && mmc erase 0x1000 0x1000 && mmc write $loadaddr 0x1000 0x1000 && mmc erase 0x2000 0x800
2、 linux下mmc命令

2.1、设备生成

内核启动后,驱动会将MMC的几个物理分区分别挂载成对应的设备

  • mmcblk0boot0、mmcblk0boot1、mmcblk0rpmb这是三个独立的分区,内核mtd不会使用到
  • mmcblk0分区就用用户分区,给内核mtd使用,只要再根据实际应用软件mtd分区
[    1.726828] mmc0: new DDR MMC card at address 0001
[    1.736013] mmcblk0: mmc0:0001 S40004 3.64 GiB 
[    1.741029] mmcblk0boot0: mmc0:0001 S40004 partition 1 4.00 MiB
[    1.747099] mmcblk0boot1: mmc0:0001 S40004 partition 2 4.00 MiB
[    1.753180] mmcblk0rpmb: mmc0:0001 S40004 partition 3 4.00 MiB
[    1.764627] Alternate GPT is invalid, using primary GPT.
[    1.769988]  mmcblk0: p1 p2 p3 p4 p5 p128
[    2.704843] 13 cmdlinepart partitions found on MTD device EMMC
[    2.710693] Creating 13 MTD partitions on "EMMC":
[    2.715400] 0x000000000000-0x000000200000 : "gpt"
[    2.720864] 0x000000200000-0x000000400000 : "fip"
[    2.726225] 0x000000400000-0x000000600000 : "uboot-env"
[    2.732165] 0x000000600000-0x000003600000 : "firmware"
[    2.742601] 2 fit-fw partitions found on MTD device firmware
[    2.748319] 0x000000600000-0x0000008d0000 : "kernel"
[    2.757981] 0x0000008e0000-0x000003600000 : "rootfs"
[    2.763555] mtd: device 5 (rootfs) set to be root filesystem
[    2.769277] 0x000003600000-0x000006600000 : "firmware2"
[    2.779141] 0x000006600000-0x000006680000 : "zbootconfig"

在设备管理下可以看到mmc的块设备和mtd的块设备

oot@openwrt:~# cat /proc/partitions 
major minor  #blocks  name179        0    3817472 mmcblk0179        1       2048 mmcblk0p1179        2       1024 mmcblk0p2179        3      49152 mmcblk0p3179        4      49152 mmcblk0p4179        5        512 mmcblk0p5259        0       2031 mmcblk0p128179       24       4096 mmcblk0rpmb179       16       4096 mmcblk0boot1179        8       4096 mmcblk0boot031        0       2048 mtdblock031        1       2048 mtdblock131        2       2048 mtdblock231        3      49152 mtdblock331        4       2880 mtdblock431        5      46208 mtdblock531        6      49152 mtdblock6

mmc的操作命令在mmc-utils包中,支持很多命令,下面只介绍常用的几个命令

2.2、读取寄存器值

mmc有很多寄存器,所以有专门的寄存器查看命令

root@openwrt:~# mmc extcsd read /dev/mmcblk0
=============================================Extended CSD rev 1.8 (MMC 5.1)
=============================================Card Supported Command sets [S_CMD_SET: 0x01]
HPI Features [HPI_FEATURE: 0x01]: implementation based on CMD13
Background operations support [BKOPS_SUPPORT: 0x01]
Max Packet Read Cmd [MAX_PACKED_READS: 0x3f]
Max Packet Write Cmd [MAX_PACKED_WRITES: 0x3f]
Data TAG support [DATA_TAG_SUPPORT: 0x01]
Data TAG Unit Size [TAG_UNIT_SIZE: 0x00]
Tag Resources Size [TAG_RES_SIZE: 0x00]
Context Management Capabilities [CONTEXT_CAPABILITIES: 0x78]
Large Unit Size [LARGE_UNIT_SIZE_M1: 0x01]
Extended partition attribute support [EXT_SUPPORT: 0x03]
Generic CMD6 Timer [GENERIC_CMD6_TIME: 0x05]
Power off notification [POWER_OFF_LONG_TIME: 0x64]
Cache Size [CACHE_SIZE] is 1024 KiB
Background operations status [BKOPS_STATUS: 0x00]
1st Initialisation Time after programmed sector [INI_TIMEOUT_AP: 0x0a]
Power class for 52MHz, DDR at 3.6V [PWR_CL_DDR_52_360: 0x00]
Power class for 52MHz, DDR at 1.95V [PWR_CL_DDR_52_195: 0x00]
Power class for 200MHz at 3.6V [PWR_CL_200_360: 0x00]
Power class for 200MHz, at 1.95V [PWR_CL_200_195: 0x00]
Minimum Performance for 8bit at 52MHz in DDR mode:[MIN_PERF_DDR_W_8_52: 0x00][MIN_PERF_DDR_R_8_52: 0x00]
TRIM Multiplier [TRIM_MULT: 0x02]
Secure Feature support [SEC_FEATURE_SUPPORT: 0x55]
Boot Information [BOOT_INFO: 0x07]Device supports alternative boot methodDevice supports dual data rate during bootDevice supports high speed timing during boot
Boot partition size [BOOT_SIZE_MULTI: 0x20]
...

比如我们最常用的PARTITION_CONFIG值

root@Openwrt:/# mmc extcsd read /dev/mmcblk0 | grep PARTITION_CONFIG
Boot configuration bytes [PARTITION_CONFIG: 0x48]
2.3、修改启动使能位

如下介绍:

mmc bootpart enable <boot_partition> <send_ack> <device>Enable the boot partition for the <device>.Disable the boot partition for the <device> if <boot_partition> is set to 0.To receive acknowledgment of boot from the card set <send_ack>to 1, else set it to 0

该接口就可以设置前面提到的BOOT_PARTITION_ENABLE的值,设置启动分区。

方法1:使能boot1,将BOOT_PARTITION_ENABLE设置为1,设置完再读出寄存器PARTITION_CONFIG的值看是否改变。

root@Openwrt:/# mmc bootpart enable 1 1 /dev/mmcblk0
root@Openwrt:/# mmc extcsd read /dev/mmcblk0 | grep PARTITION_CONFIG
Boot configuration bytes [PARTITION_CONFIG: 0x48]

方法2:使能UDA,将BOOT_PARTITION_ENABLE设置为7,设置完再读出寄存器PARTITION_CONFIG的值看是否改变。

root@Openwrt:/# mmc bootpart enable 7 1 /dev/mmcblk0
root@Openwrt:/# mmc extcsd read /dev/mmcblk0 | grep PARTITION_CONFIG
Boot configuration bytes [PARTITION_CONFIG: 0x78]
2.4、允许写入Boot分区

正常情况下,我们没办法往boot1和boot2分区写内容,有写保护;所以当我们要烧录preloader的时候就需要去掉写保护。

echo 0 > /sys/block/mmcblk0boot0/force_ro #将boot1的写保护去掉
dd if=mtk-bpi-r64-preloader-emmc.bin of=/dev/mmcblk0boot0
mmc bootpart enable 1 1   /dev/mmcblk0

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

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

相关文章

epoll模型下的简易版code

epoll模型下的简易版code c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/epoll.h> #include <fcntl.h>#define MAX_EVENTS 10 #define NUM_DESCRIPTORS 5 // 模拟多个文件描述符// …

【代码随想录训练营】【Day 38】【贪心-5】| Leetcode 435, 763, 56

【代码随想录训练营】【Day 38】【贪心-5】| Leetcode 435, 763, 56 需强化知识点 重叠区间系列 题&#xff0c; 763&#xff0c; 435 题目 435. 无重叠区间 左起点排序&#xff0c;记录重叠区间个数&#xff0c;总数相减即为结果&#xff0c;过程中维护右边界注意&#x…

工具类解决事务和过滤器解决事务

事务的四大特性ACID 原子性&#xff1a;强调事务的不可分割.多条语句要么都成功&#xff0c;要么都失败。 一致性&#xff1a;强调的是事务的执行的前后&#xff0c;数据要保持一致 隔离性&#xff1a;并发访问数据库时,一个事务的执行不应该受到其他事务的干扰. 持久性&#…

测试:ollama加载羊驼版本llama-3中文大模型

找了一个晚上各种模型&#xff0c;像极了当初找各种操作系统的镜像&#xff0c;雨林木风&#xff0c;深蓝、老毛桃…… 主要是官方的默认7B版本回答好多英文&#xff0c;而且回复的很慢&#xff0c;所以我是在ollama上搜索"chinese"找到了这个羊驼版本的&#xff0c…

使用javacv对摄像头视频转码并实现播放

要实现Java接受RTSP流解码&#xff0c;并推送给前端实现播放实时流&#xff0c;可以使用一些流媒体处理库&#xff0c;比如JavaCV或者FFmpeg等。以下是一个简单的示例代码&#xff1a; 1.控制层方面的 根据视频rtsp流链接打开转换&#xff0c;通过响应写出流到前台使用flvjs播…

go语言初学04

Go 语言近年来发展迅速&#xff0c;并且出现了许多优秀的开发框架和组件来支持各种不同的开发需求。以下是一些常用的 Go 语言开发框架和组件&#xff1a; Web 框架 Gin&#xff1a; URL: Gin简单、高效、易用&#xff0c;适合构建高性能的 Web 应用。 Echo&#xff1a; URL: …

crossover软件是干什么的 crossover软件安装使用教程 crossover软件如何使用

CrossOver 以其出色的跨平台兼容性&#xff0c;让用户在Mac设备上轻松运行各种Windows软件&#xff0c;无需复杂的设置或额外的配置&#xff0c;支持多种语言&#xff0c;满足不同国家和地区用户的需求。 CrossOver 软件是干嘛的 使用CrossOver 不必购买Windows 授权&#xf…

Winform ListView 嵌入组合框、布尔、图片等复杂控件

一、Winform ListView 显示复杂控件示例 以下展示了两种实现思路方案。最后修改日期 2024-05 surfsky 1.1 方案一&#xff1a;ListView 结合组合框进行模拟编辑 基本思路 在界面上放置一个lisview和一个combobox&#xff0c;combobox平时是隐藏的。点击listview&#xff0c…

ArrayList源码讲解

ArrayList 底层采用的是数组队列&#xff0c;相当于动态数组。 ArrayList内部使用一个可重新分配的Object数组来存储元素&#xff0c;这个数组会随着元素的添加自动增长以容纳更多的元素&#xff0c;这就是所谓的“动态数组”。 1.实现了RandomAccess接口&#xff0c;可以随机…

rust嵌入式开发之总结

我们用rust开发的新版产品刚刚交付&#xff0c;已经在海上安装测试完毕并顺利投产。终于松了口气&#xff0c;同时也有时间和精力来做个全面的总结了。 这个产品&#xff0c;目前差不多有三版&#xff1a; 第一个版本是用crt-thread写的&#xff0c;投产后出了一个内存泄露的…

521源码-源码论坛-宝塔面板操作日志是存放在哪里的? 如何删除部分日志记录

我们帮别人搭建或者登录了&#xff08;不是自己权属的宝塔面板&#xff09;&#xff0c;会留下登录及操作的日志&#xff0c;我们不想留下这些操作日志&#xff0c;可以通过下面的方法处理掉&#xff0c;以达到无痕迹访问操作的目的&#xff1a; 如图所示的面板操作日志&#…

Python-3.12.0文档解读-内置函数sum()详细说明+记忆策略+常用场景+巧妙用法+综合技巧

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 详细说明 sum(iterable, /, start0) 参数&#xff1a; 返回值&#xff1a; 注意事…

骑砍2霸主MOD开发(10)-游戏大地图(MapScene)制作

一.MapScene中初始化NavMeshFaceID与TerrainType public TerrainType GetFaceTerrainType(PathFaceRecord navMeshFace){switch (navMeshFace.FaceGroupIndex){case 1:return TerrainType.Plain;case 2:return TerrainType.Desert;case 3:return TerrainType.Snow;case 4:retur…

算法优化:空间与时间复杂度的权衡

引言 在软件开发中&#xff0c;算法的性能至关重要。算法的性能通常通过其时间复杂度和空间复杂度来衡量。时间复杂度指的是算法执行时间与输入规模的关系&#xff0c;而空间复杂度则关注算法执行过程中所占用的存储空间。本文将探讨如何权衡这两者&#xff0c;以实现算法的最…

排序方法大汇总

以下所有排序方法均以排升序为例 一.插入排序 1.直接插入排序 1>方法介绍&#xff1a;假定前n个数据有序&#xff0c;将第n1个数据依次与前n个数据相比&#xff0c;若比第i个数据小且比第i-1个数据大则插入两者之间 2>时间复杂度&#xff1a;O(N^2) 空间复杂度&#…

【JS】对象转变成数组

1、Object.keys() 方法&#xff1a; 将对象的键转换为数组 const a { name: aa,age: 18 }; const arr Object.keys(a); console.log(arr); // 输出 [name, age] 2、Object.values() 方法&#xff1a; 将对象的值转换为数组 const a { name: aa,age: 18 }; const arr Obj…

BUUCTF中的密码题目解密

BUUCTF 1.MD5 题目名称就是MD5&#xff0c;这个题目肯定和md5密码有关&#xff0c;下载题目&#xff0c;打开后发现这确实是一个md5加密的密文 Md5在线解密网站&#xff1a;md5在线解密破解,md5解密加密 经过MD5在线解密网站解密后&#xff0c;获取到flag为&#xff1a;flag{…

域名主机服务器配置失败的原因和解决方法

域名主机服务器配置失败的原因可能涉及多个方面&#xff0c;包括域名设置、DNS配置、服务器设置、网络问题等。以下是一些常见的原因和相应的解决方案&#xff1a; 1. DNS配置错误 原因&#xff1a; 域名解析错误&#xff1a;域名没有正确指向服务器的IP地址。 DNS记录未更新&a…

网络编程TCP

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f649; 内容推荐:Java网络编程(下)&#x1f649; &#x1f439;今日诗词: 壮士当唱大风哥, 宵小之徒能几何&#xff1f;&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微…

CentOS7单用户模式,救援模式操作记录

CentOS7单用户模式&#xff0c;救援模式操作记录 1. 单用户模式 单用户模式进入不需要密码&#xff0c;无网络连接&#xff0c;拥有root权限&#xff0c;禁止远程登陆。一般用于用于系统维护&#xff0c;例如忘记root密码后可以通过进入单用户模式进行重置。 开机启动&#…