- 2024-02-04
-
发表了主题帖:
【米尔-TI AM62x开发板-试用评测】4.基于Python的图形化测试(未成功版)
# 【米尔-TI AM62x开发板-试用评测】4.基于Python的图形化测试
开发板的默认镜像中是包含了 **Python3** 的,笔者还是习惯直接使用 `python` 命令,所以创建一个软连接。
```bash
ln -s /usr/bin/python3 /usr/bin/python
```
安装 pip3
**Python3** 有了,还少的了 **pip3** 么,运行
```bash
python -m ensurepip --upgrade
```
进行安装,同样也创建软连接。
```bash
ln -s /usr/bin/pip3 /usr/bin/pip
```
查看版本号
```bash
python -V
pip -V
```
设置虚拟机环境
```bash
python -m venv tutorial-env
```
启动虚拟机环境
```bash
source tutorial-env/bin/activate
```
更换国内源
```bash
mkdir -p ~/.pip
touch ~/.pip/pip.conf
vi ~/.pip/pip.conf
```
在里面添加
```
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
```
安装 pandas
```bash
pip install pandas
```
安装 matplotlib seaborn
```bash
pip install matplotlib seaborn
```
编写一个图形化示例程序
```bash
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 创建一个简单的DataFrame
data = {'Month': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
'Temperature': [15, 18, 22, 25, 30, 33],
'Rainfall': [50, 45, 30, 15, 10, 5]}
df = pd.DataFrame(data)
# 打印DataFrame
print("DataFrame:")
print(df)
# 使用seaborn绘制温度折线图
plt.figure(figsize=(10, 5))
sns.lineplot(x='Month', y='Temperature', data=df, marker='o', label='Temperature')
plt.title('Monthly Temperature')
plt.xlabel('Month')
plt.ylabel('Temperature (°C)')
# 使用seaborn绘制降雨柱状图
plt.figure(figsize=(10, 5))
sns.barplot(x='Month', y='Rainfall', data=df, color='blue', label='Rainfall')
plt.title('Monthly Rainfall')
plt.xlabel('Month')
plt.ylabel('Rainfall (mm)')
# 显示图形
plt.show()
```
如果板子图形化能正常的话,照理来说在这里就可以看到画出的图了。
但是我这边测试非常卡,不能出图,键盘反馈也不好。
---
另一个代码示例
```python
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 创建一个简单的数据集
data = {'A': [1, 2, 3, 4, 5],
'B': [2, 3, 5, 7, 11],
'C': [8, 6, 4, 2, 0]}
df = pd.DataFrame(data)
# 使用 Seaborn 设置图形样式
sns.set(style="whitegrid")
# 创建一个散点图
plt.figure(figsize=(8, 6))
sns.scatterplot(x='A', y='B', data=df, hue='C', palette='viridis', size='C', sizes=(50, 200))
# 添加标题和标签
plt.title('Scatter Plot with Seaborn and Matplotlib')
plt.xlabel('Variable A')
plt.ylabel('Variable B')
# 显示图例
plt.legend(title='Variable C', loc='upper right')
# 显示图形
plt.show()
```
-
发表了主题帖:
【米尔-TI AM62x开发板-试用评测】5.串口通信及网络测试
# 【米尔-TI AM62x开发板-试用评测】5.串口通信及网络测试
因为 **MYD-6231** 板卡的图像化表现实在是差强人意……只能转而测试其他方向了。今天测试的是网络部分。
由于回老家,板子离路由器的位置太远,所以首先用串口连接,开启 **WiFi** 之后,再用 **SSH** 连接。
## 串口通信
**COMTransmit** 是一款串口调试助手。以下是它的一些主要特性:
- 集成串口功能与各种常用工具
- 支持多串口通讯、串口互通测试
- 文件发送与接收
- 字符串和十六进制数据输入和显示
- 模块帧格式调试
- 功能非常强大
- 在 Linux 系统下,它的界面风格与 Windows 上的串口调试助手类似
- 可以查看 USB 转串口芯片的型号及 VID、PID
这款软件在 **Windows** 和 **Linux** 平台上都有良好的应用,并且在串口设备的调试和监控方面表现出色。如果你在进行嵌入式开发或物联网项目,**COMTransmit** 可能会是一个很好的工具。
下载地址:https://www.wch.cn/downloads/COMTransmit_ZIP.html
这是打开串口之后,整个页面显示的开机信息
[localvideo]4adfcdbf2e02e3ee283f2e6510bb9e0a[/localvideo]
### 开启WiFi
开发板板载 **L297B Wi-Fi** 和 **Bluetooth** 二合一模块,当前不支持 **STA** 和 **AP** 同时工
作,**L297B Wi-Fi** 模块对应的驱动为 **moal** 和 **mlan**:
```bash
lsmod
```
查看网络节点 **mlan0**
```bash
ifconfig mlan0
```
激活 **mlan0**
```bash
ifconfig mlan0 up
```
扫描 **WIFI**
```bash
iw dev mlan0 scan | grep SSID
```
设置 **WIFI** 名字和密码
```bash
wpa_passphrase FAST_17DC qq123456 >> /etc/wpa_supplicant.conf
```
初始化 **wpa_supplicant**
```bash
killall wpa_supplicant
wpa_supplicant -B -i mlan0 -c /etc/wpa_supplicant.conf
```
查看 **IP** 地址
```bash
udhcpc -i mlan0
```
拿到 **IP** 地址之后,就可以 **SSH** 登录了
## 网络测速
首先安装 speedtest-cli
```bash
pip install speedtest-cli
```
新建一个测速脚本
```python
import speedtest
st = speedtest.Speedtest()
st.get_best_server()
st.download()
st.upload()
st.results.share()
results_dict = st.results.dict()
download_speed = results_dict['download'] / (10**6)
upload_speed = results_dict['upload'] / (10**6)
print(f'下载速度: {download_speed} Mbps')
print(f'上传速度: {upload_speed} Mbps')
```
这是运行结果
家里是100M的宽带,这个下载速度小于上传速度也是神奇了。
-
回复了主题帖:
阅读打卡终点站: 进程管理之调试与案例分析—— 《奔跑吧Linux内核(第2版)卷1》
1. 查看进程的调度信息可以使用命令 `ps -eLf` 或 `top`。这些命令可以显示进程的详细信息,包括调度相关的信息。
2. 查看CFS(Completely Fair Scheduler)的调度信息可以使用 `schedstat` 工具。通过 `/proc` 文件系统可以查看,例如使用命令 `cat /proc/schedstat` 可以显示当前CFS的统计信息。
3. 查看调度域的拓扑关系可以使用 `lscpu` 命令。这个命令会显示有关CPU架构的信息,包括调度域的拓扑结构。
4. 在一个双核处理器系统中,假设在Shell界面下运行test程序,CPU0的就绪队列中有4个进程,而CPU1的就绪队列中有1个进程,test程序和这5个进程的nice值都为0。现在来画出test程序在内核空间的运行流程:
```
+---------------------------------------------+
| |
| 用户空间 |
| |
+---------------------------------------------+
| 内核空间 |
| |
| +---------------------------------+ |
| | | |
| | Scheduler (调度器) | |
| | | |
| +---------------------------------+ |
| | | |
| | test程序 | |
| | (PID: X) | |
| | | |
| +---------------------------------+ |
| | | |
| | 进程1 (PID: Y) | |
| | | |
| +---------------------------------+ |
| | | |
| | 进程2 (PID: Z) | |
| | | |
| +---------------------------------+ |
| | | |
| | ... | |
| | | |
| +---------------------------------+ |
+---------------------------------------------+
```
随着时间的推移,CPU0和CPU1的就绪队列可能发生变化,具体的变化取决于调度算法和各个进程的状态。例如,某些进程可能被调度到CPU0或CPU1上执行,而有些进程可能被移出就绪队列,等等。
- 2024-01-19
-
回复了主题帖:
阅读打卡第七站:进程管理之基本概念 ——《奔跑吧Linux内核(第2版)卷1》
1. 进程是计算机中正在执行的程序的实例。它包含了程序的代码、数据和进程控制块等信息。每个进程都是独立运行的,拥有自己的地址空间、资源和状态。多个进程可以同时运行在计算机系统中,彼此之间相互独立。
2. 操作系统描述和抽象一个进程通过进程控制块(Process Control Block,PCB)来实现。PCB是操作系统维护的一个数据结构,包含了进程的重要信息,如进程状态、程序计数器、寄存器状态、内存分配信息、打开文件的列表等。PCB允许操作系统管理和控制每个进程的执行。
3. 进程有生命周期,包括创建、就绪、运行、阻塞、唤醒和终止等阶段。这些阶段描述了进程从被创建到运行,再到结束的整个过程。
4. 进程通过唯一的进程标识符(Process ID,PID)来进行标识。PID是一个整数,用于唯一地区分系统中运行的每个进程。
5. 进程之间可以有不同的关系,包括父子关系、兄弟关系等。进程之间可以通过进程间通信(IPC)的机制来进行数据交换和协作。
6. 在Linux系统中,第0个进程是"swapper"或"init"进程,其PID为0。这个进程是系统启动时创建的,它在系统初始化期间负责一些基本的初始化工作,并在系统启动后演变为init进程。
7. 在Linux系统中,第1个进程是init进程,其PID为1。init是用户空间的第一个进程,负责系统的初始化和启动用户空间的其它进程。
8. - `fork()`: 创建一个子进程,子进程复制了父进程的地址空间,但是在独立的进程空间中运行。子进程和父进程是独立的,各自有自己的数据和代码副本。
- `vfork()`: 类似于fork,但是在子进程中运行时,它共享父进程的地址空间,直到调用exec或者exit。vfork用于创建一个新进程,但子进程会借用父进程的内存空间,因此在子进程中对内存的修改可能影响到父进程。
- `clone()`: 具有更灵活的选项,可以控制新进程与父进程共享的资源,包括文件描述符、信号处理等。clone更为通用,可以实现类似于fork和vfork的功能,还可以创建线程。
-
回复了主题帖:
阅读打卡第八站:进程管理之调度与负载均衡 ——《奔跑吧Linux内核(第2版)卷1》
1. 进程优先级、nice值和权重之间的关系:
- 进程优先级:操作系统为了有效地调度进程而引入的概念,通常表示为一个数字,数字越低表示优先级越高。
- nice值:是一个用户可调整的进程优先级的参数,范围一般为-20到+19。负值表示高优先级,正值表示低优先级。
- 权重:Linux中的CFS(完全公平调度器)使用权重来确定进程的相对优先级。CFS把进程的nice值转换为一个权重,通过这个权重来分配CPU时间。
具体关系如下:nice值的改变会影响进程的权重,而权重决定了进程在CFS中的调度优先级。较高权重的进程更容易获得CPU时间,从而提高其执行优先级。
2. CFS(完全公平调度器)的工作原理:
- CFS旨在提供公平的CPU时间分配,确保所有运行中的进程都有相等的时间片。
- CFS使用虚拟运行时间(vruntime)来衡量进程的执行时间。每个进程都有一个vruntime值,表示它在CPU上运行的时间。
- 进程的调度优先级与其vruntime值成反比。vruntime值越小,表示进程执行时间越长,其调度优先级越低。
- CFS通过不断选择vruntime最小的进程来进行调度,以确保资源公平地分配。
3. CFS中vruntime的计算:
- 初始时,每个进程的vruntime值为0。
- 当一个进程在CPU上运行时,其vruntime值会增加,增加的速度与进程的权重成正比。
- CFS会根据进程的权重和运行时间来计算新的vruntime值,以维持公平调度。
- 具体计算公式:新的vruntime = 当前vruntime + 运行时间 * 权重。
通过这种方式,CFS通过动态调整vruntime值来确定下一个应该被调度的进程,以实现公平的CPU时间分配。
- 2024-01-10
-
发表了主题帖:
一起读《奔跑吧Linux内核(第2版)卷1:基础架构》——查看内存相关的命令
`/proc/meminfo` 是 Linux 操作系统中的一个特殊文件,用于提供有关系统内存使用的信息。这个文件包含了许多有关系统内存的统计数据,可以帮助系统管理员和开发人员监视和分析系统的内存性能。以下是一些常见的 `/proc/meminfo` 输出字段及其解释:
1. **MemTotal**: 系统总内存大小(以 KB 为单位)。
2. **MemFree**: 可用内存的大小(以 KB 为单位),该值包括空闲的、缓存的和可回收的内存。
3. **MemAvailable**: 估算的可用内存大小(以 KB 为单位),它考虑了内核的内存管理和系统中的内存压力。
4. **Buffers**: 内核缓冲区占用的内存大小(以 KB 为单位)。
5. **Cached**: 缓存占用的内存大小(以 KB 为单位),包括文件缓存和页缓存。
6. **SwapCached**: 交换缓存占用的内存大小(以 KB 为单位)。
7. **Active**: 当前活跃的内存大小(以 KB 为单位),包括正在使用的和最近被使用的内存。
8. **Inactive**: 当前不活跃的内存大小(以 KB 为单位),包括最近没有被使用的内存。
9. **SwapTotal**: 交换空间的总大小(以 KB 为单位)。
10. **SwapFree**: 可用的交换空间大小(以 KB 为单位)。
11. **Dirty**: 等待写回到磁盘的脏页面的大小(以 KB 为单位)。
12. **Writeback**: 正在被写回到磁盘的页面的大小(以 KB 为单位)。
13. **AnonPages**: 匿名页面的大小(以 KB 为单位),这是未映射到文件的内存页。
14. **Mapped**: 映射到文件的页面的大小(以 KB 为单位)。
15. **Shmem**: 共享内存的大小(以 KB 为单位)。
16. **Slab**: 内核数据结构缓存的大小(以 KB 为单位)。
17. **CommitLimit**: 内核允许分配的内存总量,即系统当前状态下,内存不会耗尽的极限值(以 KB 为单位)。
18. **Committed_AS**: 当前已经使用或保留的内存总量(以 KB 为单位)。
19. **VmallocTotal**: 虚拟内存总量(以 KB 为单位)。
20. **VmallocUsed**: 当前正在使用的虚拟内存大小(以 KB 为单位)。
21. **VmallocChunk**: 最大单块虚拟内存区域的大小(以 KB 为单位)。
这些字段提供了关于系统内存使用的详细信息,通过观察这些值,可以了解系统当前的内存状态,并进行性能分析和故障排除。这些值都是以 KB 为单位的整数。
`/proc/zoneinfo` 是 Linux 操作系统中的一个特殊文件,提供有关内核内存管理中不同内存区域(zone)的详细信息。每个物理内存节点都对应一个 `/proc/zoneinfo` 文件,其中包含了有关该节点内存区域的统计数据。以下是该文件的一些关键字段及其解释:
1. **Node**: 表示物理内存节点的标识符。
2. **Zone**: 表示内存区域的类型,常见的区域类型包括 `DMA`、`DMA32`、`Normal`、`HighMem` 等。
3. **Present**: 表示该内存区域的物理内存是否存在(1 表示存在,0 表示不存在)。
4. **Managed**: 表示内核是否管理该内存区域的页框(1 表示是,0 表示否)。
5. **Spanned**: 表示该内存区域的页框跨度(以页框为单位)。
6. **Present pages**: 表示该内存区域中当前存在的页框数量。
7. **NrFree**: 表示该内存区域中当前可用的空闲页框数量。
8. **NrInactive**: 表示该内存区域中当前不活跃(未被使用)的页框数量。
9. **NrActive**: 表示该内存区域中当前活跃(正在使用)的页框数量。
10. **NrUnevictable**: 表示该内存区域中当前不可被逐出(不可回收)的页框数量。
11. **NrMlock**: 表示该内存区域中当前被 mlock 锁定的页框数量。
12. **NrAnonPages**: 表示该内存区域中匿名页面(未映射到文件的页面)的数量。
13. **NrMapped**: 表示该内存区域中映射到文件的页面的数量。
14. **NrFilePages**: 表示该内存区域中属于文件缓存的页面的数量。
15. **NrDirty**: 表示该内存区域中当前被标记为脏页的数量。
16. **NrWriteback**: 表示该内存区域中当前正在被写回到磁盘的页面数量。
17. **NrSlab**: 表示该内存区域中 slab 分配器使用的页面数量。
18. **NrSReclaimable**: 表示该内存区域中可回收的 slab 页面数量。
19. **NrSUnreclaim**: 表示该内存区域中不可回收的 slab 页面数量。
这些字段提供了有关不同内存区域的详细信息,通过查看这些值,可以了解系统内存管理的细节,包括可用内存、活跃页、不活跃页、缓存页等。这对于进行性能分析和调优是非常有用的。这些值通常是以页面为单位的整数。
通过书中的介绍,笔者试着查询了自己电脑的信息。
当然!这本书为各位读者提供了深入而详细的关于 Linux 操作系统内存管理的信息,特别是 `/proc/meminfo` 和 `/proc/zoneinfo` 文件。这些是系统管理员和开发人员必须了解的关键概念,而该书似乎以清晰而易懂的方式呈现了这些复杂的主题。
通过讨论这两个文件,该书为读者提供了深入理解内核如何管理系统内存的工具。这种深度的探索对于解决内存性能问题、进行系统调优以及有效地利用系统资源都是至关重要的。
感谢这本书为笔者提供了有关 Linux 内存管理的详实信息,它对于理解和优化系统性能非常有价值的资源。笔者非常享受阅读的过程,并在之后的实践中应用这些宝贵的知识!
-
发表了主题帖:
一起读《奔跑吧Linux内核(第2版)卷1:基础架构》——什么是MMAP
`mmap` 是一种在UNIX和类UNIX系统中用于内存映射的系统调用。`mmap` 是 **memory map** 的缩写,它允许一个进程将文件的一部分或整个文件映射到其地址空间,而不需要实际地读取文件到内存中。这种技术使得文件的内容可以直接在内存中访问,而无需通过标准的读写操作。
`mmap` 函数通常用于在进程之间共享数据,因为它允许多个进程映射同一文件,从而实现数据共享。此外,`mmap` 还用于优化文件的访问,因为它可以避免不必要的数据复制和减少磁盘I/O。
一般而言,`mmap` 函数的原型如下:
```c
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
```
其中:
- `addr`:指定映射的起始地址,通常设置为 `NULL`,由系统决定。
- `length`:映射的长度,以字节为单位。
- `prot`:指定映射区域的保护方式,例如可读、可写、可执行等。
- `flags`:指定映射的类型,例如是共享映射还是私有映射。
- `fd`:文件描述符,表示要映射的文件。
- `offset`:文件中的偏移量,从该偏移量开始映射。
使用 `mmap` 可以更灵活地处理大文件,共享内存,以及实现一些高效的文件操作。但是需要注意使用时的一些细节,如适当的同步机制以防止数据冲突。
下面是一个简单的C语言代码示例,演示了如何使用`mmap`将文件映射到内存,并进行一些基本的读写操作:
```c
#include
#include
#include
#include
#include
#include
int main() {
const char *file_path = "example.txt";
int fd = open(file_path, O_RDWR | O_CREAT, (mode_t)0600);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// 获取文件大小
struct stat file_info;
if (fstat(fd, &file_info) == -1) {
perror("fstat");
close(fd);
exit(EXIT_FAILURE);
}
off_t file_size = file_info.st_size;
// 使用mmap将文件映射到内存
void *mapped_data = mmap(NULL, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (mapped_data == MAP_FAILED) {
perror("mmap");
close(fd);
exit(EXIT_FAILURE);
}
// 打印文件内容
printf("File content:\n%s\n", (char *)mapped_data);
// 修改文件内容
const char *new_content = "Hello, mmap!";
snprintf((char *)mapped_data, file_size, "%s", new_content);
printf("Updated content:\n%s\n", (char *)mapped_data);
// 解除内存映射
if (munmap(mapped_data, file_size) == -1) {
perror("munmap");
}
// 关闭文件
close(fd);
return 0;
}
```
这个例子假设存在一个名为 **example.txt** 的文件,程序首先打开该文件,然后使用 `mmap` 将文件内容映射到内存中。接着,程序打印文件内容,修改文件内容,并再次打印修改后的内容。最后,程序使用 `munmap` 解除内存映射,并关闭文件。
- 2024-01-06
-
发表了主题帖:
【米尔-TI AM62x开发板-试用评测】3.基本功能测试
# 【米尔-TI AM62x开发板-试用评测】3.基本功能测试
笔者手中拿到的是厂商邮寄过来的 **MYD-6231** 板卡,**ARM** 处理器规格 **AM6231,1*Cortex-A53@1GHz+Cortex-M4F@400MHz**
## 镜像烧录
首先将网盘下载的镜像解压
```bash
xz -dk myir-image-full-myd-am62x.wic.xz
```
烧录到 **SD** 卡,这速度太感人了,不到2秒烧录完,还是 **Ubuntu** 香啊。
```bash
sudo dd if=myir-image-full-myd-am62x.wic of=/dev/sda bs=4M
```
将 **SD** 卡插入到开发板的卡槽,上电开机。可以观察到蓝色的灯双闪烁,说明系统已经刷好了。
[localvideo]9e97f101155ac23e87f0c23ea0176acf[/localvideo]
另外接上网线,在路由器的后面查看开发板的IP地址。通过 **SSH** 连上开发板。
```bash
ssh root@192.168.124.30
```
## 测试核心资源
### CPU
查看 **CPU** 信息
```bash
cat /proc/cpuinfo
```
查看 **CPU** 使用率
```bash
top
```
获取 **CPU** 温度信息
```bash
cat /sys/class/thermal/thermal_zone0/temp
```
### Graphics
**YM6231** 没有 **GPU**,非常遗憾,测不了……
### Memory
查看内存信息
```bash
cat /proc/meminfo
```
获取内存使用率
```bash
free -m
```
### eMMC
查看 **eMMC** 容量
```bash
fdisk -l
```
查看 **eMMC** 分区信息
```bash
df -h
```
查看 **eMMC** 寿命
```bash
mmc extcsd read /dev/mmcblk0 | grep Life
```
## 外部接口测试
### LED
板载两颗蓝色 **LED** ,**D53** 和 **D54** ,默认情况是闪烁的。
首先将 **D53** 关闭
```bash
echo 0 > /sys/class/leds/am62-sk\:d53/brightness
```
接着再次开启 **D53**
```bash
echo 1 > /sys/class/leds/am62-sk\:d53/brightness
```
此时可以观察到,**D53** 常亮。
[localvideo]1691b6b07acbf069aaae9efb3a532a78[/localvideo]
简单写个 shell 脚本,实现流水灯效果
```shell
#!/bin/bash
LED1_PATH="/sys/class/leds/am62-sk:d53"
LED2_PATH="/sys/class/leds/am62-sk:d54"
BRIGHTNESS_PATH1="$LED1_PATH/brightness"
BRIGHTNESS_PATH2="$LED2_PATH/brightness"
while true; do
# 切换第一个 LED 的状态
echo "1" > "$BRIGHTNESS_PATH1"
sleep 0.5
echo "0" > "$BRIGHTNESS_PATH1"
# 切换第二个 LED 的状态
echo "1" > "$BRIGHTNESS_PATH2"
sleep 0.5
echo "0" > "$BRIGHTNESS_PATH2"
done
```
### 移动硬盘
将移动硬盘连接到开发板 **USB Host** 接口(**J16**),查看内核提示信息
```bash
dmesg
```
挂载设备
```bash
mount /dev/sda1 /mnt/
```
```txt
mount: /mnt: unknown filesystem type 'ntfs'.
```
挂载失败……这是因为硬盘文件格式是 **NTFS** ,需要后续给开发板安装相应的软件包才行。
下一篇尝试如何安装软件包……
- 2024-01-05
-
回复了主题帖:
阅读打卡第六站: 内存管理之实战案例分析 ——《奔跑吧Linux内核(第2版)卷1》
1. Linux内核的内存管理模块主要对以下几类页面进行统计:
- **活动页面(Active Pages)**:正在使用或者最近被使用过的页面。
- **非活动页面(Inactive Pages)**:最近没有被使用过的页面,但仍然在内存中,因为系统认为可能会再次被使用。
- **自由页面(Free Pages)**:完全空闲的页面,可以直接分配给新的数据。
- **缓冲区页面(Buffer Pages)**:被用作文件系统缓存的页面。
- **缓存页面(Cached Pages)**:被高速缓存子系统用来缓存块设备数据的页面。
- **不可交换页面(Unswappable Pages)**:不能被交换到磁盘上的页面。
- **可交换页面(Swappable Pages)**:可以被交换到磁盘上的页面。
2. `/proc/meminfo` 文件提供了有关系统内存使用情况的详细信息。以下是一些常见条目的含义:
- **MemTotal**:系统总内存大小。
- **MemFree**:未被使用的内存大小。
- **MemAvailable**:可用于新进程或文件系统缓存的内存大小。
- **Buffers**:用作块设备缓存的内存大小。
- **Cached**:用作页面缓存的内存大小。
- **SwapCached**:被交换到磁盘上的页面的大小。
- **Active**:正在使用的页面的大小。
- **Inactive**:最近未使用的页面的大小。
- **SwapTotal**:交换空间总大小。
- **SwapFree**:未被使用的交换空间大小。
3. `/proc/meminfo` 中的 `MemTotal` 不等于 QEMU 虚拟机中分配的内存大小可能是因为 QEMU 可能分配了更多的内存给虚拟机,包括一些用于虚拟化和管理的内存。此外,还有一些内核和系统使用的内存,不会被列在 `/proc/meminfo` 中的特定条目中。因此,虚拟机中分配的总内存可能包含一些不在 `/proc/meminfo` 中显示的其他内存开销。
- 2023-12-27
-
回复了主题帖:
阅读打卡第五站: 内存管理之不错主题 ——《奔跑吧Linux内核(第2版)卷1》
1. **_refcount和_mapcount的区别:**
- `_refcount`: 用于跟踪页面的引用计数,表示有多少个指针指向该页面。
- `_mapcount`: 用于跟踪页面在页表中的映射计数,表示有多少个页表项映射到该页面。
2. **匿名页面和高速缓存页面的区别:**
- **匿名页面:** 这是指不与文件关联的页面,通常用于进程的堆栈、匿名映射等。
- **高速缓存页面:** 这是指与文件关联的页面,从文件系统中读取数据,例如文件映射。
3. **trylock_page()和lock_page()的区别:**
- **trylock_page():** 尝试获取页面锁,如果获取成功返回真,否则立即返回假,而不会阻塞。
- **lock_page():** 获取页面锁,如果无法获取,则会阻塞直到锁可用。
4. **page数据结构中flags成员的布局示意图:**
```
+---------------------+
| flags |
+---------------------+
```
5. **_refcount和_mapcount计数的使用案例:**
- **_refcount使用案例:**
- 在内存管理中,通过引用计数来追踪页面的引用,确保在没有引用时可以释放页面。
- 在共享内存机制中,跟踪共享内存块的引用计数。
- **_mapcount使用案例:**
- 在分页系统中,用于跟踪页面在页表中的映射次数,以确保在不再映射时可以释放页面。
- 在内存映射文件时,跟踪页面在文件映射中的映射次数。
-
发表了主题帖:
【米尔-TI AM62x开发板-试用评测】2.部署SDK
# 【米尔-TI AM62x开发板-试用评测】2.部署SDK
看着另一个测评者 **i9** 编译源码和 **SDK** 都花了一整天,属实把我吓到了。想想我这3年前买的 **R5** 笔记本,估计是编译不来这么耗时长的代码了,所以我选择了百度网盘。在黑科技的加持下,很快网盘里的所有资源都在电脑上了。千兆宽带跑起来还是不需要一整天的。
我这边系统是 **Ubuntu 22.04** 的,那么官方文档推荐是 **Ubuntu 20.04**,倒也差异不是很大啦。
## 主机环境配置
安装编译链之前,需要安装一些必须的依赖,像`git` `gcc`这些。
### 更换清华源
更换不是必须的,如果你网络良好,那就不用换了。
打开清华大学开源软件镜像站:https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/ ,选择你的 ubuntu 版本,如 22.04,Ubuntu 的软件源配置文件是 /etc/apt/sources.list。
```txt
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu/ jammy-security main restricted universe multiverse
# deb-src http://security.ubuntu.com/ubuntu/ jammy-security main restricted universe multiverse
# 预发布软件源,不建议启用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse
# # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse
```
### 安装 SDK 必要工具
```bash
sudo apt-get update
```
要安装的依赖挺多的,可能需要等一会儿。
```bash
sudo apt-get -f -y install git build-essential \
diffstat texinfo gawk chrpath socat doxygen dos2unix python3 bison \
flex libssl-dev u-boot-tools mono-devel mono-complete curl lrzsz lzop \
python3-distutils pseudo python3-sphinx g++-multilib bc python3-pip \
libc6-dev-i386 jq git-lfs pigz zstd liblz4-tool cpio file autoconf automake \
xinetd tftpd nfs-kernel-server minicom libncurses5-dev dos2unix screen \
zstd lz4 python3-pyelftools python3-setuptools swig repo
```
```bash
sudo pip3 install jsonschema pyelftools
```
### 安装编译链
将大达 **1.7G** 的 `arago-2023.04-toolchain-2023.04.sh` 拷贝到工作目录,并执行
```bash
./arago-2023.04-toolchain-2023.04.sh
```
执行后会要你填安装目录,默认就好,记住在哪个位置。
初始化环境变量
```bash
source /media/clark/Data/Users/Documents/DevPCB/MYIR/MYMYD-YM62X/environment-setup-aarch64-oe-linux
```
测试SDK
```bash
$CC -v
```
## 镜像烧录
这个相对来说比较简单,将 `myir-image-full-myd-am62x` 解压成 `wic` 格式,然后使用 **Win32DiskImager** 烧录就行,建议选一张 **32G** 以上的 **SD** 卡。将 **SD** 卡插入到开发板,调整拨码开关为 **0001 001** ,上电开机即可。
|启动方式|B3:B4:B5:B6|B7:B8:B9|
|:-:|:-:|:-:|
|OSPI启动|0111|001|
|SD启动|0001|001|
|eMMC启动|1001|000|
笔者在拨码的时候,不小心拨成了 **0001 0001**,没想到也 **SD** 启动了。经过官方人员的解释,原来是拨错码的情况下,会尝试 **SD** 卡启动。给官方人员点赞,解答有耐心又及时。
## 开机展示
这个页面只有能到终端的入口,毕竟内存只有 **1G** ,装不了完整的图形化界面。鼠标拖动时,顿挫感很明显,不是很流畅。
## 感受
即使我这边省略了大部分时间,没有使用 **Yocto** ,还是赶紧有点复杂了,建个工程不容易啊。
- 2023-12-25
-
发表了主题帖:
【米尔-TI AM62x开发板-试用评测】1.迟到的开箱
# 【米尔-TI AM62x开发板-试用评测】1.迟到的开箱
最近学校期末,确实是有点忙,开箱报告姗姗来迟,非常的不好意思啊。
当从工作人员那边得知我通过了米尔的申请,非常的意外,非常的惊喜,感觉不可思议。一忙完,我就马不停蹄来赶帖子了。
## 开箱视频
[localvideo]02615bbffd91c42226551aa2b0544dad[/localvideo]
## 包装
米尔-TI AM62x开发板的包装非常令人印象深刻。盒子采用厚实的卡纸,印刷精美,展现了高品质的设计。
## 外观
开发板外观设计简洁大方。板载的各个接口和元件布局合理,易于使用。以下是一些外观特写:
- **正面照片**
- **背面照片**
## 规格
米尔-TI AM62x开发板的规格如下:
- 处理器:TI AM62x 处理器
- 存储:1GB + 8GB eMMC
- 接口:UARTx9、CAN-FDx3、I2Cx
6、SPIx4、GPMC、DPI+双通道 LVDS,最高 2K、ETHx2、OSPI、CSI、USB2.0x2 等
- 其他特性:采用 12V/2A 直流供电,支持 1080P 高清显示,支持 OpenGL 3.x/2.0/1.1、Vulkan 1.2 图形加速引擎
## 附件
开发板附带了一些有用的附件
- 电源适配器 12V/2A 电源及配件一个
- USB Type A 转 USB Type C 线一条
- 快速入门指南
- DC 转接头 5.5x2.1 female 转 5.5x1.7 male 一个
## 初次使用
首次使用米尔-TI AM62x开发板非常简单。只需连接12V/2A的电源和电视机,按照快速使用指南的步骤操作,即可开始体验。
可以看到示例程序左上角是可以看到鼠标的,但是操作鼠标没反应。
## 吐槽
快递没用顺丰,包装箱有点压瘪了……还好没损坏开发板。另一个这个开发板到时候需要退还,能不能将选配模块 MY-CAM003M MIPI 接口摄像头模块 MY-LVDS070C,7 寸 LVDS 触摸屏友达 19 寸工控屏 M190ETN01 一起寄来测评呢?
- 2023-12-18
-
回复了主题帖:
阅读打卡第四站: 物理内存与虚拟内存 ——《奔跑吧Linux内核(第2版)卷1》
1. **Linux内核中的页面分配器(page allocator)在理想情况下是如何分配连续物理页面的:**
- 当内核需要分配一定数量的页面时,它会尝试在系统的物理内存中找到一块连续的空闲内存。这通常是通过 Buddy 系统来管理的。
- Buddy 系统将内存划分为不同大小的块,每个块大小都是2的幂次方。当需要分配一定数量的页面时,页面分配器会寻找最小的可用块,并将其划分为所需大小的页面块。
- 如果找到了足够大的连续块,页面分配器将其标记为已用,并返回分配的页面的首地址。
- 如果找不到足够大的连续块,分配器可能会尝试合并相邻的空闲块,以满足分配请求。
2. **确定可以从哪些zone中分配内存的分配掩码(gfp_mask):**
- `gfp_mask` 是一个掩码,用于指定内存分配的一些属性。其中的 `__GFP_BITS_MASK` 部分包含了有关分配的 zone 信息。
- Zone 表示系统中内存的不同区域,通常包括 NORMAL、DMA、HIGHMEM 等。通过在 `gfp_mask` 中设置不同的标志位,可以指定允许从哪些 zone 中分配内存。例如,`GFP_DMA` 表示只能从 DMA 区域分配内存。
3. **页面分配器按照什么方向来扫描zone:**
- 页面分配器通常按照从高地址到低地址的方向来扫描 zone。这是因为在 32 位系统中,内核通常将低地址的内存留给用户空间,而将高地址的内存用于内核空间。
4. **为用户进程分配物理内存时,应该选用GFP_KERNEL还是GFP_HIGHUSER_MOVABLE:**
- 一般情况下,为用户进程分配物理内存时,应该选择 `GFP_KERNEL`。这是因为 `GFP_KERNEL` 表示内核常规的内存分配,适用于大多数内核模块和数据结构。
- `GFP_HIGHUSER_MOVABLE` 主要用于分配用户进程中的可移动内存,例如用于页交换或内存迁移。这个标志用于告诉页面分配器,内核希望尽量在可移动内存区域分配页面。通常,对于普通用户进程的一般内存分配,使用 `GFP_KERNEL` 是更合适的选择。
-
回复了主题帖:
阅读打卡第三站:内存管理之预备知识 ——《奔跑吧Linux内核(第2版)卷1》
1. **UMA(Uniform Memory Access)和NUMA(Non-Uniform Memory Access)的区别:**
- UMA:在UMA架构中,所有处理器对内存的访问时间是相同的,即内存对所有处理器都是均匀可访问的。这种结构适用于小型系统,其中处理器数量有限。
- NUMA:在NUMA架构中,处理器与内存之间的访问时间可能不同。系统中有多个节点(Node),每个节点有自己的本地内存,而访问本地内存的速度要快于访问远程节点的内存。NUMA适用于大型多处理器系统,其中处理器数量较多。
2. **CPU访问各级存储结构的速度是否一样?**
不同级别的存储结构访问速度是不同的。通常,从快到慢的顺序是:寄存器 > 缓存 > 内存 > 硬盘。寄存器位于CPU内部,速度最快,而硬盘则是机械式存储,速度相对较慢。因此,CPU访问寄存器的速度最快,而访问其他层次的存储结构速度逐渐降低。
3. **内存管理常用的数据结构关系图:**
```lua
+-------------+ +-------------+ +-------------+ +-------------+
| mm_struct | ------->| VMA || Page || PTE |
+-------------+ +-------------+ +-------------+ +-------------+
| | | |
| | | |
V V V V
+-------------+ +-------------+ +-------------+ +-------------+
| vaddr | | paddr | | PFN | | zone |
+-------------+ +-------------+ +-------------+ +-------------+
| |
V V
+-------------+ +-------------+
| pg_data | | ...
+-------------+ +-------------+
```
- **mm_struct(Memory Management Structure)**:表示一个进程的内存空间,包含该进程的所有VMA。
- **VMA(Virtual Memory Area)**:表示一个连续的虚拟内存区域,包含了一段地址范围及其属性。
- **vaddr(Virtual Address)**:虚拟地址,进程中使用的地址。
- **paddr(Physical Address)**:物理地址,实际硬件上的地址。
- **Page**:页,内存管理的最小单位。
- **PFN(Page Frame Number)**:页框号,用于标识内存中的页。
- **PTE(Page Table Entry)**:页表项,用于将虚拟地址映射到物理地址。
- **zone**:表示一块具有相似特性的物理内存。
- **pg_data**:表示一组内存页的集合,包括与该组相关的信息。
这些数据结构之间的转换关系涉及虚拟地址到物理地址的映射、页表的建立和管理,以及对内存的分区和管理。详细的转换关系取决于操作系统的实现和架构。
- 2023-12-06
-
回复了主题帖:
测评入围名单: 接力AM335x,米尔-TI AM62x开发板
个人信息无误,确认可以完成评测计划
- 2023-12-04
-
回复了主题帖:
阅读打卡第二站:ARM64在Linux内核中的实现——《奔跑吧Linux内核(第2版)卷1》
1. **ARM64处理器中的两个页表基地址寄存器TTBR0和TTBR1:**
- **TTBR0:** 用于用户态的页表基地址。
- **TTBR1:** 用于内核态的页表基地址。
处理器在运行时根据当前的运行模式(用户态或内核态)选择使用相应的寄存器。在用户态运行时,处理器使用TTBR0中的页表基地址来访问页表,而在内核态运行时,使用TTBR1中的页表基地址。
2. **ARM64处理器的4级页表映射过程:**
- **L0:** 位[47:39],512 GB的大页表。
- **L1:** 位[38:30],1 GB的大页表。
- **L2:** 位[29:21],2 MB的大页表。
- **L3:** 位[20:12],4 KB的页表。
地址位[47:39]决定L0页表项的索引,[38:30]决定L1页表项的索引,以此类推。每个级别的页表项包含下一级页表的基地址。通过递归地查找各级页表项,最终找到对应的物理页框。
3. **判断页表项是块类型还是页表类型:**
- 在L0~L2页表项中,可以通过检查描述符的一些位来确定是块类型还是页表类型。
- 对于块类型(大页表),一般会设置一个特定的标志位,例如在L1和L2级别,ARM64中的"Block"标志位(位1)用于指示块类型。
- 如果标志位设置为1,表示这个页表项是一个块,而不是指向下一级页表的地址。如果标志位为0,表示这是一个页表项,需要继续查找下一级页表。
4. **ARM64 Linux内核中的用户空间和内核空间划分:**
- ARM64采用了经典的Linux内核和用户空间分离的内存管理模型。
- 用户空间的虚拟地址范围通常在0x0000000000000000到0x00007fffffffffff,高47位为0。
- 内核空间的虚拟地址范围通常在0xffff800000000000到0xffffffffffffffff,高47位为1。
- 这样的划分允许内核和用户空间各自有独立的地址空间,提高了系统的稳定性和安全性。在ARM64上,这种分割是通过使用TTBR0和TTBR1寄存器来实现的。 TTBR0用于用户空间,而TTBR1用于内核空间。
- 2023-12-03
-
发表了主题帖:
一起读《奔跑吧Linux内核(第2版)卷1:基础架构》——初识
书籍印刷精美,排版清晰易读。插图、图表和代码展示工整有序,提升了学习体验。
纸质选择考究,质感上乘,为读者提供了高品质的阅读感受。
本书内容深入浅出,涵盖了处理器架构的方方面面,从基础知识到高级应用一应俱全。作者对于ARM64架构的详尽解读令人受益匪浅。是一本高质量、权威性强的学习参考书籍。
以下是笔者个人理解的读书笔记。目前笔者只阅读了第一章节,摘录部分内容如下。
**精简指令集和复杂指令集**
> 处理器架构可分为精简指令集(RISC)和复杂指令集(CISC)。RISC通过简化指令集提高执行速度,而CISC提供更复杂的指令集,有助于编程。
**高速缓存的工作方式**
> 高速缓存是提高处理器性能的关键组成部分,通过存储最常用的数据和指令,减少对主存的访问时间,提高数据读取速度。
**ARM的大/小核架构**
> ARM架构支持大/小核架构,实现高性能和低功耗的平衡。大核用于高性能任务,小核用于低功耗任务,实现灵活的处理器设计。
**ARMv8-A架构**
> ARMv8-A架构是ARM64架构的基础,支持64位指令集,提供更大的寻址空间和更高的性能。
**ARMv8架构中的基本概念**
> 引入了ARMv8中的基本概念,包括不对齐访问,处理器执行状态等,为理解后续章节奠定基础。
**函数调用标准和栈布局**
> 理解函数调用时寄存器的使用规范和栈的布局,对编写高效的汇编代码和理解程序运行过程有重要作用。
**ARM64异常处理**
> 异常类型、同步异常和异步异常的处理方式,了解异常发生后系统的响应和处理机制。
**总结**
通过学习本章节,深入理解了处理器架构的关键概念和技术。从基础的指令集和字节序到高级的异常处理和寄存器使用规范,本章节为深入掌握处理器架构提供了全面而系统的知识体系。对于从事系统级编程和嵌入式系统开发的人员,本书无疑是一本不可多得的参考资料。通过对ARM64架构的深入了解,笔者能够更好地优化代码,提高系统性能,并充分利用处理器的各种功能。
- 2023-11-29
-
回复了主题帖:
阅读打卡第一站:处理器架构——《奔跑吧Linux内核(第2版)卷1:基础架构》
1. **RISC和CISC的区别:**
- **RISC(Reduced Instruction Set Computing):**
- 简化指令集,指令长度一致。
- 指令执行时间相对较短。
- 采用硬件流水线,提高指令流水线效率。
- 通常具有更多通用寄存器。
- 指令以较低层次的操作为主,需要更多的指令完成同样的任务。
- **CISC(Complex Instruction Set Computing):**
- 复杂指令集,指令长度不一致。
- 单条指令可能执行多个低层次的操作,执行时间较长。
- 通常具有较少的通用寄存器。
- 可能包含一些复杂的指令,减少编程过程中的指令数目。
2. **大小端字节序处理器的存储方式:**
- 对于数值0x1234 5678:
- 大端字节序:0x12 0x34 0x56 0x78
- 小端字节序:0x78 0x56 0x34 0x12
3. **存储读写指令的执行全过程(以双核Cortex-A9为例):**
- 取指令(Instruction Fetch):从内存中读取指令。
- 指令译码(Instruction Decode):解释指令的含义。
- 执行(Execution):执行指令的操作,可能包括运算、数据传送等。
- 访存(Memory Access):如果涉及内存操作,进行读写内存。
- 写回(Write Back):将执行结果写回寄存器。
- 更新程序计数器(PC):指向下一条指令。
4. **内存屏障的产生原因:**
- 多核处理器中存在缓存一致性问题,不同核的缓存可能包含相同的数据,但数据更新时可能不同步。内存屏障用于指导编译器和处理器在代码中插入同步点,确保内存操作的顺序性和可见性。
5. **ARM的内存屏障指令:**
- ARM有三条内存屏障指令:DMB(Data Memory Barrier)、DSB(Data Synchronization Barrier)、ISB(Instruction Synchronization Barrier)。
- 区别在于它们对不同类型的数据访问和指令执行提供了不同级别的同步保障。
6. **高速缓存的工作方式:**
- 缓存存储频繁访问的数据,减少对主存的访问次数。
- 分为缓存行,每行包含多个字节。
- 缓存具有读取和写入操作,读取时检查缓存是否包含所需数据,写入时更新缓存并标记为脏(dirty)。
- 缓存采用替换算法,根据缓存映射方式确定替换规则。
7. **高速缓存映射方式:**
- **全关联(full-associative):** 允许任何主存块映射到任何缓存行。
- **直接映射(direct-mapping):** 每个主存块只能映射到一个特定的缓存行。
- **组相联(set-associative):** 介于全关联和直接映射之间,主存块映射到一组缓存行,选择替换时在该组内选择。
- **为什么使用组相联的高速缓存映射方式:**
- 组相联兼顾了全关联和直接映射的优点,减少了缓存冲突,提高了命中率。
- 更好地平衡了复杂性和性能,适应了多核处理器的需求,降低了替换开销。