SS928系统增加内存方式(解析U-Boot和DDR)(干货篇)
问题引入
前段时间在SS928中编译ROS的时候出现了内存不足的问题,想起来自己烧录的是8G+64G版本的固件,不应该出现这个问题呢?
使用free -h查看了系统可用内存,发现根本只有不到1G可用:
一一排查
有什么地方会影响到系统的可用内存呢?我们可以从硬件层面和软件层面来一步一步测试。首先我们使用的是SS928V100的开发板,支持的最大容量是8GB,也就是说我们的硬件层是支持8GB的。那么从软件层面入手,嵌入式arm板端Linux系统启动流程如下:
graph TD
subgraph SoC 内部芯片
A[电源开启] --> B(BootROM);
end
subgraph 引导加载程序 (Bootloader)
B --> |从 Flash/SD卡 加载| C[U-Boot SPL];
C --> |初始化DDR| D[U-Boot 主体];
end
subgraph 内核与用户空间
D --> |执行 bootcmd| E[加载 Linux 内核 (zImage)];
D --> |执行 bootcmd| F[加载设备树 (DTB)];
E & F --> G{启动内核};
G --> H[内核初始化硬件];
H --> I[挂载根文件系统 (RootFS)];
I --> J[执行第一个用户进程 /sbin/init];
J --> K[启动系统服务与应用];
end
BootROM是厂家编写的代码我们无法修改,于是接着进入U-Boot。U-Boot是引导加载程序,分为U-Boot SPL和U-Boot Proper两部分。
SPL是一个精简版的U-Boot运行在芯片内部的SRAM中,主要任务是初始化关键外设、DDR内存、加载BL3,并跳转到DDR中U-Boot Proper入口地址。U-Boot Proper首先进行前期板级初始化,首先会在DDR中初始化一些不需要直接写地址的硬件(通过固定寄存器访问的硬件)、为U-Boot规划重定位地址、初始化全局数据gd。接着开始重定位,将U-Boot整个代码段和数据段全部从DDR当前临时位置,拷贝到最终运行位置(通常是DDR的高端地址区域,为内核腾出低端地址空间)。然后进行后期初始化,初始化前期无法初始化的设备,如网络、USB等。
全部初始化完成后,U-Boot进入主循环。首先初始化环境变量,从默认的环境变量或持久化存储(如Flash上的环境变量分区)中加载环境变量。然后启动bootdelay,等待用户是否按下按键。按下按键中断后,用户进入U-Boot命令行界面,可以在里面查看内存、烧写镜像、修改环境变量等;如果没有按下按键,就执行bootcmd环境变量中定义的自动启动命令序列,通常包含load kernel(从存储设备(eMMC等)将操作系统内核镜像和设备树文件加载到DDR内存的指定位置)和booti/bootm(跳转到内核的入口地址,将设备树地址等信息传递给内核,最后将控制权彻底交接给操作系统)
学到更多后便出现了新的问题,内存、DDR到底是什么?我们使用free -h查看到的是什么内存呢?
首先DDR可以表示两个名词:DDR内存芯片和DDR协议。一个是物理实体(内存芯片),一个是通信协议(计算机系统如何与内存芯片通信的协议)。我们在上面提到的DDR都是指DDR内存芯片这一说法。
而上面说的内存,是指DDR内存芯片能存储的空间大小。而我们平时说的”这块板子的内存有多大“的意思,就是说这块板端DDR内存容量有多少。
而free -h查看到的,是:Linux 内核的内存管理子系统所识别和管理的、可供内核和应用程序使用的 DDR 内存空间的大小。(呼~)
回归问题
这样我们回到最开始的问题!我们使用free -h查看系统可用内存,发现只有900多MB,而我们硬件DDR内存空间却有整整8G。由我们刚刚学习到的知识,可以从U-Boot启动入手。
在SRAM中SPL进行了初始化DDR内存、Proper进行了重定位后,U-Boot会首先初始化环境变量。那么我们先看看这个环境变量中会不会有与内存相关的部分:
由于SS928死活进不了U-Boot命令行界面,我们就直接在Ubuntu系统里面查看U-Boot的环境变量。进入系统后通过这段命令可以查看U-Boot的环境变量:
fw_printenv
输出的内容如下:
arch=arm
baudrate=115200
board=ss928v100
board_name=ss928v100
bootargs=console=ttyAMA0,115200 clk_ignore_unused rw rootwait rootfstype=ext4 blkdevparts=mmcblk0:512K(uboot),512K(env),1M(logo),20M(kernel),-(rootfs)
bootcmd=setenv bootargs "mem=${os_mem_size} total_mem=${total_mem_size} ${bootargs} ${rootfs_devpart}";run logo_cmd;mmc read 0 ${kernel_addr} ${kernel_start} ${kernel_size};bootm ${kernel_addr}
bootdelay=1
buffer_addr=0x42000000
buffer_size=0x01000000
cpu=armv8
ethact=gmac0
import_addr=0x41000000
jpeg_addr=0x230000000
jpeg_emar_buf=0x234000000
jpeg_size=0x3e728
kernel_addr=0x50000000
kernel_size=0xA000
kernel_start=0x1000
logo_cmd=if test "${logo_show}" = "yes";then mmc read 0 ${jpeg_addr} 0x800 0x800;decjpg 0;setvobg 0 0x0;startvo 0 16 23;startvl 0 ${vobuf} 1920 0 0 1920 1080;fi;
logo_show=yes
os_mem_size=1024M
part_env=0x80000
part_kernel=0x1400000
part_logo=0x100000
part_uboot=0x80000
preboot=setenv part_num 0; setenv partcnt 0; setenv filesize 0; mmc partcnt 1; while test "${part_num}" -le "${partcnt}";do load mmc 1:${part_num} ${import_addr} /boot/env_append.txt; if test "${filesize}" != "0";then env import -t -r ${import_addr} ${filesize}; if test "${append_preboot}" != "";then run append_preboot; fi; exit 0; fi; setexpr part_num ${part_num} + 1; done;
rootfs_devpart=root=/dev/mmcblk0p5
soc=ss928v100
stderr=serial
stdin=serial
stdout=serial
total_mem_size=8G
vendor=vendor
verify=n
vobuf=0x238000000
我们来分块解释:
系统基本信息变量:
内存配置变量:
存储分区信息变量:
这些变量定义了 eMMC 或 SD 卡上的分区布局。
核心启动参数:bootargs
核心启动命令:bootcmd
bootcmd=setenv bootargs "mem=${os_mem_size} total_mem=${total_mem_size} ${bootargs} ${rootfs_devpart}";run logo_cmd;mmc read 0 ${kernel_addr} ${kernel_start} ${kernel_size};bootm ${kernel_addr}
能理解的部分我就不多说了,mmc read 0 ...是指从存储设备读取内核到内存(从MMC设备0的kernel_start开始读取kernel_size个扇区的内容,放到内存的 kernel_addr地址处),bootm ${kernel_addr}就是从内存地址为kernel_addr的位置启动Linux内核
其它功能变量:
功能脚本变量:
解决问题
我们从这个环境变量中就能看出,直接影响我们系统可用内存大小的部分,就是os_mem_size被设置为了1024M。我们将这个内存扩大为4G试试:
fw_setenv os_mem_size 4G
# 重启生效
reboot

