Compare commits

...

4 Commits

Author SHA1 Message Date
dichgrem
1164d77a15 add:linux_0 2025-11-17 18:51:43 +08:00
dichgrem
954182c59b update:stm32 2025-11-17 16:30:44 +08:00
dichgrem
1c22b82f58 update:stm32 2025-11-15 19:33:11 +08:00
dichgrem
62217074f2 update:py 2025-11-13 14:37:35 +08:00
34 changed files with 1525 additions and 157 deletions

379
content/linux-0-start.md Normal file
View File

@@ -0,0 +1,379 @@
+++
title = "Linux-优雅过渡"
date = 2023-06-20
[taxonomies]
tags = ["Linux"]
+++
前言 本文面向刚刚从Windows转向Linux的一般使用者和想在Linux上进行开发的开发者主要说明其系统特点和使用须知。
<!-- more -->
## 0.启程
### 内核/发行版
Linux 是一种开源的类 UNIX 操作系统内核,广泛应用于各种设备,包括个人计算机、服务器、手机、嵌入式系统等。它由芬兰的 Linus Torvalds 于1991年开始开发是一个自由、免费的操作系统。与 Windows 和 macOS 等操作系统不同Linux 的源代码对所有人开放任何人都可以查看、修改和重新分发。我们常常说的Linux实际上是指各种发行版比如UbuntuArch LinuxDebian等等。
> Liunx可以用来玩游戏吗
实际上著名的 Steam Deck 的系统就是基于Arch linux 的。对于个人使用而言现在有不少原生支持linux 的游戏也可以使用Wine来运行Windows下的游戏。
### Linux的主要构成
Linux操作系统主要由以下几个部分组成
1. **内核**操作系统的核心负责管理系统资源。如Zen内核LTS内核等。
2. **Shell**命令行界面用户通过它与系统交互如Bash,Zsh等。
3. **图形用户界面GUI**提供图形化操作界面如GNOME、KDE、XFCE等。
4. **文件系统**如ext4、Btrfs等用于组织和管理磁盘上的文件。
5. **系统库**:为应用程序提供运行时支持。
6. **应用程序**用户可以直接使用的软件如文本编辑器、网页浏览器等。其中也有著名的GNU工具如Vim,GCC等。
### 选择Linux发行版
从上文可以发现选择Linux发行版实际上是在选择 **内核/包管理器/图形界面** 等组件的排列组合。其中最主要的因素是包管理器。
Linux有许多不同的发行版但大致可以分为几个系
**Debian系**
- DebianDebian以稳定性安全性和轻量级著称适合用于服务器和桌面环境。我们常说的Ubuntu就是基于Debian的发行版注重用户友好性和易用性。它提供了多种桌面环境选择以及许多现成的软件包。
- APTAdvanced Package Tool是Debian系发行版的主要包管理器。它使用命令行工具如apt-get、aptitude等来管理软件包。
**Red Hat系**
- Red Hat Enterprise LinuxRHELRHEL是一款商业发行版专注于企业级应用和支持。它提供了长期支持和专业技术支持服务适用于企业级服务器和工作站。
- CentOSCentOS是基于RHEL源代码编译而成的免费发行版与RHEL兼容并提供类似的功能和性能。它也提供了长期支持版本和稳定性较高的特点。
- FedoraFedora是由Red Hat支持的社区驱动的发行版注重提供最新的软件特性和技术。它适用于开发者和技术爱好者提供了稳定的发布周期和丰富的软件包。
- YUMYellowdog Updater, Modified是Red Hat系发行版的主要包管理器。最近的版本也开始采用DNFDandified YUM
**Arch系**
- Arch LinuxArch Linux是一个简洁、轻量级且灵活的发行版注重简洁性和滚动更新。它采用“滚动发布”的方式用户可以通过自定义安装来构建自己的系统适合有一定Linux经验的用户。
- PacmanPackage Manager是Arch Linux的主要包管理器。它使用简洁的命令来管理软件包如pacman -S安装软件包、pacman -Syu更新系统等。
**Gentoo系**
- GentooGentoo是一个源码驱动的发行版用户可以通过源代码自定义编译软件包以满足自己的需求。它注重性能和灵活性适合高级用户和技术爱好者。
- Portage是Gentoo的包管理器它是一个源代码驱动的包管理器允许用户从源代码构建和安装软件包。
除了以上列举的包管理器外还有其他一些较为特殊的包管理器如Slackware系的pkgtool、SUSE系的zypper等。
对于个人使用而言我个人建议新手使用Ubuntu,有比较易用的界面和完善的资料参考如果你是一个系统极客可以使用Arch linux 或者 NixOS。
## 1.初探FHS
李华是一个从WindowsXP时代一直使用到Win11的微软“老资历”用户这一天他下定决心要学会使用Linux于是他按照网上CSDN的教程在VMware中安装了大名鼎鼎的Ubuntu系统但很快他发现为什么系统里面``没有C盘和D盘``,只有一个神秘的``/``和一堆奇怪的英文?
在 Windows 的世界里,存储设备是用字母区分的,比如``C: D: E:``等等。但Linux 不给磁盘分字母,它采用的是一种叫做 ``FHSFilesystem Hierarchy Standard文件系统层次结构标准`` 的方式来组织系统。在 FHS 的世界里,整个系统就像一棵树:
- 树根是 /(根目录)
- 所有磁盘、分区、U盘、设备都会被“挂载mount”到这棵树的某个枝丫上
因此对于Linux而言文件系统是这样的
```shell
/ — 根
/home — 用户家目录
/root — 超级用户的家
/bin — 基础命令/二进制文件
/sbin — 管理命令
/usr — 大多数程序和资源
/lib — 库文件
/etc — 配置文件
/var — 日志、缓存、变化的数据
/tmp — 临时文件
/dev — 设备文件
/media — 自动挂载U盘
/mnt — 手动挂载点
/opt — 第三方软件
/boot — 系统启动文件
/proc — 虚拟进程信息
/sys — 虚拟硬件信息
/run — 系统运行状态
```
其中Home目录类似Windows上的``C:\Users\你的名字``,里面有``桌面/文档/下载/图片/音乐/视频/``,是不是非常眼熟?
可以看出Linux下是不用专门分出系统盘和数据盘的某种意义上解决了Windows的C盘空间不足红色爆满的问题。
> 小知识为什么Windows上是“\”而Linux是“/”? Unix 在1970年代就使用“/”,诞生于 1980 年代的 MS-DOS 本来也是用“/”的!但后来微软加入了命令行参数(如 /help和路径冲突了。为了区分选项和路径微软紧急决定“/” 用来当选项前缀至今仍如此dir /a文件路径改用“\”,于是 Windows 专门和全世界不一样。
> 并非所有Linux发行版都遵守FHS比如Nixos.
理解了FHS下一步就是要如何安装软件呢
## 2.包管理器与ELF
在windows中当我们想要安装某个软件的时候第一时间就是去寻找``EXE安装包``,而后点击安装-确定软件就出现在桌面了但李华很快发现他将下载的EXE文件放在Ubuntu的桌面并点击显示无法运行
这是因为Linux下不使用Windows的PE格式而是用ELF格式这并不是说李华得手动一个个下载ELF并点击运行实际上Linux上使用的是名为``包管理器``的方法。
在Ubuntu的界面中李华看到了一个名为``终端``的应用,输入``apt install neofetch``,就安装成功...不,暂时还没有成功,再次输入``sudo apt install neofetch``,就成功安装了neofetch这个软件随后我们输入``neofetch``,可以看到系统的一些信息:
```shell
neofetch
.-/+oossssoo+/-. dich@uos
`:+ssssssssssssssssss+:` --------
-+ssssssssssssssssssyyssss+- OS: Ubuntu 24.04.3 LTS x86_64
.ossssssssssssssssssdMMMNysssso. Host: KVM/QEMU (Standard PC (Q35 + ICH9, 2009) pc-q35-10.0)
/ssssssssssshdmmNNmmyNMMMMhssssss/ Kernel: 6.14.0-35-generic
+ssssssssshmydMMMMMMMNddddyssssssss+ Uptime: 2 mins
/sssssssshNMMMyhhyyyyhmNMMMNhssssssss/ Packages: 2522 (dpkg), 12 (snap)
.ssssssssdMMMNhsssssssssshNMMMdssssssss. Shell: zsh 5.9
+sssshhhyNMMNyssssssssssssyNMMMysssssss+ Resolution: 1280x800
ossyNMMMNyMMhsssssssssssssshmmmhssssssso Terminal: /dev/pts/0
ossyNMMMNyMMhsssssssssssssshmmmhssssssso GPU: 00:01.0 Red Hat, Inc. Virtio 1.0 GPU
+sssshhhyNMMNyssssssssssssyNMMMysssssss+ Memory: 1126MiB / 13976MiB
.ssssssssdMMMNhsssssssssshNMMMdssssssss.
/sssssssshNMMMyhhyyyyhdNMMMNhssssssss/
+sssssssssdmydMMMMMMMMddddyssssssss+
/ssssssssssshdmNNNNmyNMMMMhssssss/
.ossssssssssssssssssdMMMNysssso.
-+sssssssssssssssssyyyssss+-
`:+ssssssssssssssssss+:`
.-/+oossssoo+/-.
```
可见在Linux上安装软件其实比Windows的简单只需一行命令包管理器会从``源``下载软件包,并进行解压,``处理依赖项/动态链接/环境变量``等等这并非代表不安全Linux上大部分是开源软件关于开源软件日后我们再进行说明。那么如何知道安装需要的命令呢
我们可以从Ubuntu的软件源``https://packages.ubuntu.com/``上搜索软件包的名字,输入关键字(如 firefox、python、vlc它会列出
- 软件包的准确名字
- 所属版本(如 24.04、22.04
- 依赖关系
- 下载链接(如果你想手工装)
或者使用``apt search 包名``如果apt没有某个包还可以使用``AppImage / Flatpak / Snap``等等管理器来下载。
> 包管理器常用命令
| 功能 | aptUbuntu/Debian | paru/pacmanArch/Manjaro | 说明 |
| ------------ | ------------------------------------------- | -------------------------------- | ---------------------------- |
| 更新软件包索引 | `sudo apt update` | `sudo paru -Sy` | 先更新仓库信息 |
| 升级已安装的软件 | `sudo apt upgrade` | `sudo paru -Syu` | 升级所有已安装的软件(包含系统更新) |
| 安装软件包 | `sudo apt install <package>` | `sudo paru -S <package>` | 安装指定软件 |
| 移除软件包(保留配置) | `sudo apt remove <package>` | `sudo paru -R <package>` | 删除软件包,但保留配置文件 |
| 完全删除软件包(含配置) | `sudo apt purge <package>` | `sudo paru -Rns <package>` | 删除软件包及依赖、配置文件 |
| 搜索软件包 | `apt search <package>` | `paru -Ss <package>` | 查找仓库中的软件包 |
| 查看已安装软件 | `apt list --installed` | `paru -Q` | 列出系统已安装软件 |
| 查看软件信息 | `apt show <package>` | `paru -Si <package>` | 显示软件包详细信息 |
| 自动清理无用依赖 | `sudo apt autoremove` | `sudo paru -Rns $(pacman -Qdtq)` | 删除不再需要的依赖包 |
| 清理下载缓存 | `sudo apt clean` | `sudo paru -Sc` | 删除已下载的软件包缓存 |
| 升级单个软件包 | `sudo apt install --only-upgrade <package>` | `sudo paru -S <package>` | 仅升级指定软件 |
> AppImage可直接运行像“可携带版 EXE”;Flatpak沙盒化、现代、安全;Snap由 Ubuntu 官方主推;第三方仓库 PPA常见于开发版软件...
> 如果你使用其他Linux发行版也有对应的包管理器。比如Arch的Pacman/ParuFedora 的 dnfopenSUSE 的 zypperNixOS 的 nix...
> 实际上Windows上也是有包管理的比如 Windows 10/11 内置的 wingetWindows Package ManagerchocoChocolateyscoop...由于历史原因不为大部分人所熟悉.可以使用这个项目[UniGetUI](https://github.com/marticliment/UniGetUI)在Windows上方便的进行包管理.
## 3.权限系统/Sudo/Root
还记得前面我们使用的``sudo apt install xxx``吗为什么不加上sudo就无法运行呢这其实和Linux的权限系统有关.在Windows中有些无法直接运行的软件需要右键单击并选择``以管理员权限运行``.这表示某个操作会修改系统需要管理员Administrator的允许。Linux 也有类似的概念但名字不一样Linux 的管理员叫:``root``.
在Linux中普通用户如你的账户只能管理自己的文件、自己的程序
而root 用户能管理整个系统、安装软件、删除系统文件、修改配置;所以,日常使用的时候不是“管理员账号”,而是一个安全的普通用户。`sudo`super user do就是“请允许我**暂时**以 root 的身份执行这一条命令。”
为什么不用 root 账号直接登录呢?因为 root 太强大了:
- 可以删掉任何文件
- 可以覆盖系统配置
- 可以误操作把系统搞到无法启动
所以日常使用 root 类似于:“天天坐在一个自带核弹按钮的办公桌前”。这就是为什么 Linux 默认让你用普通用户,然后用 `sudo` 临时提升权限。
当李华学会使用 `sudo` 后,他又开始好奇:
> “为什么有些文件我能读,有些不能?
> 为什么有些文件能执行,有些却提示权限不够?”
Linux 的权限可以简单理解为``UGO+RWX``.
- UGO由用户User/ 用户组Group/ 其他人Others构成每个文件都有 Owner所有者和 Group用户组
- RWX权限分为 **r 读 / w 写 / x 执行**,并以类似 `-rwxr-x---` 的形式展示(文件类型 + Owner 权限 + Group 权限 + Others 权限)。
- **用户组Group** 是“权限相同的用户集合”,如:`sudo` 组能用 sudo`audio` 组能访问音频,`video` 组能用 GPU`docker` 组能管理容器。Linux 通过把用户加入不同组来决定他们能操作什么。
- **chmod** 用于修改权限:`chmod +x a.sh`(所有人加执行权限),`chmod u+x`(给 Owner 加执行权限),`chmod g-w`(去掉 Group 写权限),`chmod o-r`(禁掉 Others 读权限)。数字模式如 `755`、`644` 表示 r/w/x 的数字和(``r=4, w=2, x=1``):例如 `755` = Owner(rwx) / Group(r-x) / Others(r-x)。
比如创建一个新用户,可以使用``sudo adduser <用户名>``授予这个用户sudo权限可以使用``sudo usermod -aG sudo <用户名>``.
## 4.命令行
看到这里李华发觉Linux很多操作都是命令行式的在终端里面操作的但李华不知道有那些命令可以使用于是李华找了一些网站并尝试了一些常用的命令
- Linux命令查询[linux-command](https://wangchujiang.com/linux-command/hot.html)
- Linux常用命令表[Quick Reference](https://wangchujiang.com/reference/docs/linux-command.html)
```
date
Sun Nov 16 09:16:15 PM +08 2025
uname -a
Linux dos 6.17.7-cachyos #1-NixOS SMP PREEMPT_DYNAMIC Sun Nov 2 13:18:05 UTC 2025 x86_64 GNU/Linux
uptime
21:16:23 up 4:54, 0 users, load average: 0.79, 0.74, 0.70
ls
Data Desktop Documents Downloads Git go Picback Pictures
cd ./Downloads
~/Downloads
```
李华很好奇:这些 `ls`、`cd`、`uname`、`date` 等命令究竟来自哪里?它们是 Linux 内置的吗其实Linux 里的命令大致可以分为三类:**Shell 内建命令、外部二进制程序、BusyBox 提供的工具**。
- 一些命令是由 Shell 自己实现的,例如`cd` `echo` `pwd` `export` `alias` `history`这些命令不需要执行外部程序,由 Shell 本身的代码直接完成。可以用下面的方式判断命令是否是内建的:
```bash
type cd
# cd is a shell builtin
```
- 大多数常用命令是独立的可执行文件,例如 `/usr/bin/ls`、`/usr/bin/date`,它们通常来自一个叫 **coreutilsGNU Core Utilities** 的软件集合。可以用 `which` 查看一个命令的真实位置:
```bash
which ls
# /usr/bin/ls
```
这类命令本质上是ELF 可执行文件/被内核加载/在用户空间运行
- 在一些精简 Linux例如 Alpine、OpenWrt中命令不来自 GNU coreutils而来自一个叫 **BusyBox** 的单程序。BusyBox 只一个二进制文件,但内部包含了上百个命令,这种方式体积小,适用于嵌入式设备。
```
/bin/busybox ls
/bin/busybox cp
/bin/busybox tar
```
## 5.Shell/Terminal/TTY
随着李华在系统中的探索,李华发现常常遇到诸如``TerminalConsolebash,zsh,shell,tty``等概念,这些概念常常被混淆,似乎都和命令行相关,但又不太清楚它们之间是什么关系?
### 终端和控制台
终端,英文叫做 terminal ,通常简称为 term控制台英文叫做 console。
要明白这两者的关系,还得从最初的计算机说起。当时的计算机价格昂贵,一台计算机一般是由多个人同时使用的。在这种情况下一台计算机需要连接上许多套键盘和显示器来供多个人使用。在以前专门有这种可以连上一台电脑的设备,只有显示器和键盘,还有简单的处理电路,本身不具有处理计算机信息的能力,他是负责连接到一台正常的计算机上(通常是通过串口) ,然后登陆计算机,并对该计算机进行操作。当然,那时候的计算机操作系统都是多任务多用户的操作系统。这样一台``只有显示器和键盘能够通过串口连接到计算机的设备就叫做终端``。
而控制台又是什么回事呢?其概念来自于管风琴的控制台。顾名思义,控制台就是一个直接控制设备的台面(一个面板,上面有很多控制按钮)。 在计算机里,把那套``直接连接在电脑上的键盘和显示器就叫做控制台``。
终端是通过串口连接上的,不是计算机本身就有的设备,而控制台是计算机本身就有的设备,一个计算机只有一个控制台。计算机启动的时候,所有的信息都会显示到控制台上,而不会显示到终端上。也就是说,``控制台是计算机的基本设备,而终端是附加设备``。 当然,由于控制台也有终端一样的功能,控制台有时候也被模糊的统称为终端。
以上是控制台和终端的历史遗留区别。现在由于计算机硬件越来越便宜,终端和控制台的概念也慢慢演化了。``终端和控制台由硬件的概念,演化成了软件的概念``。
### 内核与外壳
内核( Kernel )和外壳( Shell )是 linux 的两个主要部分。Kernel 是操作系统的核心,系统的文件管理、进程管理、内存管理、设备管理这些功能,都是由 Kernel 提供的。
用户和操作系统内核交流需要一个工具,那么这个工具就是 Shell。
什么是 Shell在 Linux 中,最常见的 Shell 形式有命令行界面命令行界面和图形界面两种。并不是打开的那个终端窗口就是 Shell如Alacritty、Gnome-Terminal、xterm 、kitty等程序它们不是 Shell而它们里面``运行的 Bash、Zsh、fish 等命令行解释器程序,才是 Shell``。
那``Alacritty、Gnome-Terminal、xtermxterm``是什么?
它们是``终端模拟器``。
前面提到过,在远古时代,终端和控制台都是有实体的。控制台直接和计算机在一起,你可以通过控制台控制计算机。终端通过数据线和计算机连接,终端也提供一个键盘和一个屏幕,你可以通过键盘向计算机下达指令,然后通过屏幕观察输出。
但是现在的计算机组成和以前不一样了,一般一台电脑都是自带键盘和屏幕,很少再外接终端设备。
所以 Linux 提供了另外一个更高级的功能,那就是虚拟终端。那就是在一台电脑上,通过软件的模拟,好像有好几个终端连接在这台计算机上一样。
``现在说的终端,比如 linux 中的虚拟终端,都是软件的概念``。虚拟终端称之为 ttytty 是电传打字机电传打字机 Teletypewriter 的缩写在带显示屏的视频终端出现之前tty是最流行的终端设备。每一个 tty 都有一个编号,在/dev目录下有相应的设备文件。其中/dev/tty1到/dev/tty7可以通过 Ctrl+Alt+F1 到 Ctrl+Alt+F7 进行切换,也可以通过 chvt 命令进行切换,就好比是以前多人公用的计算机中的六个终端设备,这就是为什么这个叫“虚拟终端”的原因。
> 如果你现在使用linux可以使用Ctrl+Alt+F2切换到TTY界面
## 6.DE/WM/Wayland/X11
在 Windows 上,图形界面是系统密不可分的一部分。但李华发现,他安装的 Ubuntu 界面叫 GNOME而他同学安装的 Mint 界面却是 Cinnamon而且他听说还有 KDE、XFCE 等等,这让他感到困惑。
在 Linux 中,``图形界面是可以高度定制和替换的``。它主要由以下几个核心组件构成:
- 桌面环境Desktop Environment, DE
**桌面环境DE** 是一整套完整的、提供图形化操作体验的软件集合。它包括了:
```
窗口管理器Window Manager, WM负责绘制窗口边框、最大化/最小化按钮、控制窗口的移动和堆叠。
文件管理器:如 Nautilus (GNOME)、Dolphin (KDE)。
面板/任务栏:提供应用启动器、系统托盘、时钟等。
显示管理器Display Manager, DM负责登录界面如 GDM, LightDM
一系列配套应用:如文本编辑器、图片查看器等。
```
- 窗口管理器Window Manager, WM
**窗口管理器WM** 是 DE 的核心组件之一,但也可以独立运行。如果你不需要一个完整的桌面环境(如文件管理器、面板等),只想要管理窗口的显示和布局,就可以只安装一个 WM。
| 常见 DE | 常见 WM |
| -------------------------------- | ---------------------------------------------- |
| [KDE](https://docs.kde.org/) | [i3](https://i3wm.org/) |
| [Xfce](https://docs.xfce.org/) | [niri](https://github.com/YaLTeR/niri) |
| [Gnome](https://help.gnome.org/) | [qtile](https://github.com/qtile/qtile/) |
| — | [bspwm](https://github.com/baskerville/bspwm) |
| — | [Hyprland](https://github.com/hyprwm/Hyprland) |
| — | [awesomewm](https://awesomewm.org/) |
### 图形协议X11 与 Wayland
无论是 DE 还是 WM它们都需要一套机制来告诉应用程序“在哪里绘制一个按钮”、“如何响应鼠标点击”等。这就是 **图形显示协议**。
* **X Window SystemX11/Xorg** 历史悠久、功能强大但结构复杂的图形协议,已经使用了几十年。它的设计初衷是网络透明——理论上你可以在一台机器上运行程序,并在另一台机器上显示其图形界面。
* **Wayland** X11 的现代替代品。它设计更简洁、安全性更高、性能更好,尤其是在高分屏和混合刷新率显示器上。目前 GNOME 和 KDE 都在积极转向 Wayland。
> 对于新手,建议直接使用主流发行版的默认 DE如 Ubuntu 的 GNOME 或 CachyOS 的 KDE它们都提供了完整的用户体验。如果你是开发者或极客可以尝试平铺式 WM并关注 Wayland 的发展。
## 7.XDG
李华在折腾 GNOME 桌面时,发现很多配置文件夹都藏在 `~/.config` 下,而缓存文件在 `~/.cache`,下载的应用数据却在 `~/.local/share`。他发现这比 Windows 时代全部扔在 `C:\Users\username\AppData` 里规范多了!
这套规范就是 **XDG 基础目录规范XDG Base Directory Specification**,它是 Freedesktop.org一个致力于桌面环境互操作性的组织推广的一项标准。
XDG 规范的核心思想是将用户的文件按照用途分离,而不是像 Windows 那样把所有数据都塞进一个 `AppData` 文件夹。
| 环境变量/目录 | 默认路径(若未设置) | 用途 |
| :---------- | :----------------------------- | :----------------------------------------------------- |
| `$XDG_CONFIG_HOME` | `~/.config` | 存放**用户配置文件**Configuration files。 |
| `$XDG_CACHE_HOME` | `~/.cache` | 存放**非关键的缓存文件**Cache files可以随时删除。 |
| `$XDG_DATA_HOME` | `~/.local/share` | 存放**应用程序生成的用户数据**Data files如游戏存档、下载的图标等。 |
| `$XDG_RUNTIME_DIR` | 通常是 `/run/user/$(id -u)` | 存放**运行时文件**,生命周期与用户登录会话一致,重启或注销后消失。 |
通过遵守 XDG 规范,可以带来很多好处:
- **清理更方便:** 想清理缓存?直接删除 `$XDG_CACHE_HOME` 下的文件即可,不会误删配置。
- **备份更清晰:** 只需要备份 `$XDG_CONFIG_HOME` 就可以保留所有应用程序的配置。
- **兼容性更好:** 不同 Linux 发行版和桌面环境下的应用程序都能遵循一致的目录结构。
## 8.DEV面向开发者
对于想在 Linux 上进行开发的李华来说Linux 简直是为开发而生的系统。由于其开源、类 UNIX 的特性,它在软件开发领域拥有巨大的优势。
Linux 默认提供了强大的 GNU 工具链:
* **GCC/Clang** 编译 C/C++ 等语言。
* **Make/CMake** 构建自动化工具。
* **Git** 版本控制的行业标准Linux 对其支持极佳。
* **Bash/Zsh/Shell Scripting** 强大的命令行脚本能力,用于自动化运维。
* **Docker/Podman** 容器化技术在 Linux 上天然且高效。
在 Windows 上,安装 Python 或 Node.js 往往需要下载安装包并手动设置环境变量,管理多版本很麻烦。在 Linux 上,这变得非常优雅:
* **包管理器:** 可以直接通过 `apt` 或 `pacman` 安装主流编程语言及其依赖。
* **版本管理器:** 开发者通常会使用专门的工具来隔离和管理不同项目的语言版本,例如:
* **Python** `pyenv`
* **Node.js** `nvm`
* **Go** `gvm`
* **Ruby** `rvm` / `rbenv`
Linux 的内核天然支持 **Cgroups****Namespaces**,这是 **Docker****Kubernetes** 等容器化技术的基础。
* **Docker** 在 Linux 上运行 Docker 几乎没有性能损耗,是开发、测试和部署微服务的理想平台。
* **KVM/QEMU** 内置的高性能虚拟化技术,相比 Windows 的 Hyper-V 或 VMware性能更好更通用。
---
**Done.**

View File

@@ -6,29 +6,67 @@ date = 2025-07-20
tags = ["Linux"]
+++
前言 本文记录STM32命令行开发环境在Ubuntu上的部署用以替代Windows上的RT-Thread-studio。RT-Thread同样是开源
前言 本文记录STM32命令行开发环境在Ubuntu上的部署用以替代Windows上的RT-Thread-studio。RT-Thread-studio同样是开源
软件但目前似乎没有Nixos上的打包。
<!-- more -->
## 环境
在ubuntu24.04中安装这些包,包括连接工具,工具链和调试器等等。
```
- **Ubuntu**
以ubuntu24.04为例,安装这些包,包括连接工具,工具链和调试器等等。
```shell
sudo apt update
sudo apt install -y git python3 scons openocd stlink-tools gcc-arm-none-eabi gdb-multiarch
```
- **Nixos**
虽然没有RT-Thread-studio这个包但是可以用flake.nix很方便的搭建一个开发环境
```nix
{
description = "STM32 && RT-Thread development environment";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
outputs = { self, nixpkgs }:
let
supportedSystems = [ "x86_64-linux" "aarch64-linux" ];
forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f {
pkgs = import nixpkgs { inherit self system; };
});
in
{
devShells = forEachSupportedSystem ({ pkgs }: {
default = pkgs.mkShell {
packages = with pkgs; [
python312
scons
openocd
stlink
stlink-tool
gcc-arm-embedded
picocom
renode-bin
];
};
});
};
}
```
## 源码
使用Git拉取RT-Thread开源项目:
```
使用Git拉取项目源码
```shell
git clone https://github.com/RT-Thread/rt-thread.git
git clone https://github.com/RT-Thread-Studio/sdk-bsp-stm32f407-spark.git
```
## 连接
使用USB连接开发板和开发PC并使用lsusb查看是否连接成功
```
```shell
lsusb
Bus 001 Device 004: ID 0483:374b STMicroelectronics ST-LINK/V2.1
```
@@ -37,7 +75,7 @@ Bus 001 Device 004: ID 0483:374b STMicroelectronics ST-LINK/V2.1
添加成功后可以使用这个命令来检测:
```
```shell
st-info --probe
Found 1 stlink programmers
version: V2J35S26
@@ -51,7 +89,7 @@ Found 1 stlink programmers
## ENV工具
使用Git拉取RT-Thread配套的linux开发环境并添加Shell变量。我使用的是fish你也可以用其他的Shell命令有所不同。
```
```shell
git clone https://github.com/RT-Thread/env.git ~/env
set -x PATH $PATH ~/env
fish_add_path ~/env
@@ -63,7 +101,7 @@ type pkgs
由于该项目大量使用Python所以需要PKG包支持。首先我们修改这个文件的交叉工具链部分
```
```python
#修改 rtconfig.py
# cross_tool provides the cross compiler
@@ -97,7 +135,7 @@ elif CROSS_TOOL == 'llvm-arm':
```
随后可以使用PKG初始化并安装两个必要的包
```
```shell
pkgs --update
pip install kconfiglib
pip install scons
@@ -105,11 +143,11 @@ pip install scons
## 编译
在完成以上设置之后我们可以开始编译。STM32使用scons编译系统同样是menuconfig命令
```
```shell
scons --menuconfig
```
修改配置并保存退出后即可开始编译,$(nproc)代表使用全部CPU线程来编译
```
```shell
scons -j$(nproc)
```
@@ -119,23 +157,186 @@ scons -j$(nproc)
在烧入之前,我们可以备份一下原来的系统:
```
```shell
st-flash read firmware_backup.bin 0x08000000 0x100001
```
随后使用如下命令烧入系统:
```
```shell
st-flash write rtthread.bin 0x08000000
```
## 串口
除了USB之外我们还可以使用串口连接
```
```shell
sudo apt install picocom
picocom -b 115200 /dev/ttyACM0
version
```
可以使用``ctrl + A 然后 ctrl + x``退出。
## 使用Cmake
通过官方文档可以得知除了scons外还可以使用Cmake来编译.
首先找到编译器的路径并export
```shell
which arm-none-eabi-gcc
/nix/store/v9p5md3d4aaqwc9i9hlaxkl7nawd9vrc-gcc-arm-embedded-14.3.rel1/bin/arm-none-eabi-gcc
export RTT_EXEC_PATH=/nix/store/v9p5md3d4aaqwc9i9hlaxkl7nawd9vrc-gcc-arm-embedded-14.3.rel1/bin
export RTT_CC=gcc
```
随后使用指令``scons --target=cmake``
```shell
scons --target=cmake
scons: Reading SConscript files ...
Newlib version:4.5.0
Update setting files for CMakeLists.txt...
Done!
scons: done reading SConscript files.
scons: Building targets ...
scons: building associated VariantDir targets: build
CC build/applications/main.o
LINK rt-thread.elf
arm-none-eabi-objcopy -O binary rt-thread.elf rtthread.bin
arm-none-eabi-size rt-thread.elf
scons: done building targets.
```
可以看到生成CmakeLists.txt成功随后开始构建
```shell
cd ./build
cmake ..
CMake Warning (dev) at CMakeLists.txt:43:
Syntax Warning in cmake code at column 100
Argument not separated from preceding token by whitespace.
This warning is for project developers. Use -Wno-dev to suppress it.
-- The C compiler identification is GNU 14.3.1
-- The CXX compiler identification is GNU 14.3.1
-- The ASM compiler identification is GNU
-- Found assembler: /nix/store/v9p5md3d4aaqwc9i9hlaxkl7nawd9vrc-gcc-arm-embedded-14.3.rel1/bin/arm-none-eabi-gcc
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /nix/store/v9p5md3d4aaqwc9i9hlaxkl7nawd9vrc-gcc-arm-embedded-14.3.rel1/bin/arm-none-eabi-gcc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /nix/store/v9p5md3d4aaqwc9i9hlaxkl7nawd9vrc-gcc-arm-embedded-14.3.rel1/bin/arm-none-eabi-g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (0.4s)
-- Generating done (0.0s)
-- Build files have been written to: /home/dich/Git/sdk-bsp-stm32f407-spark/projects/02_basic_ir/build
```
使用``make``命令编译:
```shell
make
[ 1%] Building C object CMakeFiles/rtthread.elf.dir/applications/main.c.obj
[ 2%] Building C object CMakeFiles/rtthread.elf.dir/home/dich/Git/sdk-bsp-stm32f407-spark/rt-thread/components/libc/compilers/common/cctype.c.obj
[ 3%] Building C object CMakeFiles/rtthread.elf.dir/home/dich/Git/sdk-bsp-stm32f407-spark/rt-thread/components/libc/compilers/common/cstdio.c.obj
......
[ 97%] Building C object CMakeFiles/rtthread.elf.dir/home/dich/Git/sdk-bsp-stm32f407-spark/libraries/STM32F4xx_HAL/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c.obj
[ 98%] Building C object CMakeFiles/rtthread.elf.dir/home/dich/Git/sdk-bsp-stm32f407-spark/libraries/STM32F4xx_HAL/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c.obj
[100%] Linking C executable rtthread.elf
text data bss dec hex filename
98516 1468 8400 108384 1a760 rtthread.elf
[100%] Built target rtthread.elf
```
## 使用Renode
如果没有真实的开发版可以使用Renode来进行仿真模拟
```shell
# 启动renode
renode
# 创建机器
(monitor) mach create
# 加载STM32F407平台
(monitor) machine LoadPlatformDescription @platforms/boards/stm32f4_discovery.repl
# 加载你的固件
(monitor) sysbus LoadELF @/你的路径/rtthread.elf
# 打开串口窗口finsh会显示在这里
(monitor) showAnalyzer sysbus.usart1
# 启动仿真
(monitor) start
```
> Renode 常用命令大全
```bash
# 机器管理
mach add "名称" # 创建新机器(指定名称)
mach create # 创建新机器(自动命名)
mach set "名称" # 切换到指定机器
mach set 0 # 切换到编号0的机器
mach rem "名称" # 删除机器
mach clear # 清除当前选择
mach # 显示帮助信息
emulation # 查看仿真信息
# 仿真控制
start # 启动仿真
pause # 暂停仿真
quit # 退出Renode
# 帮助
help # 显示帮助
help 命令名 # 查看特定命令帮助
# 加载固件
sysbus LoadELF @/path/to/firmware.elf # 加载ELF文件
sysbus LoadBinary @/path/to/firmware.bin 0x8000000 # 加载BIN到指定地址
# 重置
sysbus Reset # 重置系统总线
machine Reset # 重置整个机器
# 读取内存
sysbus ReadByte 0x20000000 # 读1字节
sysbus ReadWord 0x20000000 # 读2字节
sysbus ReadDoubleWord 0x20000000 # 读4字节
# 写入内存
sysbus WriteByte 0x20000000 0xFF
sysbus WriteWord 0x20000000 0x1234
sysbus WriteDoubleWord 0x20000000 0x12345678
# 查看内存区域
sysbus FindSymbolAt 0x08000000 # 查找地址对应的符号
# 查看GPIO端口
sysbus.gpioPortA
# 设置GPIO状态
sysbus.gpioPortA.0 Set true # 设置PA0为高
sysbus.gpioPortA.0 Set false # 设置PA0为低
sysbus.gpioPortA.0 Toggle # 切换PA0状态
# 读取GPIO状态
sysbus.gpioPortA.0 State
# 使用GDB调试
(monitor) machine StartGdbServer 3333
# 另一个终端
arm-none-eabi-gdb firmware.elf
(gdb) target remote :3333
(gdb) load
(gdb) b main
(gdb) c
```
---
**Done.**

View File

@@ -184,77 +184,100 @@ pip install jupyter-notebook-translation
> 当然,你也可以使用其他编辑器/IDE如 Sublime Text 或者 JetBrains 系列的 PyCharm 。
## 使用UV替代Conda
> UV由 Astral 团队开发)是一个用 Rust 编写的高性能包管理器,提供了类似 Conda 的虚拟环境管理和依赖解析功能,并且在大多数场景下比 pip 和 Conda 快 10100 倍。它通过命令行工具如 uv venv创建/管理虚拟环境)和 uv pip安装/锁定/同步依赖)来覆盖传统的 conda create、conda install、conda env export 等操作,但本身并不管理底层的 C/C++ 库,因此对于诸如 GDAL、SciPy 等需要系统级二进制依赖的包,仍建议在 Conda/系统包管理器中预装相关库,然后用 UV 来管理 Python 包。
## 使用 UV 替代 Conda
**安装与激活**
```
> UV由 Astral 团队开发)是一个用 Rust 编写的高性能 Python 包管理器,提供类似 Conda 的虚拟环境管理和依赖解析功能,在大多数场景下比 pip 和 Conda 快 10100 倍。它通过命令行工具如 `uv venv`(创建/管理虚拟环境)和 `uv pip`(安装/锁定/同步依赖)覆盖传统的 Conda 流程,但本身不管理底层的 C/C++ 库,因此对于 GDAL、SciPy 等需要系统级二进制依赖的包,仍建议先通过系统包管理器或 Conda 安装,然后用 UV 管理 Python 包。
---
- 安装 UV
```bash
wget -qO- https://astral.sh/uv/install.sh | sh
```
- 在当前目录下创建 .venv使用系统默认 Python若不存在则自动下载
```
uv venv
```
- 指定环境名称或路径
```
uv venv myenv
```
- 指定 Python 版本(需系统已有或可下载)
```
uv venv --python 3.11
```
- 激活
```
- 创建与管理环境
```bash
# 创建虚拟环境,指定 Python 版本
uv venv --python 3.12
# 激活环境
source .venv/bin/activate
```
**安装包**
```bash
# 安装单个包
uv pip install requests
# 退出环境
deactivate
# 批量安装并自动锁定依赖
uv pip install fastapi uvicorn sqlalchemy
# 删除环境
rm -rf .venv
```
**生成与同步锁文件**
- 直接运行
```bash
# 从 requirements.in 生成统一依赖文件
uv pip compile docs/requirements.in \
--universal \
--output-file docs/requirements.txt
# 根据锁文件同步环境
uv pip sync docs/requirements.txt
uv run python
uv run jupyter lab
```
此流程替代 `conda env export` + `conda env update`,并保证跨平台一致性 ([GitHub][3])。
**查看与卸载**
- 注册 Jupyter 内核
```bash
uv pip list # 列出已安装包(类似 conda list
uv run python -m ipykernel install --user --name bank --display-name "Python (bank)"
```
---
- 安装依赖
```bash
uv add tensorflow
uv pip install requests fastapi uvicorn sqlalchemy
```
> 安装完成后UV 会自动更新 `uv.lock` 文件锁定依赖版本,保证环境可复现。
- 使用 TOML 配置管理依赖
创建一个 `pyproject.toml`
```toml
[tool.uv.dependencies]
fastapi = "*"
uvicorn = "*"
sqlalchemy = "*"
```
然后同步环境:
```bash
uv pip sync
```
这会根据 `pyproject.toml` + `uv.lock` 安装和锁定所有依赖。
- 查看与卸载包
```bash
uv pip list # 列出已安装包
uv pip uninstall numpy
```
**替代常见 Conda 工作流**
---
| Conda 操作 | UV 对应 |
| -------------------------------- | ---------------------------------------- |
| `conda create -n env python=3.x` | `uv venv --python 3.x` |
| `conda activate env` | `source .venv/bin/activate` 或 `activate` |
| `conda install pkg1 pkg2` | `uv pip install pkg1 pkg2` |
| `conda env export > env.yml` | `uv pip compile requirements.in` |
| `conda env update -f env.yml` | `uv pip sync requirements.txt` |
| `conda list` | `uv pip list` |
### 替代常见 Conda 工作流
**最佳实践**
| Conda 操作 | UV 对应 |
| -------------------------------- | ------------------------------------------------- |
| `conda create -n env python=3.x` | `uv venv --python 3.x` |
| `conda activate env` | `source .venv/bin/activate` 或 `uv venv activate` |
| `conda install pkg1 pkg2` | `uv pip install pkg1 pkg2` |
| `conda env export > env.yml` | 自动生成 `uv.lock` 或 `uv pip compile requirements.in` |
| `conda env update -f env.yml` | `uv pip sync`(根据 `uv.lock` 或 `pyproject.toml` 同步) |
| `conda list` | `uv pip list` |
1. **系统依赖**:用 Conda/Mamba 安装较难编译的 C 库(`conda install gdal`)。
2. **Python 包**:用 UV 管理所有纯 Python 依赖(`uv pip install pandas scikit-learn`)。
3. **统一锁定**:把 `uv pip compile` 生成的 `requirements.txt` 放入版本控制,确保团队环境一致。
## ipynb转markdown

View File

@@ -588,6 +588,16 @@
::
<a class="post-tag" href="https://blog.dich.bid/tags/linux/">#Linux</a></span>
</li>
<li class="post-list">
<a href="https://blog.dich.bid/linux-0-start/">
<span class="post-date">2023-06-20</span>
:: <span class="post-list-title">Linux-优雅过渡</span></a>
<span class="post-tags-inline">
::
<a class="post-tag" href="https://blog.dich.bid/tags/linux/">#Linux</a></span>
</li>
</ul>

View File

@@ -24,7 +24,7 @@
<link rel="alternate" type="text/html" href="https://blog.dich.bid/linux-2-stm32/"/>
<id>https://blog.dich.bid/linux-2-stm32/</id>
<summary type="html">&lt;p&gt;前言 本文记录STM32命令行开发环境在Ubuntu上的部署用以替代Windows上的RT-Thread-studio。RT-Thread同样是开源
<summary type="html">&lt;p&gt;前言 本文记录STM32命令行开发环境在Ubuntu上的部署用以替代Windows上的RT-Thread-studio。RT-Thread-studio同样是开源
软件但目前似乎没有Nixos上的打包。&lt;&#x2F;p&gt;</summary>
</entry>
@@ -1320,4 +1320,23 @@
<summary type="html">&lt;p&gt;前言 本文基于常见发行版systemd + NetworkManager + PipeWire&#x2F; PulseAudio &#x2F; ALSA,目标是把常见的桌面&#x2F;笔记本硬件Wi-Fi、蓝牙、亮度、音量通过命令行可复现、可理解地组织起来。&lt;&#x2F;p&gt;</summary>
</entry>
<entry xml:lang="en">
<title>Linux-优雅过渡</title>
<published>2023-06-20T00:00:00+00:00</published>
<updated>2023-06-20T00:00:00+00:00</updated>
<author>
<name>
Unknown
</name>
</author>
<link rel="alternate" type="text/html" href="https://blog.dich.bid/linux-0-start/"/>
<id>https://blog.dich.bid/linux-0-start/</id>
<summary type="html">&lt;p&gt;前言 本文面向刚刚从Windows转向Linux的一般使用者和想在Linux上进行开发的开发者主要说明其系统特点和使用须知。&lt;&#x2F;p&gt;</summary>
</entry>
</feed>

View File

@@ -125,7 +125,7 @@
<div class="post-content">
<p>前言 本文记录STM32命令行开发环境在Ubuntu上的部署用以替代Windows上的RT-Thread-studio。RT-Thread同样是开源
<p>前言 本文记录STM32命令行开发环境在Ubuntu上的部署用以替代Windows上的RT-Thread-studio。RT-Thread-studio同样是开源
软件但目前似乎没有Nixos上的打包。</p>
</div>
<div>

View File

@@ -0,0 +1,487 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Dich&#x27;s Blog</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="robots" content="noodp"/>
<!-- 字体预加载 - 减少布局偏移 CLS -->
<link rel="preload" href="https://blog.dich.bid/fonts/hack-regular.woff2?sha=3114f1256" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="https://blog.dich.bid/fonts/hack-bold.woff2?sha=3114f1256" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="https://blog.dich.bid/fonts/hack-italic.woff2?sha=3114f1256" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="https://blog.dich.bid/fonts/hack-bolditalic.woff2?sha=3114f1256" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="https://blog.dich.bid/style.css">
<link rel="stylesheet" href="https://blog.dich.bid/color/blue.css">
<link rel="stylesheet" href="https://blog.dich.bid/font-hack-subset.css">
<meta name="description" content="">
<meta property="og:description" content="">
<meta property="og:title" content="Dich's Blog">
<meta property="og:type" content="article">
<meta property="og:url" content="https://blog.dich.bid/linux-0-start/">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:description" content="">
<meta name="twitter:title" content="Dich's Blog">
<meta property="twitter:domain" content="blog.dich.bid">
<meta property="twitter:url" content="https://blog.dich.bid/linux-0-start/">
<link rel="alternate" type="application/atom+xml" title="Dich&#x27;s Blog Atom Feed" href="https://blog.dich.bid/atom.xml" />
<link rel="shortcut icon" type="image/webp" href="/dich.webp">
<!-- ✅ Added center alignment styles -->
<style>
.footer {
text-align: center;
padding: 1rem 0;
}
.footer__inner {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
.copyright {
text-align: center;
}
</style>
</head>
<body class="">
<div class="container">
<header class="header">
<div class="header__inner">
<div class="header__logo">
<a href="https://blog.dich.bid" style="text-decoration: none;">
<div class="logo">
Dich&#x27;s Blog
</div>
</a>
</div>
</div>
<nav class="menu">
<ul class="menu__inner">
<li class="active"><a href="https://blog.dich.bid">Blog</a></li>
<li><a href="https://blog.dich.bid/archive">Archive</a></li>
<li><a href="https://blog.dich.bid/weekly">Weekly</a></li>
<li><a href="https://blog.dich.bid/tags">Tags</a></li>
<li><a href="https://blog.dich.bid/search">Search</a></li>
<li><a href="https://blog.dich.bid/links">Links</a></li>
<li><a href="https://blog.dich.bid/atom.xml">Rss</a></li>
<li><a href="https://blog.dich.bid/about">About me</a></li>
<li><a href="https://github.com/Dichgrem" target="_blank" rel="noopener noreferrer">My github</a></li>
<li><a href="https://github.com/getzola/zola" target="_blank" rel="noopener noreferrer">Zola frame</a></li>
</ul>
</nav>
</header>
<div class="content">
<div class="post" data-pagefind-body>
<h1 class="post-title"><a href="https://blog.dich.bid/linux-0-start/">Linux-优雅过渡</a></h1>
<div class="post-meta-inline">
<span class="post-date">
2023-06-20
</span>
</div>
<span class="post-tags-inline">
:: tags:&nbsp;
<a class="post-tag" href="https://blog.dich.bid/tags/linux/">#Linux</a></span>
<div class="post-content">
<p>前言 本文面向刚刚从Windows转向Linux的一般使用者和想在Linux上进行开发的开发者主要说明其系统特点和使用须知。</p>
<span id="continue-reading"></span><h2 id="0-qi-cheng">0.启程</h2>
<h3 id="nei-he-fa-xing-ban">内核/发行版</h3>
<p>Linux 是一种开源的类 UNIX 操作系统内核,广泛应用于各种设备,包括个人计算机、服务器、手机、嵌入式系统等。它由芬兰的 Linus Torvalds 于1991年开始开发是一个自由、免费的操作系统。与 Windows 和 macOS 等操作系统不同Linux 的源代码对所有人开放任何人都可以查看、修改和重新分发。我们常常说的Linux实际上是指各种发行版比如UbuntuArch LinuxDebian等等。</p>
<blockquote>
<p>Liunx可以用来玩游戏吗
实际上著名的 Steam Deck 的系统就是基于Arch linux 的。对于个人使用而言现在有不少原生支持linux 的游戏也可以使用Wine来运行Windows下的游戏。</p>
</blockquote>
<h3 id="linuxde-zhu-yao-gou-cheng">Linux的主要构成</h3>
<p>Linux操作系统主要由以下几个部分组成</p>
<ol>
<li><strong>内核</strong>操作系统的核心负责管理系统资源。如Zen内核LTS内核等。</li>
<li><strong>Shell</strong>命令行界面用户通过它与系统交互如Bash,Zsh等。</li>
<li><strong>图形用户界面GUI</strong>提供图形化操作界面如GNOME、KDE、XFCE等。</li>
<li><strong>文件系统</strong>如ext4、Btrfs等用于组织和管理磁盘上的文件。</li>
<li><strong>系统库</strong>:为应用程序提供运行时支持。</li>
<li><strong>应用程序</strong>用户可以直接使用的软件如文本编辑器、网页浏览器等。其中也有著名的GNU工具如Vim,GCC等。</li>
</ol>
<h3 id="xuan-ze-linuxfa-xing-ban">选择Linux发行版</h3>
<p>从上文可以发现选择Linux发行版实际上是在选择 <strong>内核/包管理器/图形界面</strong> 等组件的排列组合。其中最主要的因素是包管理器。</p>
<p>Linux有许多不同的发行版但大致可以分为几个系</p>
<p><strong>Debian系</strong></p>
<ul>
<li>
<p>DebianDebian以稳定性安全性和轻量级著称适合用于服务器和桌面环境。我们常说的Ubuntu就是基于Debian的发行版注重用户友好性和易用性。它提供了多种桌面环境选择以及许多现成的软件包。</p>
</li>
<li>
<p>APTAdvanced Package Tool是Debian系发行版的主要包管理器。它使用命令行工具如apt-get、aptitude等来管理软件包。</p>
</li>
</ul>
<p><strong>Red Hat系</strong></p>
<ul>
<li>Red Hat Enterprise LinuxRHELRHEL是一款商业发行版专注于企业级应用和支持。它提供了长期支持和专业技术支持服务适用于企业级服务器和工作站。</li>
<li>CentOSCentOS是基于RHEL源代码编译而成的免费发行版与RHEL兼容并提供类似的功能和性能。它也提供了长期支持版本和稳定性较高的特点。</li>
<li>FedoraFedora是由Red Hat支持的社区驱动的发行版注重提供最新的软件特性和技术。它适用于开发者和技术爱好者提供了稳定的发布周期和丰富的软件包。</li>
<li>YUMYellowdog Updater, Modified是Red Hat系发行版的主要包管理器。最近的版本也开始采用DNFDandified YUM</li>
</ul>
<p><strong>Arch系</strong></p>
<ul>
<li>
<p>Arch LinuxArch Linux是一个简洁、轻量级且灵活的发行版注重简洁性和滚动更新。它采用“滚动发布”的方式用户可以通过自定义安装来构建自己的系统适合有一定Linux经验的用户。</p>
</li>
<li>
<p>PacmanPackage Manager是Arch Linux的主要包管理器。它使用简洁的命令来管理软件包如pacman -S安装软件包、pacman -Syu更新系统等。</p>
</li>
</ul>
<p><strong>Gentoo系</strong></p>
<ul>
<li>
<p>GentooGentoo是一个源码驱动的发行版用户可以通过源代码自定义编译软件包以满足自己的需求。它注重性能和灵活性适合高级用户和技术爱好者。</p>
</li>
<li>
<p>Portage是Gentoo的包管理器它是一个源代码驱动的包管理器允许用户从源代码构建和安装软件包。</p>
</li>
</ul>
<p>除了以上列举的包管理器外还有其他一些较为特殊的包管理器如Slackware系的pkgtool、SUSE系的zypper等。</p>
<p>对于个人使用而言我个人建议新手使用Ubuntu,有比较易用的界面和完善的资料参考如果你是一个系统极客可以使用Arch linux 或者 NixOS。</p>
<h2 id="1-chu-tan-fhs">1.初探FHS</h2>
<p>李华是一个从WindowsXP时代一直使用到Win11的微软“老资历”用户这一天他下定决心要学会使用Linux于是他按照网上CSDN的教程在VMware中安装了大名鼎鼎的Ubuntu系统但很快他发现为什么系统里面<code>没有C盘和D盘</code>,只有一个神秘的<code>/</code>和一堆奇怪的英文?</p>
<p>在 Windows 的世界里,存储设备是用字母区分的,比如<code>C: D: E:</code>等等。但Linux 不给磁盘分字母,它采用的是一种叫做 <code>FHSFilesystem Hierarchy Standard文件系统层次结构标准</code> 的方式来组织系统。在 FHS 的世界里,整个系统就像一棵树:</p>
<ul>
<li>树根是 /(根目录)</li>
<li>所有磁盘、分区、U盘、设备都会被“挂载mount”到这棵树的某个枝丫上</li>
</ul>
<p>因此对于Linux而言文件系统是这样的</p>
<pre data-lang="shell" style="background-color:#151515;color:#e8e8d3;" class="language-shell "><code class="language-shell" data-lang="shell"><span>/ — 根
</span><span>/home — 用户家目录
</span><span>/root — 超级用户的家
</span><span>/bin — 基础命令/二进制文件
</span><span>/sbin — 管理命令
</span><span>/usr — 大多数程序和资源
</span><span>/lib — 库文件
</span><span>/etc — 配置文件
</span><span>/var — 日志、缓存、变化的数据
</span><span>/tmp — 临时文件
</span><span>/dev — 设备文件
</span><span>/media — 自动挂载U盘
</span><span>/mnt — 手动挂载点
</span><span>/opt — 第三方软件
</span><span>/boot — 系统启动文件
</span><span>/proc — 虚拟进程信息
</span><span>/sys — 虚拟硬件信息
</span><span>/run — 系统运行状态
</span></code></pre>
<p>其中Home目录类似Windows上的<code>C:\Users\你的名字</code>,里面有<code>桌面/文档/下载/图片/音乐/视频/</code>,是不是非常眼熟?</p>
<p>可以看出Linux下是不用专门分出系统盘和数据盘的某种意义上解决了Windows的C盘空间不足红色爆满的问题。</p>
<blockquote>
<p>小知识为什么Windows上是“\”而Linux是“/”? Unix 在1970年代就使用“/”,诞生于 1980 年代的 MS-DOS 本来也是用“/”的!但后来微软加入了命令行参数(如 /help和路径冲突了。为了区分选项和路径微软紧急决定“/” 用来当选项前缀至今仍如此dir /a文件路径改用“\”,于是 Windows 专门和全世界不一样。</p>
</blockquote>
<blockquote>
<p>并非所有Linux发行版都遵守FHS比如Nixos.</p>
</blockquote>
<p>理解了FHS下一步就是要如何安装软件呢</p>
<h2 id="2-bao-guan-li-qi-yu-elf">2.包管理器与ELF</h2>
<p>在windows中当我们想要安装某个软件的时候第一时间就是去寻找<code>EXE安装包</code>,而后点击安装-确定软件就出现在桌面了但李华很快发现他将下载的EXE文件放在Ubuntu的桌面并点击显示无法运行</p>
<p>这是因为Linux下不使用Windows的PE格式而是用ELF格式这并不是说李华得手动一个个下载ELF并点击运行实际上Linux上使用的是名为<code>包管理器</code>的方法。</p>
<p>在Ubuntu的界面中李华看到了一个名为<code>终端</code>的应用,输入<code>apt install neofetch</code>,就安装成功...不,暂时还没有成功,再次输入<code>sudo apt install neofetch</code>,就成功安装了neofetch这个软件随后我们输入<code>neofetch</code>,可以看到系统的一些信息:</p>
<pre data-lang="shell" style="background-color:#151515;color:#e8e8d3;" class="language-shell "><code class="language-shell" data-lang="shell"><span> neofetch
</span><span> .-/+oossssoo+/-. dich@uos
</span><span> `:+ssssssssssssssssss+:` --------
</span><span> -+ssssssssssssssssssyyssss+- OS: Ubuntu 24.04.3 LTS x86_64
</span><span> .ossssssssssssssssssdMMMNysssso. Host: KVM/QEMU (Standard PC (Q35 + ICH9, 2009) pc-q35-10.0)
</span><span> /ssssssssssshdmmNNmmyNMMMMhssssss/ Kernel: 6.14.0-35-generic
</span><span> +ssssssssshmydMMMMMMMNddddyssssssss+ Uptime: 2 mins
</span><span> /sssssssshNMMMyhhyyyyhmNMMMNhssssssss/ Packages: 2522 (dpkg), 12 (snap)
</span><span>.ssssssssdMMMNhsssssssssshNMMMdssssssss. Shell: zsh 5.9
</span><span>+sssshhhyNMMNyssssssssssssyNMMMysssssss+ Resolution: 1280x800
</span><span>ossyNMMMNyMMhsssssssssssssshmmmhssssssso Terminal: /dev/pts/0
</span><span>ossyNMMMNyMMhsssssssssssssshmmmhssssssso GPU: 00:01.0 Red Hat, Inc. Virtio 1.0 GPU
</span><span>+sssshhhyNMMNyssssssssssssyNMMMysssssss+ Memory: 1126MiB / 13976MiB
</span><span>.ssssssssdMMMNhsssssssssshNMMMdssssssss.
</span><span> /sssssssshNMMMyhhyyyyhdNMMMNhssssssss/
</span><span> +sssssssssdmydMMMMMMMMddddyssssssss+
</span><span> /ssssssssssshdmNNNNmyNMMMMhssssss/
</span><span> .ossssssssssssssssssdMMMNysssso.
</span><span> -+sssssssssssssssssyyyssss+-
</span><span> `:+ssssssssssssssssss+:`
</span><span> .-/+oossssoo+/-.
</span></code></pre>
<p>可见在Linux上安装软件其实比Windows的简单只需一行命令包管理器会从<code></code>下载软件包,并进行解压,<code>处理依赖项/动态链接/环境变量</code>等等这并非代表不安全Linux上大部分是开源软件关于开源软件日后我们再进行说明。那么如何知道安装需要的命令呢</p>
<p>我们可以从Ubuntu的软件源<code>https://packages.ubuntu.com/</code>上搜索软件包的名字,输入关键字(如 firefox、python、vlc它会列出</p>
<ul>
<li>软件包的准确名字</li>
<li>所属版本(如 24.04、22.04</li>
<li>依赖关系</li>
<li>下载链接(如果你想手工装)</li>
</ul>
<p>或者使用<code>apt search 包名</code>如果apt没有某个包还可以使用<code>AppImage / Flatpak / Snap</code>等等管理器来下载。</p>
<blockquote>
<p>包管理器常用命令</p>
</blockquote>
<table><thead><tr><th>功能</th><th>aptUbuntu/Debian</th><th>paru/pacmanArch/Manjaro</th><th>说明</th></tr></thead><tbody>
<tr><td>更新软件包索引</td><td><code>sudo apt update</code></td><td><code>sudo paru -Sy</code></td><td>先更新仓库信息</td></tr>
<tr><td>升级已安装的软件</td><td><code>sudo apt upgrade</code></td><td><code>sudo paru -Syu</code></td><td>升级所有已安装的软件(包含系统更新)</td></tr>
<tr><td>安装软件包</td><td><code>sudo apt install &lt;package&gt;</code></td><td><code>sudo paru -S &lt;package&gt;</code></td><td>安装指定软件</td></tr>
<tr><td>移除软件包(保留配置)</td><td><code>sudo apt remove &lt;package&gt;</code></td><td><code>sudo paru -R &lt;package&gt;</code></td><td>删除软件包,但保留配置文件</td></tr>
<tr><td>完全删除软件包(含配置)</td><td><code>sudo apt purge &lt;package&gt;</code></td><td><code>sudo paru -Rns &lt;package&gt;</code></td><td>删除软件包及依赖、配置文件</td></tr>
<tr><td>搜索软件包</td><td><code>apt search &lt;package&gt;</code></td><td><code>paru -Ss &lt;package&gt;</code></td><td>查找仓库中的软件包</td></tr>
<tr><td>查看已安装软件</td><td><code>apt list --installed</code></td><td><code>paru -Q</code></td><td>列出系统已安装软件</td></tr>
<tr><td>查看软件信息</td><td><code>apt show &lt;package&gt;</code></td><td><code>paru -Si &lt;package&gt;</code></td><td>显示软件包详细信息</td></tr>
<tr><td>自动清理无用依赖</td><td><code>sudo apt autoremove</code></td><td><code>sudo paru -Rns $(pacman -Qdtq)</code></td><td>删除不再需要的依赖包</td></tr>
<tr><td>清理下载缓存</td><td><code>sudo apt clean</code></td><td><code>sudo paru -Sc</code></td><td>删除已下载的软件包缓存</td></tr>
<tr><td>升级单个软件包</td><td><code>sudo apt install --only-upgrade &lt;package&gt;</code></td><td><code>sudo paru -S &lt;package&gt;</code></td><td>仅升级指定软件</td></tr>
</tbody></table>
<blockquote>
<p>AppImage可直接运行像“可携带版 EXE”;Flatpak沙盒化、现代、安全;Snap由 Ubuntu 官方主推;第三方仓库 PPA常见于开发版软件...</p>
</blockquote>
<blockquote>
<p>如果你使用其他Linux发行版也有对应的包管理器。比如Arch的Pacman/ParuFedora 的 dnfopenSUSE 的 zypperNixOS 的 nix...</p>
</blockquote>
<blockquote>
<p>实际上Windows上也是有包管理的比如 Windows 10/11 内置的 wingetWindows Package ManagerchocoChocolateyscoop...由于历史原因不为大部分人所熟悉.可以使用这个项目<a href="https://github.com/marticliment/UniGetUI">UniGetUI</a>在Windows上方便的进行包管理.</p>
</blockquote>
<h2 id="3-quan-xian-xi-tong-sudo-root">3.权限系统/Sudo/Root</h2>
<p>还记得前面我们使用的<code>sudo apt install xxx</code>为什么不加上sudo就无法运行呢这其实和Linux的权限系统有关.在Windows中有些无法直接运行的软件需要右键单击并选择<code>以管理员权限运行</code>.这表示某个操作会修改系统需要管理员Administrator的允许。Linux 也有类似的概念但名字不一样Linux 的管理员叫:<code>root</code>.</p>
<p>在Linux中普通用户如你的账户只能管理自己的文件、自己的程序
而root 用户能管理整个系统、安装软件、删除系统文件、修改配置;所以,日常使用的时候不是“管理员账号”,而是一个安全的普通用户。<code>sudo</code>super user do就是“请允许我<strong>暂时</strong>以 root 的身份执行这一条命令。”</p>
<p>为什么不用 root 账号直接登录呢?因为 root 太强大了:</p>
<ul>
<li>可以删掉任何文件</li>
<li>可以覆盖系统配置</li>
<li>可以误操作把系统搞到无法启动</li>
</ul>
<p>所以日常使用 root 类似于:“天天坐在一个自带核弹按钮的办公桌前”。这就是为什么 Linux 默认让你用普通用户,然后用 <code>sudo</code> 临时提升权限。</p>
<p>当李华学会使用 <code>sudo</code> 后,他又开始好奇:</p>
<blockquote>
<p>“为什么有些文件我能读,有些不能?
为什么有些文件能执行,有些却提示权限不够?”</p>
</blockquote>
<p>Linux 的权限可以简单理解为<code>UGO+RWX</code>.</p>
<ul>
<li>
<p>UGO由用户User/ 用户组Group/ 其他人Others构成每个文件都有 Owner所有者和 Group用户组</p>
</li>
<li>
<p>RWX权限分为 <strong>r 读 / w 写 / x 执行</strong>,并以类似 <code>-rwxr-x---</code> 的形式展示(文件类型 + Owner 权限 + Group 权限 + Others 权限)。</p>
</li>
<li>
<p><strong>用户组Group</strong> 是“权限相同的用户集合”,如:<code>sudo</code> 组能用 sudo<code>audio</code> 组能访问音频,<code>video</code> 组能用 GPU<code>docker</code> 组能管理容器。Linux 通过把用户加入不同组来决定他们能操作什么。</p>
</li>
<li>
<p><strong>chmod</strong> 用于修改权限:<code>chmod +x a.sh</code>(所有人加执行权限),<code>chmod u+x</code>(给 Owner 加执行权限),<code>chmod g-w</code>(去掉 Group 写权限),<code>chmod o-r</code>(禁掉 Others 读权限)。数字模式如 <code>755</code><code>644</code> 表示 r/w/x 的数字和(<code>r=4, w=2, x=1</code>):例如 <code>755</code> = Owner(rwx) / Group(r-x) / Others(r-x)。</p>
</li>
</ul>
<p>比如创建一个新用户,可以使用<code>sudo adduser &lt;用户名&gt;</code>授予这个用户sudo权限可以使用<code>sudo usermod -aG sudo &lt;用户名&gt;</code>.</p>
<h2 id="4-ming-ling-xing">4.命令行</h2>
<p>看到这里李华发觉Linux很多操作都是命令行式的在终端里面操作的但李华不知道有那些命令可以使用于是李华找了一些网站并尝试了一些常用的命令</p>
<ul>
<li>Linux命令查询<a href="https://wangchujiang.com/linux-command/hot.html">linux-command</a></li>
<li>Linux常用命令表<a href="https://wangchujiang.com/reference/docs/linux-command.html">Quick Reference</a></li>
</ul>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span> date
</span><span>Sun Nov 16 09:16:15 PM +08 2025
</span><span> uname -a
</span><span>Linux dos 6.17.7-cachyos #1-NixOS SMP PREEMPT_DYNAMIC Sun Nov 2 13:18:05 UTC 2025 x86_64 GNU/Linux
</span><span> uptime
</span><span> 21:16:23 up 4:54, 0 users, load average: 0.79, 0.74, 0.70
</span><span> ls
</span><span>Data Desktop Documents Downloads Git go Picback Pictures
</span><span> cd ./Downloads
</span><span>~/Downloads
</span></code></pre>
<p>李华很好奇:这些 <code>ls</code><code>cd</code><code>uname</code><code>date</code> 等命令究竟来自哪里?它们是 Linux 内置的吗其实Linux 里的命令大致可以分为三类:<strong>Shell 内建命令、外部二进制程序、BusyBox 提供的工具</strong></p>
<ul>
<li>一些命令是由 Shell 自己实现的,例如<code>cd</code> <code>echo</code> <code>pwd</code> <code>export</code> <code>alias</code> <code>history</code>这些命令不需要执行外部程序,由 Shell 本身的代码直接完成。可以用下面的方式判断命令是否是内建的:</li>
</ul>
<pre data-lang="bash" style="background-color:#151515;color:#e8e8d3;" class="language-bash "><code class="language-bash" data-lang="bash"><span>type cd
</span><span style="color:#888888;"># cd is a shell builtin
</span></code></pre>
<ul>
<li>大多数常用命令是独立的可执行文件,例如 <code>/usr/bin/ls</code><code>/usr/bin/date</code>,它们通常来自一个叫 <strong>coreutilsGNU Core Utilities</strong> 的软件集合。可以用 <code>which</code> 查看一个命令的真实位置:</li>
</ul>
<pre data-lang="bash" style="background-color:#151515;color:#e8e8d3;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#ffb964;">which</span><span> ls
</span><span style="color:#888888;"># /usr/bin/ls
</span></code></pre>
<p>这类命令本质上是ELF 可执行文件/被内核加载/在用户空间运行</p>
<ul>
<li>在一些精简 Linux例如 Alpine、OpenWrt中命令不来自 GNU coreutils而来自一个叫 <strong>BusyBox</strong> 的单程序。BusyBox 只一个二进制文件,但内部包含了上百个命令,这种方式体积小,适用于嵌入式设备。</li>
</ul>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>/bin/busybox ls
</span><span>/bin/busybox cp
</span><span>/bin/busybox tar
</span></code></pre>
<h2 id="5-shell-terminal-tty">5.Shell/Terminal/TTY</h2>
<p>随着李华在系统中的探索,李华发现常常遇到诸如<code>TerminalConsolebash,zsh,shell,tty</code>等概念,这些概念常常被混淆,似乎都和命令行相关,但又不太清楚它们之间是什么关系?</p>
<h3 id="zhong-duan-he-kong-zhi-tai">终端和控制台</h3>
<p>终端,英文叫做 terminal ,通常简称为 term控制台英文叫做 console。</p>
<p>要明白这两者的关系,还得从最初的计算机说起。当时的计算机价格昂贵,一台计算机一般是由多个人同时使用的。在这种情况下一台计算机需要连接上许多套键盘和显示器来供多个人使用。在以前专门有这种可以连上一台电脑的设备,只有显示器和键盘,还有简单的处理电路,本身不具有处理计算机信息的能力,他是负责连接到一台正常的计算机上(通常是通过串口) ,然后登陆计算机,并对该计算机进行操作。当然,那时候的计算机操作系统都是多任务多用户的操作系统。这样一台<code>只有显示器和键盘能够通过串口连接到计算机的设备就叫做终端</code></p>
<p>而控制台又是什么回事呢?其概念来自于管风琴的控制台。顾名思义,控制台就是一个直接控制设备的台面(一个面板,上面有很多控制按钮)。 在计算机里,把那套<code>直接连接在电脑上的键盘和显示器就叫做控制台</code></p>
<p>终端是通过串口连接上的,不是计算机本身就有的设备,而控制台是计算机本身就有的设备,一个计算机只有一个控制台。计算机启动的时候,所有的信息都会显示到控制台上,而不会显示到终端上。也就是说,<code>控制台是计算机的基本设备,而终端是附加设备</code>。 当然,由于控制台也有终端一样的功能,控制台有时候也被模糊的统称为终端。</p>
<p>以上是控制台和终端的历史遗留区别。现在由于计算机硬件越来越便宜,终端和控制台的概念也慢慢演化了。<code>终端和控制台由硬件的概念,演化成了软件的概念</code></p>
<h3 id="nei-he-yu-wai-ke">内核与外壳</h3>
<p>内核( Kernel )和外壳( Shell )是 linux 的两个主要部分。Kernel 是操作系统的核心,系统的文件管理、进程管理、内存管理、设备管理这些功能,都是由 Kernel 提供的。</p>
<p>用户和操作系统内核交流需要一个工具,那么这个工具就是 Shell。</p>
<p>什么是 Shell在 Linux 中,最常见的 Shell 形式有命令行界面命令行界面和图形界面两种。并不是打开的那个终端窗口就是 Shell如Alacritty、Gnome-Terminal、xterm 、kitty等程序它们不是 Shell而它们里面<code>运行的 Bash、Zsh、fish 等命令行解释器程序,才是 Shell</code></p>
<p><code>Alacritty、Gnome-Terminal、xtermxterm</code>是什么?</p>
<p>它们是<code>终端模拟器</code></p>
<p>前面提到过,在远古时代,终端和控制台都是有实体的。控制台直接和计算机在一起,你可以通过控制台控制计算机。终端通过数据线和计算机连接,终端也提供一个键盘和一个屏幕,你可以通过键盘向计算机下达指令,然后通过屏幕观察输出。</p>
<p>但是现在的计算机组成和以前不一样了,一般一台电脑都是自带键盘和屏幕,很少再外接终端设备。</p>
<p>所以 Linux 提供了另外一个更高级的功能,那就是虚拟终端。那就是在一台电脑上,通过软件的模拟,好像有好几个终端连接在这台计算机上一样。</p>
<p><code>现在说的终端,比如 linux 中的虚拟终端,都是软件的概念</code>。虚拟终端称之为 ttytty 是电传打字机电传打字机 Teletypewriter 的缩写在带显示屏的视频终端出现之前tty是最流行的终端设备。每一个 tty 都有一个编号,在/dev目录下有相应的设备文件。其中/dev/tty1到/dev/tty7可以通过 Ctrl+Alt+F1 到 Ctrl+Alt+F7 进行切换,也可以通过 chvt 命令进行切换,就好比是以前多人公用的计算机中的六个终端设备,这就是为什么这个叫“虚拟终端”的原因。</p>
<blockquote>
<p>如果你现在使用linux可以使用Ctrl+Alt+F2切换到TTY界面</p>
</blockquote>
<h2 id="6-de-wm-wayland-x11">6.DE/WM/Wayland/X11</h2>
<p>在 Windows 上,图形界面是系统密不可分的一部分。但李华发现,他安装的 Ubuntu 界面叫 GNOME而他同学安装的 Mint 界面却是 Cinnamon而且他听说还有 KDE、XFCE 等等,这让他感到困惑。</p>
<p>在 Linux 中,<code>图形界面是可以高度定制和替换的</code>。它主要由以下几个核心组件构成:</p>
<ul>
<li>桌面环境Desktop Environment, DE</li>
</ul>
<p><strong>桌面环境DE</strong> 是一整套完整的、提供图形化操作体验的软件集合。它包括了:</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>窗口管理器Window Manager, WM负责绘制窗口边框、最大化/最小化按钮、控制窗口的移动和堆叠。
</span><span>文件管理器:如 Nautilus (GNOME)、Dolphin (KDE)。
</span><span>面板/任务栏:提供应用启动器、系统托盘、时钟等。
</span><span>显示管理器Display Manager, DM负责登录界面如 GDM, LightDM
</span><span>一系列配套应用:如文本编辑器、图片查看器等。
</span></code></pre>
<ul>
<li>窗口管理器Window Manager, WM</li>
</ul>
<p><strong>窗口管理器WM</strong> 是 DE 的核心组件之一,但也可以独立运行。如果你不需要一个完整的桌面环境(如文件管理器、面板等),只想要管理窗口的显示和布局,就可以只安装一个 WM。</p>
<table><thead><tr><th>常见 DE</th><th>常见 WM</th></tr></thead><tbody>
<tr><td><a href="https://docs.kde.org/">KDE</a></td><td><a href="https://i3wm.org/">i3</a></td></tr>
<tr><td><a href="https://docs.xfce.org/">Xfce</a></td><td><a href="https://github.com/YaLTeR/niri">niri</a></td></tr>
<tr><td><a href="https://help.gnome.org/">Gnome</a></td><td><a href="https://github.com/qtile/qtile/">qtile</a></td></tr>
<tr><td></td><td><a href="https://github.com/baskerville/bspwm">bspwm</a></td></tr>
<tr><td></td><td><a href="https://github.com/hyprwm/Hyprland">Hyprland</a></td></tr>
<tr><td></td><td><a href="https://awesomewm.org/">awesomewm</a></td></tr>
</tbody></table>
<h3 id="tu-xing-xie-yi-x11-yu-wayland">图形协议X11 与 Wayland</h3>
<p>无论是 DE 还是 WM它们都需要一套机制来告诉应用程序“在哪里绘制一个按钮”、“如何响应鼠标点击”等。这就是 <strong>图形显示协议</strong></p>
<ul>
<li><strong>X Window SystemX11/Xorg</strong> 历史悠久、功能强大但结构复杂的图形协议,已经使用了几十年。它的设计初衷是网络透明——理论上你可以在一台机器上运行程序,并在另一台机器上显示其图形界面。</li>
<li><strong>Wayland</strong> X11 的现代替代品。它设计更简洁、安全性更高、性能更好,尤其是在高分屏和混合刷新率显示器上。目前 GNOME 和 KDE 都在积极转向 Wayland。</li>
</ul>
<blockquote>
<p>对于新手,建议直接使用主流发行版的默认 DE如 Ubuntu 的 GNOME 或 CachyOS 的 KDE它们都提供了完整的用户体验。如果你是开发者或极客可以尝试平铺式 WM并关注 Wayland 的发展。</p>
</blockquote>
<h2 id="7-xdg">7.XDG</h2>
<p>李华在折腾 GNOME 桌面时,发现很多配置文件夹都藏在 <code>~/.config</code> 下,而缓存文件在 <code>~/.cache</code>,下载的应用数据却在 <code>~/.local/share</code>。他发现这比 Windows 时代全部扔在 <code>C:\Users\username\AppData</code> 里规范多了!</p>
<p>这套规范就是 <strong>XDG 基础目录规范XDG Base Directory Specification</strong>,它是 Freedesktop.org一个致力于桌面环境互操作性的组织推广的一项标准。</p>
<p>XDG 规范的核心思想是将用户的文件按照用途分离,而不是像 Windows 那样把所有数据都塞进一个 <code>AppData</code> 文件夹。</p>
<table><thead><tr><th style="text-align: left">环境变量/目录</th><th style="text-align: left">默认路径(若未设置)</th><th style="text-align: left">用途</th></tr></thead><tbody>
<tr><td style="text-align: left"><code>$XDG_CONFIG_HOME</code></td><td style="text-align: left"><code>~/.config</code></td><td style="text-align: left">存放<strong>用户配置文件</strong>Configuration files</td></tr>
<tr><td style="text-align: left"><code>$XDG_CACHE_HOME</code></td><td style="text-align: left"><code>~/.cache</code></td><td style="text-align: left">存放<strong>非关键的缓存文件</strong>Cache files可以随时删除。</td></tr>
<tr><td style="text-align: left"><code>$XDG_DATA_HOME</code></td><td style="text-align: left"><code>~/.local/share</code></td><td style="text-align: left">存放<strong>应用程序生成的用户数据</strong>Data files如游戏存档、下载的图标等。</td></tr>
<tr><td style="text-align: left"><code>$XDG_RUNTIME_DIR</code></td><td style="text-align: left">通常是 <code>/run/user/$(id -u)</code></td><td style="text-align: left">存放<strong>运行时文件</strong>,生命周期与用户登录会话一致,重启或注销后消失。</td></tr>
</tbody></table>
<p>通过遵守 XDG 规范,可以带来很多好处:</p>
<ul>
<li><strong>清理更方便:</strong> 想清理缓存?直接删除 <code>$XDG_CACHE_HOME</code> 下的文件即可,不会误删配置。</li>
<li><strong>备份更清晰:</strong> 只需要备份 <code>$XDG_CONFIG_HOME</code> 就可以保留所有应用程序的配置。</li>
<li><strong>兼容性更好:</strong> 不同 Linux 发行版和桌面环境下的应用程序都能遵循一致的目录结构。</li>
</ul>
<h2 id="8-dev-mian-xiang-kai-fa-zhe">8.DEV面向开发者</h2>
<p>对于想在 Linux 上进行开发的李华来说Linux 简直是为开发而生的系统。由于其开源、类 UNIX 的特性,它在软件开发领域拥有巨大的优势。</p>
<p>Linux 默认提供了强大的 GNU 工具链:</p>
<ul>
<li><strong>GCC/Clang</strong> 编译 C/C++ 等语言。</li>
<li><strong>Make/CMake</strong> 构建自动化工具。</li>
<li><strong>Git</strong> 版本控制的行业标准Linux 对其支持极佳。</li>
<li><strong>Bash/Zsh/Shell Scripting</strong> 强大的命令行脚本能力,用于自动化运维。</li>
<li><strong>Docker/Podman</strong> 容器化技术在 Linux 上天然且高效。</li>
</ul>
<p>在 Windows 上,安装 Python 或 Node.js 往往需要下载安装包并手动设置环境变量,管理多版本很麻烦。在 Linux 上,这变得非常优雅:</p>
<ul>
<li><strong>包管理器:</strong> 可以直接通过 <code>apt</code><code>pacman</code> 安装主流编程语言及其依赖。</li>
<li><strong>版本管理器:</strong> 开发者通常会使用专门的工具来隔离和管理不同项目的语言版本,例如:</li>
<li><strong>Python</strong> <code>pyenv</code></li>
<li><strong>Node.js</strong> <code>nvm</code></li>
<li><strong>Go</strong> <code>gvm</code></li>
<li><strong>Ruby</strong> <code>rvm</code> / <code>rbenv</code></li>
</ul>
<p>Linux 的内核天然支持 <strong>Cgroups</strong><strong>Namespaces</strong>,这是 <strong>Docker</strong><strong>Kubernetes</strong> 等容器化技术的基础。</p>
<ul>
<li><strong>Docker</strong> 在 Linux 上运行 Docker 几乎没有性能损耗,是开发、测试和部署微服务的理想平台。</li>
<li><strong>KVM/QEMU</strong> 内置的高性能虚拟化技术,相比 Windows 的 Hyper-V 或 VMware性能更好更通用。</li>
</ul>
<hr />
<p><strong>Done.</strong></p>
</div>
<div class="pagination">
<div class="pagination__title">
<span class="pagination__title-h">Thanks for reading! Read other posts?</span>
<hr />
</div>
<div class="pagination__buttons">
<span class="button next">
<a href="https://blog.dich.bid/linux-1-command/">
<span class="button__text">Linux-命令行操控</span>&nbsp;
<span class="button__icon"></span>
</a>
</span>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="footer__inner">
<div class="copyright">
<span>©
2025
Dichgrem</span>
<span class="copyright-theme">
<span class="copyright-theme-sep"> :: CC BY-SA 4.0 :: A friend comes from distant lands</span>
</a>
</span>
</div>
</div>
</footer>
</div>
</body>
</html>

View File

@@ -349,6 +349,13 @@
<hr />
</div>
<div class="pagination__buttons">
<span class="button previous">
<a href="https://blog.dich.bid/linux-0-start/">
<span class="button__icon"></span>&nbsp;
<span class="button__text">Linux-优雅过渡</span>
</a>
</span>
<span class="button next">
<a href="https://blog.dich.bid/awesome-vm-android/">

View File

@@ -122,25 +122,61 @@
<div class="post-content">
<p>前言 本文记录STM32命令行开发环境在Ubuntu上的部署用以替代Windows上的RT-Thread-studio。RT-Thread同样是开源
<p>前言 本文记录STM32命令行开发环境在Ubuntu上的部署用以替代Windows上的RT-Thread-studio。RT-Thread-studio同样是开源
软件但目前似乎没有Nixos上的打包。</p>
<span id="continue-reading"></span><h2 id="huan-jing">环境</h2>
<p>在ubuntu24.04中安装这些包,包括连接工具,工具链和调试器等等。</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>sudo apt update
<ul>
<li><strong>Ubuntu</strong></li>
</ul>
<p>以ubuntu24.04为例,安装这些包,包括连接工具,工具链和调试器等等。</p>
<pre data-lang="shell" style="background-color:#151515;color:#e8e8d3;" class="language-shell "><code class="language-shell" data-lang="shell"><span>sudo apt update
</span><span>sudo apt install -y git python3 scons openocd stlink-tools gcc-arm-none-eabi gdb-multiarch
</span></code></pre>
<ul>
<li><strong>Nixos</strong></li>
</ul>
<p>虽然没有RT-Thread-studio这个包但是可以用flake.nix很方便的搭建一个开发环境</p>
<pre data-lang="nix" style="background-color:#151515;color:#e8e8d3;" class="language-nix "><code class="language-nix" data-lang="nix"><span>{
</span><span> </span><span style="color:#ffb964;">description </span><span>= </span><span style="color:#99ad6a;">&quot;STM32 &amp;&amp; RT-Thread development environment&quot;</span><span>;
</span><span> </span><span style="color:#ffb964;">inputs</span><span>.</span><span style="color:#ffb964;">nixpkgs</span><span>.</span><span style="color:#ffb964;">url </span><span>= </span><span style="color:#99ad6a;">&quot;github:NixOS/nixpkgs/nixpkgs-unstable&quot;</span><span>;
</span><span> </span><span style="color:#ffb964;">outputs </span><span>= { </span><span style="color:#ffb964;">self</span><span>, </span><span style="color:#ffb964;">nixpkgs </span><span>}:
</span><span> let
</span><span> </span><span style="color:#ffb964;">supportedSystems </span><span>= [ </span><span style="color:#99ad6a;">&quot;x86_64-linux&quot; &quot;aarch64-linux&quot; </span><span>];
</span><span> </span><span style="color:#ffb964;">forEachSupportedSystem </span><span>= </span><span style="color:#ffb964;">f</span><span>: </span><span style="color:#ffb964;">nixpkgs</span><span>.</span><span style="color:#ffb964;">lib</span><span>.</span><span style="color:#ffb964;">genAttrs supportedSystems </span><span>(</span><span style="color:#ffb964;">system</span><span>: </span><span style="color:#ffb964;">f </span><span>{
</span><span> </span><span style="color:#ffb964;">pkgs </span><span>= import </span><span style="color:#ffb964;">nixpkgs </span><span>{ inherit </span><span style="color:#ffb964;">self system</span><span>; };
</span><span> });
</span><span> in
</span><span> {
</span><span> </span><span style="color:#ffb964;">devShells </span><span>= </span><span style="color:#ffb964;">forEachSupportedSystem </span><span>({ </span><span style="color:#ffb964;">pkgs </span><span>}: {
</span><span> </span><span style="color:#ffb964;">default </span><span>= </span><span style="color:#ffb964;">pkgs</span><span>.</span><span style="color:#ffb964;">mkShell </span><span>{
</span><span> </span><span style="color:#ffb964;">packages </span><span>= with </span><span style="color:#ffb964;">pkgs</span><span>; [
</span><span> </span><span style="color:#ffb964;">python312
</span><span> </span><span style="color:#ffb964;">scons
</span><span> </span><span style="color:#ffb964;">openocd
</span><span> </span><span style="color:#ffb964;">stlink
</span><span> </span><span style="color:#ffb964;">stlink-tool
</span><span> </span><span style="color:#ffb964;">gcc-arm-embedded
</span><span> </span><span style="color:#ffb964;">picocom
</span><span> </span><span style="color:#ffb964;">renode-bin
</span><span> ];
</span><span> };
</span><span> });
</span><span> };
</span><span>}
</span></code></pre>
<h2 id="yuan-ma">源码</h2>
<p>使用Git拉取RT-Thread开源项目:</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>git clone https://github.com/RT-Thread/rt-thread.git
<p>使用Git拉取项目源码</p>
<pre data-lang="shell" style="background-color:#151515;color:#e8e8d3;" class="language-shell "><code class="language-shell" data-lang="shell"><span>git clone https://github.com/RT-Thread/rt-thread.git
</span><span>git clone https://github.com/RT-Thread-Studio/sdk-bsp-stm32f407-spark.git
</span></code></pre>
<h2 id="lian-jie">连接</h2>
<p>使用USB连接开发板和开发PC并使用lsusb查看是否连接成功</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>lsusb
<pre data-lang="shell" style="background-color:#151515;color:#e8e8d3;" class="language-shell "><code class="language-shell" data-lang="shell"><span>lsusb
</span><span>Bus 001 Device 004: ID 0483:374b STMicroelectronics ST-LINK/V2.1
</span></code></pre>
<p>如果你和我一样使用 qemu 需要在libvirt中使用Add_hardware添加usb设备。</p>
<p>添加成功后可以使用这个命令来检测:</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span> st-info --probe
<pre data-lang="shell" style="background-color:#151515;color:#e8e8d3;" class="language-shell "><code class="language-shell" data-lang="shell"><span> st-info --probe
</span><span>Found 1 stlink programmers
</span><span> version: V2J35S26
</span><span> serial: 0671FF373654393143244522
@@ -151,7 +187,7 @@
</span></code></pre>
<h2 id="envgong-ju">ENV工具</h2>
<p>使用Git拉取RT-Thread配套的linux开发环境并添加Shell变量。我使用的是fish你也可以用其他的Shell命令有所不同。</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>git clone https://github.com/RT-Thread/env.git ~/env
<pre data-lang="shell" style="background-color:#151515;color:#e8e8d3;" class="language-shell "><code class="language-shell" data-lang="shell"><span>git clone https://github.com/RT-Thread/env.git ~/env
</span><span>set -x PATH $PATH ~/env
</span><span>fish_add_path ~/env
</span><span>echo $PATH
@@ -159,64 +195,211 @@
</span></code></pre>
<h2 id="pkggong-ju">PKG工具</h2>
<p>由于该项目大量使用Python所以需要PKG包支持。首先我们修改这个文件的交叉工具链部分</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>#修改 rtconfig.py
<pre data-lang="python" style="background-color:#151515;color:#e8e8d3;" class="language-python "><code class="language-python" data-lang="python"><span style="color:#888888;">#修改 rtconfig.py
</span><span>
</span><span># cross_tool provides the cross compiler
</span><span># EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR
</span><span>import os
</span><span style="color:#888888;"># cross_tool provides the cross compiler
</span><span style="color:#888888;"># EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR
</span><span style="color:#8fbfdc;">import </span><span>os
</span><span>
</span><span>if CROSS_TOOL == &#39;gcc&#39;:
</span><span> PLATFORM = &#39;gcc&#39;
</span><span> if os.name == &#39;nt&#39;:
</span><span> # Windows 平台
</span><span> EXEC_PATH = r&#39;C:\Users\XXYYZZ&#39;
</span><span> else:
</span><span> # Linux / macOS 平台
</span><span> EXEC_PATH = &#39;/usr/bin&#39;
</span><span style="color:#8fbfdc;">if </span><span style="color:#ffb964;">CROSS_TOOL </span><span>== </span><span style="color:#556633;">&#39;</span><span style="color:#99ad6a;">gcc</span><span style="color:#556633;">&#39;</span><span>:
</span><span> </span><span style="color:#ffb964;">PLATFORM </span><span>= </span><span style="color:#556633;">&#39;</span><span style="color:#99ad6a;">gcc</span><span style="color:#556633;">&#39;
</span><span> </span><span style="color:#8fbfdc;">if </span><span>os.name == </span><span style="color:#556633;">&#39;</span><span style="color:#99ad6a;">nt</span><span style="color:#556633;">&#39;</span><span>:
</span><span> </span><span style="color:#888888;"># Windows 平台
</span><span> </span><span style="color:#ffb964;">EXEC_PATH </span><span>= </span><span style="color:#8fbfdc;">r</span><span style="color:#556633;">&#39;</span><span style="color:#99ad6a;">C:\Users\XXYYZZ</span><span style="color:#556633;">&#39;
</span><span> </span><span style="color:#8fbfdc;">else</span><span>:
</span><span> </span><span style="color:#888888;"># Linux / macOS 平台
</span><span> </span><span style="color:#ffb964;">EXEC_PATH </span><span>= </span><span style="color:#556633;">&#39;</span><span style="color:#99ad6a;">/usr/bin</span><span style="color:#556633;">&#39;
</span><span>
</span><span>elif CROSS_TOOL == &#39;keil&#39;:
</span><span> PLATFORM = &#39;armclang&#39; # KEIL AC6
</span><span> # PLATFORM = &#39;armcc&#39; # KEIL AC5
</span><span> EXEC_PATH = r&#39;C:/Keil_v5&#39;
</span><span style="color:#8fbfdc;">elif </span><span style="color:#ffb964;">CROSS_TOOL </span><span>== </span><span style="color:#556633;">&#39;</span><span style="color:#99ad6a;">keil</span><span style="color:#556633;">&#39;</span><span>:
</span><span> </span><span style="color:#ffb964;">PLATFORM </span><span>= </span><span style="color:#556633;">&#39;</span><span style="color:#99ad6a;">armclang</span><span style="color:#556633;">&#39; </span><span style="color:#888888;"># KEIL AC6
</span><span> </span><span style="color:#888888;"># PLATFORM = &#39;armcc&#39; # KEIL AC5
</span><span> </span><span style="color:#ffb964;">EXEC_PATH </span><span>= </span><span style="color:#8fbfdc;">r</span><span style="color:#556633;">&#39;</span><span style="color:#99ad6a;">C:/Keil_v5</span><span style="color:#556633;">&#39;
</span><span>
</span><span>elif CROSS_TOOL == &#39;iar&#39;:
</span><span> PLATFORM = &#39;iccarm&#39;
</span><span> EXEC_PATH = r&#39;C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.3&#39;
</span><span style="color:#8fbfdc;">elif </span><span style="color:#ffb964;">CROSS_TOOL </span><span>== </span><span style="color:#556633;">&#39;</span><span style="color:#99ad6a;">iar</span><span style="color:#556633;">&#39;</span><span>:
</span><span> </span><span style="color:#ffb964;">PLATFORM </span><span>= </span><span style="color:#556633;">&#39;</span><span style="color:#99ad6a;">iccarm</span><span style="color:#556633;">&#39;
</span><span> </span><span style="color:#ffb964;">EXEC_PATH </span><span>= </span><span style="color:#8fbfdc;">r</span><span style="color:#556633;">&#39;</span><span style="color:#99ad6a;">C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.3</span><span style="color:#556633;">&#39;
</span><span>
</span><span>elif CROSS_TOOL == &#39;llvm-arm&#39;:
</span><span> PLATFORM = &#39;llvm-arm&#39;
</span><span> if os.name == &#39;nt&#39;:
</span><span> EXEC_PATH = r&#39;D:\Progrem\LLVMEmbeddedToolchainForArm-17.0.1-Windows-x86_64\bin&#39;
</span><span> else:
</span><span> EXEC_PATH = &#39;/usr/bin&#39;
</span><span style="color:#8fbfdc;">elif </span><span style="color:#ffb964;">CROSS_TOOL </span><span>== </span><span style="color:#556633;">&#39;</span><span style="color:#99ad6a;">llvm-arm</span><span style="color:#556633;">&#39;</span><span>:
</span><span> </span><span style="color:#ffb964;">PLATFORM </span><span>= </span><span style="color:#556633;">&#39;</span><span style="color:#99ad6a;">llvm-arm</span><span style="color:#556633;">&#39;
</span><span> </span><span style="color:#8fbfdc;">if </span><span>os.name == </span><span style="color:#556633;">&#39;</span><span style="color:#99ad6a;">nt</span><span style="color:#556633;">&#39;</span><span>:
</span><span> </span><span style="color:#ffb964;">EXEC_PATH </span><span>= </span><span style="color:#8fbfdc;">r</span><span style="color:#556633;">&#39;</span><span style="color:#99ad6a;">D:\Progrem\LLVMEmbeddedToolchainForArm-17.0.1-Windows-x86_64</span><span style="color:#8fbfdc;">\b</span><span style="color:#99ad6a;">in</span><span style="color:#556633;">&#39;
</span><span> </span><span style="color:#8fbfdc;">else</span><span>:
</span><span> </span><span style="color:#ffb964;">EXEC_PATH </span><span>= </span><span style="color:#556633;">&#39;</span><span style="color:#99ad6a;">/usr/bin</span><span style="color:#556633;">&#39;
</span></code></pre>
<p>随后可以使用PKG初始化并安装两个必要的包</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>pkgs --update
<pre data-lang="shell" style="background-color:#151515;color:#e8e8d3;" class="language-shell "><code class="language-shell" data-lang="shell"><span>pkgs --update
</span><span>pip install kconfiglib
</span><span>pip install scons
</span></code></pre>
<h2 id="bian-yi">编译</h2>
<p>在完成以上设置之后我们可以开始编译。STM32使用scons编译系统同样是menuconfig命令</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>scons --menuconfig
<pre data-lang="shell" style="background-color:#151515;color:#e8e8d3;" class="language-shell "><code class="language-shell" data-lang="shell"><span>scons --menuconfig
</span></code></pre>
<p>修改配置并保存退出后即可开始编译,$(nproc)代表使用全部CPU线程来编译</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>scons -j$(nproc)
<pre data-lang="shell" style="background-color:#151515;color:#e8e8d3;" class="language-shell "><code class="language-shell" data-lang="shell"><span>scons -j$(nproc)
</span></code></pre>
<h2 id="shao-ru">烧入</h2>
<p>编译成功后你应该会看到有一个rtthread.bin在目录下这就是我们编译出来的系统</p>
<p>在烧入之前,我们可以备份一下原来的系统:</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>st-flash read firmware_backup.bin 0x08000000 0x100001
<pre data-lang="shell" style="background-color:#151515;color:#e8e8d3;" class="language-shell "><code class="language-shell" data-lang="shell"><span>st-flash read firmware_backup.bin 0x08000000 0x100001
</span></code></pre>
<p>随后使用如下命令烧入系统:</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>st-flash write rtthread.bin 0x08000000
<pre data-lang="shell" style="background-color:#151515;color:#e8e8d3;" class="language-shell "><code class="language-shell" data-lang="shell"><span>st-flash write rtthread.bin 0x08000000
</span></code></pre>
<h2 id="chuan-kou">串口</h2>
<p>除了USB之外我们还可以使用串口连接</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>sudo apt install picocom
<pre data-lang="shell" style="background-color:#151515;color:#e8e8d3;" class="language-shell "><code class="language-shell" data-lang="shell"><span>sudo apt install picocom
</span><span>picocom -b 115200 /dev/ttyACM0
</span><span>version
</span></code></pre>
<p>可以使用<code>ctrl + A 然后 ctrl + x</code>退出。</p>
<h2 id="shi-yong-cmake">使用Cmake</h2>
<p>通过官方文档可以得知除了scons外还可以使用Cmake来编译.</p>
<p>首先找到编译器的路径并export</p>
<pre data-lang="shell" style="background-color:#151515;color:#e8e8d3;" class="language-shell "><code class="language-shell" data-lang="shell"><span> which arm-none-eabi-gcc
</span><span>/nix/store/v9p5md3d4aaqwc9i9hlaxkl7nawd9vrc-gcc-arm-embedded-14.3.rel1/bin/arm-none-eabi-gcc
</span><span>export RTT_EXEC_PATH=/nix/store/v9p5md3d4aaqwc9i9hlaxkl7nawd9vrc-gcc-arm-embedded-14.3.rel1/bin
</span><span>export RTT_CC=gcc
</span></code></pre>
<p>随后使用指令<code>scons --target=cmake</code></p>
<pre data-lang="shell" style="background-color:#151515;color:#e8e8d3;" class="language-shell "><code class="language-shell" data-lang="shell"><span> scons --target=cmake
</span><span>
</span><span>scons: Reading SConscript files ...
</span><span>Newlib version:4.5.0
</span><span>Update setting files for CMakeLists.txt...
</span><span>Done!
</span><span>scons: done reading SConscript files.
</span><span>scons: Building targets ...
</span><span>scons: building associated VariantDir targets: build
</span><span>CC build/applications/main.o
</span><span>LINK rt-thread.elf
</span><span>arm-none-eabi-objcopy -O binary rt-thread.elf rtthread.bin
</span><span>arm-none-eabi-size rt-thread.elf
</span><span>scons: done building targets.
</span></code></pre>
<p>可以看到生成CmakeLists.txt成功随后开始构建</p>
<pre data-lang="shell" style="background-color:#151515;color:#e8e8d3;" class="language-shell "><code class="language-shell" data-lang="shell"><span> cd ./build
</span><span> cmake ..
</span><span>CMake Warning (dev) at CMakeLists.txt:43:
</span><span> Syntax Warning in cmake code at column 100
</span><span>
</span><span> Argument not separated from preceding token by whitespace.
</span><span>This warning is for project developers. Use -Wno-dev to suppress it.
</span><span>
</span><span>-- The C compiler identification is GNU 14.3.1
</span><span>-- The CXX compiler identification is GNU 14.3.1
</span><span>-- The ASM compiler identification is GNU
</span><span>-- Found assembler: /nix/store/v9p5md3d4aaqwc9i9hlaxkl7nawd9vrc-gcc-arm-embedded-14.3.rel1/bin/arm-none-eabi-gcc
</span><span>-- Detecting C compiler ABI info
</span><span>-- Detecting C compiler ABI info - done
</span><span>-- Check for working C compiler: /nix/store/v9p5md3d4aaqwc9i9hlaxkl7nawd9vrc-gcc-arm-embedded-14.3.rel1/bin/arm-none-eabi-gcc - skipped
</span><span>-- Detecting C compile features
</span><span>-- Detecting C compile features - done
</span><span>-- Detecting CXX compiler ABI info
</span><span>-- Detecting CXX compiler ABI info - done
</span><span>-- Check for working CXX compiler: /nix/store/v9p5md3d4aaqwc9i9hlaxkl7nawd9vrc-gcc-arm-embedded-14.3.rel1/bin/arm-none-eabi-g++ - skipped
</span><span>-- Detecting CXX compile features
</span><span>-- Detecting CXX compile features - done
</span><span>-- Configuring done (0.4s)
</span><span>-- Generating done (0.0s)
</span><span>-- Build files have been written to: /home/dich/Git/sdk-bsp-stm32f407-spark/projects/02_basic_ir/build
</span></code></pre>
<p>使用<code>make</code>命令编译:</p>
<pre data-lang="shell" style="background-color:#151515;color:#e8e8d3;" class="language-shell "><code class="language-shell" data-lang="shell"><span> make
</span><span>[ 1%] Building C object CMakeFiles/rtthread.elf.dir/applications/main.c.obj
</span><span>[ 2%] Building C object CMakeFiles/rtthread.elf.dir/home/dich/Git/sdk-bsp-stm32f407-spark/rt-thread/components/libc/compilers/common/cctype.c.obj
</span><span>[ 3%] Building C object CMakeFiles/rtthread.elf.dir/home/dich/Git/sdk-bsp-stm32f407-spark/rt-thread/components/libc/compilers/common/cstdio.c.obj
</span><span>......
</span><span>[ 97%] Building C object CMakeFiles/rtthread.elf.dir/home/dich/Git/sdk-bsp-stm32f407-spark/libraries/STM32F4xx_HAL/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c.obj
</span><span>[ 98%] Building C object CMakeFiles/rtthread.elf.dir/home/dich/Git/sdk-bsp-stm32f407-spark/libraries/STM32F4xx_HAL/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c.obj
</span><span>[100%] Linking C executable rtthread.elf
</span><span> text data bss dec hex filename
</span><span> 98516 1468 8400 108384 1a760 rtthread.elf
</span><span>[100%] Built target rtthread.elf
</span></code></pre>
<h2 id="shi-yong-renode">使用Renode</h2>
<p>如果没有真实的开发版可以使用Renode来进行仿真模拟</p>
<pre data-lang="shell" style="background-color:#151515;color:#e8e8d3;" class="language-shell "><code class="language-shell" data-lang="shell"><span># 启动renode
</span><span>renode
</span><span>
</span><span># 创建机器
</span><span>(monitor) mach create
</span><span>
</span><span># 加载STM32F407平台
</span><span>(monitor) machine LoadPlatformDescription @platforms/boards/stm32f4_discovery.repl
</span><span>
</span><span># 加载你的固件
</span><span>(monitor) sysbus LoadELF @/你的路径/rtthread.elf
</span><span>
</span><span># 打开串口窗口finsh会显示在这里
</span><span>(monitor) showAnalyzer sysbus.usart1
</span><span>
</span><span># 启动仿真
</span><span>(monitor) start
</span></code></pre>
<blockquote>
<p>Renode 常用命令大全</p>
</blockquote>
<pre data-lang="bash" style="background-color:#151515;color:#e8e8d3;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#888888;"># 机器管理
</span><span style="color:#ffb964;">mach</span><span> add </span><span style="color:#556633;">&quot;</span><span style="color:#99ad6a;">名称</span><span style="color:#556633;">&quot; </span><span style="color:#888888;"># 创建新机器(指定名称)
</span><span style="color:#ffb964;">mach</span><span> create </span><span style="color:#888888;"># 创建新机器(自动命名)
</span><span style="color:#ffb964;">mach</span><span> set </span><span style="color:#556633;">&quot;</span><span style="color:#99ad6a;">名称</span><span style="color:#556633;">&quot; </span><span style="color:#888888;"># 切换到指定机器
</span><span style="color:#ffb964;">mach</span><span> set 0 </span><span style="color:#888888;"># 切换到编号0的机器
</span><span style="color:#ffb964;">mach</span><span> rem </span><span style="color:#556633;">&quot;</span><span style="color:#99ad6a;">名称</span><span style="color:#556633;">&quot; </span><span style="color:#888888;"># 删除机器
</span><span style="color:#ffb964;">mach</span><span> clear </span><span style="color:#888888;"># 清除当前选择
</span><span style="color:#ffb964;">mach </span><span style="color:#888888;"># 显示帮助信息
</span><span style="color:#ffb964;">emulation </span><span style="color:#888888;"># 查看仿真信息
</span><span>
</span><span style="color:#888888;"># 仿真控制
</span><span style="color:#ffb964;">start </span><span style="color:#888888;"># 启动仿真
</span><span style="color:#ffb964;">pause </span><span style="color:#888888;"># 暂停仿真
</span><span style="color:#ffb964;">quit </span><span style="color:#888888;"># 退出Renode
</span><span>
</span><span style="color:#888888;"># 帮助
</span><span>help </span><span style="color:#888888;"># 显示帮助
</span><span>help 命令名 </span><span style="color:#888888;"># 查看特定命令帮助
</span><span>
</span><span style="color:#888888;"># 加载固件
</span><span style="color:#ffb964;">sysbus</span><span> LoadELF @/path/to/firmware.elf </span><span style="color:#888888;"># 加载ELF文件
</span><span style="color:#ffb964;">sysbus</span><span> LoadBinary @/path/to/firmware.bin 0x8000000 </span><span style="color:#888888;"># 加载BIN到指定地址
</span><span>
</span><span style="color:#888888;"># 重置
</span><span style="color:#ffb964;">sysbus</span><span> Reset </span><span style="color:#888888;"># 重置系统总线
</span><span style="color:#ffb964;">machine</span><span> Reset </span><span style="color:#888888;"># 重置整个机器
</span><span>
</span><span style="color:#888888;"># 读取内存
</span><span style="color:#ffb964;">sysbus</span><span> ReadByte 0x20000000 </span><span style="color:#888888;"># 读1字节
</span><span style="color:#ffb964;">sysbus</span><span> ReadWord 0x20000000 </span><span style="color:#888888;"># 读2字节
</span><span style="color:#ffb964;">sysbus</span><span> ReadDoubleWord 0x20000000 </span><span style="color:#888888;"># 读4字节
</span><span>
</span><span style="color:#888888;"># 写入内存
</span><span style="color:#ffb964;">sysbus</span><span> WriteByte 0x20000000 0xFF
</span><span style="color:#ffb964;">sysbus</span><span> WriteWord 0x20000000 0x1234
</span><span style="color:#ffb964;">sysbus</span><span> WriteDoubleWord 0x20000000 0x12345678
</span><span>
</span><span style="color:#888888;"># 查看内存区域
</span><span style="color:#ffb964;">sysbus</span><span> FindSymbolAt 0x08000000 </span><span style="color:#888888;"># 查找地址对应的符号
</span><span>
</span><span style="color:#888888;"># 查看GPIO端口
</span><span style="color:#ffb964;">sysbus.gpioPortA
</span><span>
</span><span style="color:#888888;"># 设置GPIO状态
</span><span style="color:#ffb964;">sysbus.gpioPortA.0</span><span> Set true </span><span style="color:#888888;"># 设置PA0为高
</span><span style="color:#ffb964;">sysbus.gpioPortA.0</span><span> Set false </span><span style="color:#888888;"># 设置PA0为低
</span><span style="color:#ffb964;">sysbus.gpioPortA.0</span><span> Toggle </span><span style="color:#888888;"># 切换PA0状态
</span><span>
</span><span style="color:#888888;"># 读取GPIO状态
</span><span style="color:#ffb964;">sysbus.gpioPortA.0</span><span> State
</span><span>
</span><span style="color:#888888;"># 使用GDB调试
</span><span>(</span><span style="color:#ffb964;">monitor</span><span>) machine StartGdbServer 3333
</span><span style="color:#888888;"># 另一个终端
</span><span style="color:#ffb964;">arm-none-eabi-gdb</span><span> firmware.elf
</span><span>(</span><span style="color:#ffb964;">gdb</span><span>) target remote :3333
</span><span>(</span><span style="color:#ffb964;">gdb</span><span>) load
</span><span>(</span><span style="color:#ffb964;">gdb</span><span>) b main
</span><span>(</span><span style="color:#ffb964;">gdb</span><span>) c
</span></code></pre>
<hr />
<p><strong>Done.</strong></p>

View File

@@ -202,6 +202,39 @@
</div>
</div>
<div class="post on-list">
<h1 class="post-title"><a href="https://blog.dich.bid/linux-0-start/">Linux-优雅过渡</a></h1>
<div class="post-meta-inline">
<span class="post-date">
2023-06-20
</span>
</div>
<span class="post-tags-inline">
:: tags:&nbsp;
<a class="post-tag" href="https://blog.dich.bid/tags/linux/">#Linux</a></span>
<div class="post-content">
<p>前言 本文面向刚刚从Windows转向Linux的一般使用者和想在Linux上进行开发的开发者主要说明其系统特点和使用须知。</p>
</div>
<div>
<!-- &#xFE0E; -- force text style - some devices render this as emoji -->
<a class="read-more button" href="https://blog.dich.bid/linux-0-start/">
<span class="button__text">Read more</span>&nbsp;
<span class="button__icon">&#8617;&#xFE0E;</span>
</a>
</div>
</div>
<div class="pagination">
<div class="pagination__buttons">

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1 +1 @@
{"version":"1.3.0","languages":{"en":{"hash":"en_40173c68cb","wasm":"en","page_count":77}}}
{"version":"1.3.0","languages":{"en":{"hash":"en_15f5696b4f","wasm":"en","page_count":78}}}

Binary file not shown.

View File

@@ -141,6 +141,10 @@
<url>
<loc>https://blog.dich.bid/links/link-7/</loc>
</url>
<url>
<loc>https://blog.dich.bid/linux-0-start/</loc>
<lastmod>2023-06-20</lastmod>
</url>
<url>
<loc>https://blog.dich.bid/linux-1-command/</loc>
<lastmod>2023-07-20</lastmod>

View File

@@ -113,7 +113,7 @@
<li class="tag-list">
<a href="https://blog.dich.bid/tags/linux/">
Linux (2 posts)
Linux (3 posts)
</a>
</li>

View File

@@ -110,7 +110,7 @@ Dich&#x27;s Blog</title>
<div class="post">
<h1 class="post-title">
tag: #Linux
(2 posts)
(3 posts)
</h1>
<a href="https://blog.dich.bid/tags">
@@ -137,6 +137,16 @@ Dich&#x27;s Blog</title>
::
<a class="post-tag" href="https://blog.dich.bid/tags/linux/">#Linux</a></span>
</li>
<li class="post-list">
<a href="https://blog.dich.bid/linux-0-start/">
<span class="post-date">2023-06-20</span>
:: <span class="post-list-title">Linux-优雅过渡</span></a>
<span class="post-tags-inline">
::
<a class="post-tag" href="https://blog.dich.bid/tags/linux/">#Linux</a></span>
</li>
</ul>

View File

@@ -306,69 +306,81 @@
<blockquote>
<p>当然,你也可以使用其他编辑器/IDE如 Sublime Text 或者 JetBrains 系列的 PyCharm 。</p>
</blockquote>
<h2 id="shi-yong-uvti-dai-conda">使用UV替代Conda</h2>
<h2 id="shi-yong-uv-ti-dai-conda">使用 UV 替代 Conda</h2>
<blockquote>
<p>UV由 Astral 团队开发)是一个用 Rust 编写的高性能包管理器,提供类似 Conda 的虚拟环境管理和依赖解析功能,并且在大多数场景下比 pip 和 Conda 快 10100 倍。它通过命令行工具如 uv venv创建/管理虚拟环境)和 uv pip(安装/锁定/同步依赖)覆盖传统的 conda create、conda install、conda env export 等操作,但本身不管理底层的 C/C++ 库,因此对于诸如 GDAL、SciPy 等需要系统级二进制依赖的包,仍建议在 Conda/系统包管理器中预装相关库,然后用 UV 管理 Python 包。</p>
<p>UV由 Astral 团队开发)是一个用 Rust 编写的高性能 Python 包管理器,提供类似 Conda 的虚拟环境管理和依赖解析功能,在大多数场景下比 pip 和 Conda 快 10100 倍。它通过命令行工具如 <code>uv venv</code>(创建/管理虚拟环境)和 <code>uv pip</code>(安装/锁定/同步依赖)覆盖传统的 Conda 流程,但本身不管理底层的 C/C++ 库,因此对于 GDAL、SciPy 等需要系统级二进制依赖的包,仍建议先通过系统包管理器或 Conda 安装,然后用 UV 管理 Python 包。</p>
</blockquote>
<p><strong>安装与激活</strong></p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>wget -qO- https://astral.sh/uv/install.sh | sh
<hr />
<ul>
<li>安装 UV</li>
</ul>
<pre data-lang="bash" style="background-color:#151515;color:#e8e8d3;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#ffb964;">wget -qO-</span><span> https://astral.sh/uv/install.sh | </span><span style="color:#ffb964;">sh
</span></code></pre>
<ul>
<li>在当前目录下创建 .venv使用系统默认 Python若不存在则自动下载</li>
<li>创建与管理环境</li>
</ul>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>uv venv
</span></code></pre>
<ul>
<li>指定环境名称或路径</li>
</ul>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>uv venv myenv
</span></code></pre>
<ul>
<li>指定 Python 版本(需系统已有或可下载)</li>
</ul>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>uv venv --python 3.11
</span></code></pre>
<ul>
<li>激活</li>
</ul>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>source .venv/bin/activate
</span></code></pre>
<p><strong>安装包</strong></p>
<pre data-lang="bash" style="background-color:#151515;color:#e8e8d3;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#888888;"># 安装单个包
</span><span style="color:#ffb964;">uv</span><span> pip install requests
<pre data-lang="bash" style="background-color:#151515;color:#e8e8d3;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#888888;"># 创建虚拟环境,指定 Python 版本
</span><span style="color:#ffb964;">uv</span><span> venv</span><span style="color:#ffb964;"> --python</span><span> 3.12
</span><span>
</span><span style="color:#888888;"># 批量安装并自动锁定依赖
</span><span style="color:#ffb964;">uv</span><span> pip install fastapi uvicorn sqlalchemy
</span></code></pre>
<p><strong>生成与同步锁文件</strong></p>
<pre data-lang="bash" style="background-color:#151515;color:#e8e8d3;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#888888;"># 从 requirements.in 生成统一依赖文件
</span><span style="color:#ffb964;">uv</span><span> pip compile docs/requirements.in \
</span><span style="color:#ffb964;"> --universal </span><span>\
</span><span style="color:#ffb964;"> --output-file</span><span> docs/requirements.txt
</span><span style="color:#888888;"># 激活环境
</span><span>source .venv/bin/activate
</span><span>
</span><span style="color:#888888;"># 根据锁文件同步环境
</span><span style="color:#ffb964;">uv</span><span> pip sync docs/requirements.txt
</span><span style="color:#888888;"># 退出环境
</span><span style="color:#ffb964;">deactivate
</span><span>
</span><span style="color:#888888;"># 删除环境
</span><span style="color:#ffb964;">rm -rf</span><span> .venv
</span></code></pre>
<p>此流程替代 <code>conda env export</code> + <code>conda env update</code>,并保证跨平台一致性 ([GitHub][3])。</p>
<p><strong>查看与卸载</strong></p>
<pre data-lang="bash" style="background-color:#151515;color:#e8e8d3;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#ffb964;">uv</span><span> pip list </span><span style="color:#888888;"># 列出已安装包(类似 conda list
<ul>
<li>直接运行</li>
</ul>
<pre data-lang="bash" style="background-color:#151515;color:#e8e8d3;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#ffb964;">uv</span><span> run python
</span><span style="color:#ffb964;">uv</span><span> run jupyter lab
</span></code></pre>
<ul>
<li>注册 Jupyter 内核</li>
</ul>
<pre data-lang="bash" style="background-color:#151515;color:#e8e8d3;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#ffb964;">uv</span><span> run python</span><span style="color:#ffb964;"> -m</span><span> ipykernel install</span><span style="color:#ffb964;"> --user --name</span><span> bank</span><span style="color:#ffb964;"> --display-name </span><span style="color:#556633;">&quot;</span><span style="color:#99ad6a;">Python (bank)</span><span style="color:#556633;">&quot;
</span></code></pre>
<hr />
<ul>
<li>安装依赖</li>
</ul>
<pre data-lang="bash" style="background-color:#151515;color:#e8e8d3;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#ffb964;">uv</span><span> add tensorflow
</span><span style="color:#ffb964;">uv</span><span> pip install requests fastapi uvicorn sqlalchemy
</span></code></pre>
<blockquote>
<p>安装完成后UV 会自动更新 <code>uv.lock</code> 文件锁定依赖版本,保证环境可复现。</p>
</blockquote>
<ul>
<li>使用 TOML 配置管理依赖</li>
</ul>
<p>创建一个 <code>pyproject.toml</code></p>
<pre data-lang="toml" style="background-color:#151515;color:#e8e8d3;" class="language-toml "><code class="language-toml" data-lang="toml"><span>[</span><span style="color:#ffb964;">tool</span><span>.</span><span style="color:#ffb964;">uv</span><span>.</span><span style="color:#ffb964;">dependencies</span><span>]
</span><span style="color:#ffb964;">fastapi </span><span>= </span><span style="color:#556633;">&quot;</span><span style="color:#99ad6a;">*</span><span style="color:#556633;">&quot;
</span><span style="color:#ffb964;">uvicorn </span><span>= </span><span style="color:#556633;">&quot;</span><span style="color:#99ad6a;">*</span><span style="color:#556633;">&quot;
</span><span style="color:#ffb964;">sqlalchemy </span><span>= </span><span style="color:#556633;">&quot;</span><span style="color:#99ad6a;">*</span><span style="color:#556633;">&quot;
</span></code></pre>
<p>然后同步环境:</p>
<pre data-lang="bash" style="background-color:#151515;color:#e8e8d3;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#ffb964;">uv</span><span> pip sync
</span></code></pre>
<p>这会根据 <code>pyproject.toml</code> + <code>uv.lock</code> 安装和锁定所有依赖。</p>
<ul>
<li>查看与卸载包</li>
</ul>
<pre data-lang="bash" style="background-color:#151515;color:#e8e8d3;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#ffb964;">uv</span><span> pip list </span><span style="color:#888888;"># 列出已安装包
</span><span style="color:#ffb964;">uv</span><span> pip uninstall numpy
</span></code></pre>
<p><strong>替代常见 Conda 工作流</strong></p>
<hr />
<h3 id="ti-dai-chang-jian-conda-gong-zuo-liu">替代常见 Conda 工作流</h3>
<table><thead><tr><th>Conda 操作</th><th>UV 对应</th></tr></thead><tbody>
<tr><td><code>conda create -n env python=3.x</code></td><td><code>uv venv --python 3.x</code></td></tr>
<tr><td><code>conda activate env</code></td><td><code>source .venv/bin/activate</code><code>activate</code></td></tr>
<tr><td><code>conda activate env</code></td><td><code>source .venv/bin/activate</code><code>uv venv activate</code></td></tr>
<tr><td><code>conda install pkg1 pkg2</code></td><td><code>uv pip install pkg1 pkg2</code></td></tr>
<tr><td><code>conda env export &gt; env.yml</code></td><td><code>uv pip compile requirements.in</code></td></tr>
<tr><td><code>conda env update -f env.yml</code></td><td><code>uv pip sync requirements.txt</code></td></tr>
<tr><td><code>conda env export &gt; env.yml</code></td><td>自动生成 <code>uv.lock</code><code>uv pip compile requirements.in</code></td></tr>
<tr><td><code>conda env update -f env.yml</code></td><td><code>uv pip sync</code>(根据 <code>uv.lock</code><code>pyproject.toml</code> 同步)</td></tr>
<tr><td><code>conda list</code></td><td><code>uv pip list</code></td></tr>
</tbody></table>
<p><strong>最佳实践</strong></p>
<ol>
<li><strong>系统依赖</strong>:用 Conda/Mamba 安装较难编译的 C 库(<code>conda install gdal</code>)。</li>
<li><strong>Python 包</strong>:用 UV 管理所有纯 Python 依赖(<code>uv pip install pandas scikit-learn</code>)。</li>
<li><strong>统一锁定</strong>:把 <code>uv pip compile</code> 生成的 <code>requirements.txt</code> 放入版本控制,确保团队环境一致。</li>
</ol>
<h2 id="ipynbzhuan-markdown">ipynb转markdown</h2>
<p>首先安装 nbformat 和 nbconvert包</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>conda install nbformat nbconvert -y