可以看到我们成功扩大了内存!不过这里我们设置的4G为什么会少200M左右呢?其实我们刚刚也说过,在U-Boot启动系统的时候,bootcmd会把操作系统内核镜像和设备树传递给DDR,同时在海思这类多媒体SOC中会保留一部分内存:
在这里我们看到SOC确实提前预留了203M的内存,这正是我们缺少的那一部分~
- 分享
- 举报
暂无数据-
浏览量:3142次2025-04-19 17:47:49
-
浏览量:12730次2022-11-10 18:07:40
-
浏览量:1134次2024-09-13 17:34:13
-
浏览量:2274次2024-06-06 10:17:20
-
浏览量:5715次2024-03-14 14:15:25
-
浏览量:2082次2023-03-28 19:19:22
-
浏览量:1491次2025-04-16 17:12:31
-
浏览量:2423次2023-04-03 15:28:29
-
浏览量:2773次2023-04-03 15:51:40
-
浏览量:2209次2023-10-28 16:08:09
-
浏览量:2162次2023-03-28 19:37:31
-
浏览量:225次2025-10-17 17:05:21
-
浏览量:1377次2025-02-05 14:33:55
-
浏览量:7225次2023-03-17 19:33:35
-
浏览量:2423次2023-12-22 14:53:36
-
浏览量:1211次2023-09-09 13:40:42
-
浏览量:3604次2023-04-01 13:01:00
-
浏览量:2661次2022-12-13 16:59:00
-
浏览量:6631次2022-09-19 14:17:36
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
银河☆海然
微信支付举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明

微信扫码分享
QQ好友