Jetson Nano swap的扩展方法(2020新)【日积月累计划】

Jetson Nano swap扩展

最近在研究摄像头加速技术,终于捡起了一年半不用的jetson nano。一年半前jetson nano很不友好,经常崩溃。现在稳定一点。目前还是仅支持ubuntu18.5.0.这几天尝试用,体验很差,饶了很多弯路。nano提供了两钟(或者三种)升级方案,一种是sd卡烧写,一种是sdkmanager。最找尝试TK1的时候,用sdkmanager,满身伤痕。这次也是因为sdkmanager。总之因为系统的种种问题和配置的问题导致了体验很差,如果不是有良好的心理准备和迎难而上的态度,可能很难深入玩耍。
好了话不多说,进入正题:扩展swap区域。
本文章虽是作者原创,但解决方法来自此处:resizeSwapMemory
在开始之前,先说明一点。我用的是A0版本,不是最新的B0版本。但软件应该区别不大。目前使用的是jetpack4.4.1,系统版本是ubuntu18.04.05 LTS.

1. 改变

如果你使用free -h查看会发现,系统有4G空间,却只有1.9G左右的swap。网上有一堆教程,大多是重新创建swapfile的。个人感觉方法不够优雅,而且有隐患。这里的方法是修改系统原来用来创建swap的方法,从而扩展1.9G到6G或者更大。我这里按照惯例,分2倍内存大小。

2. 分析

要修改扩展就需要了解之前官方镜像是怎么实现的。
官方使用的是zram的方法,另一种常用的方法是disk partition的方式。这两种方法可以自行搜索。这里转载一段内容:

Zram Swap 是 Linux 内核中采用时间换空间的一种技术。它通过压缩内存(Zram)来作为交换分区,通过压缩比来获取更多可利用的内存空间。该技术目前在各类内存受限的嵌入式系统中,尤其是 Android 手机、电视等设备上广泛采用,本文对此进行了详细介绍。
zram: 是把物理内存的一部分划分出来,把不是常用的内存数据压缩后放到zram里, 用到的时候把数据解压出来, 相当于牺牲了一些cpu效率,变相增大了内存。
磁盘 swap:是把磁盘的一部分作为内存, 对应用来说完全是透明的,相当与增大了内存, 但是缺点很明显, 当用到swap的时候,速度会变的很慢。

之前的很多方法就是上文说的磁盘swap(磁盘分区disk partition)的方式。

可以使用sudo fdisk -l查看分区情况,比如现在的jetson nano是这样的:

jetson@jetson-desktop:~/Workspace$ sudo fdisk -l
[sudo] password for jetson:
Disk /dev/ram0: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/ram1: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/ram2: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/ram3: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/ram4: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/ram5: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/ram6: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/ram7: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/ram8: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/ram9: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/ram10: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/ram11: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/ram12: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/ram13: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/ram14: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/ram15: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/loop0: 16 MiB, 16777216 bytes, 32768 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000


Disk /dev/mtdblock0: 4 MiB, 4194304 bytes, 8192 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/mmcblk0: 59.5 GiB, 63864569856 bytes, 124735488 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 6FD14DA8-D37D-4BC5-B42A-C552EF857A6E

Device          Start       End   Sectors  Size Type
/dev/mmcblk0p1   7624 124734919 124727296 59.5G Microsoft basic data
/dev/mmcblk0p2     34       289       256  128K Microsoft basic data
/dev/mmcblk0p3    290      1185       896  448K Microsoft basic data
/dev/mmcblk0p4   1186      2337      1152  576K Microsoft basic data
/dev/mmcblk0p5   2338      2465       128   64K Microsoft basic data
/dev/mmcblk0p6   2466      2849       384  192K Microsoft basic data
/dev/mmcblk0p7   2850      3617       768  384K Microsoft basic data
/dev/mmcblk0p8   3618      3745       128   64K Microsoft basic data
/dev/mmcblk0p9   3746      4641       896  448K Microsoft basic data
/dev/mmcblk0p10  4642      5537       896  448K Microsoft basic data
/dev/mmcblk0p11  5538      7073      1536  768K Microsoft basic data
/dev/mmcblk0p12  7074      7201       128   64K Microsoft basic data
/dev/mmcblk0p13  7202      7361       160   80K Microsoft basic data
/dev/mmcblk0p14  7362      7617       256  128K Microsoft basic data

Partition table entries are not in disk order.


Disk /dev/zram0: 494.5 MiB, 518537216 bytes, 126596 sectors
Units: sectors of 1 * 4096 = 4096 bytes
Sector size (logical/physical): 4096 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/zram1: 494.5 MiB, 518537216 bytes, 126596 sectors
Units: sectors of 1 * 4096 = 4096 bytes
Sector size (logical/physical): 4096 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/zram2: 494.5 MiB, 518537216 bytes, 126596 sectors
Units: sectors of 1 * 4096 = 4096 bytes
Sector size (logical/physical): 4096 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes


Disk /dev/zram3: 494.5 MiB, 518537216 bytes, 126596 sectors
Units: sectors of 1 * 4096 = 4096 bytes
Sector size (logical/physical): 4096 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes

在上面输出的最后你可以看到我的64G磁盘中有个4段zram分别是zram0~3.可以使用zramctl来很方便的查看:

jetson@jetson-desktop:~/Workspace$ zramctl
NAME       ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram3 lzo         494.5M   4K   76B   12K       4 [SWAP]
/dev/zram2 lzo         494.5M   4K   76B   12K       4 [SWAP]
/dev/zram1 lzo         494.5M   4K   76B   12K       4 [SWAP]
/dev/zram0 lzo         494.5M   4K   76B   12K       4 [SWAP]

和上面类似,可以看到每块都是494.5M分区。按照Jetsonhacks的说法是按照下列公式划分的:

mem=$((("${totalmem}" / 2 / "${NRDEVICES}") * 1024))

而这段公式定义在 /etc/systemd/nvzramconfig.sh文件中。文件很短,我们来看看吧:

#!/bin/bash
#
# Copyright (c) 2019, NVIDIA CORPORATION.  All rights reserved.
#

NRDEVICES=$(grep -c ^processor /proc/cpuinfo | sed 's/^0$/1/')
if modinfo zram | grep -q ' zram_num_devices:' 2>/dev/null; then
        MODPROBE_ARGS="zram_num_devices=${NRDEVICES}"
elif modinfo zram | grep -q ' num_devices:' 2>/dev/null; then
        MODPROBE_ARGS="num_devices=${NRDEVICES}"
else
        exit 1
fi
modprobe zram "${MODPROBE_ARGS}"

# Calculate memory to use for zram (1/2 of ram)
totalmem=`LC_ALL=C free | grep -e "^Mem:" | sed -e 's/^Mem: *//' -e 's/  *.*//'`
mem=$((("${totalmem}" / 2 / "${NRDEVICES}") * 1024))

# initialize the devices
for i in $(seq "${NRDEVICES}"); do
        DEVNUMBER=$((i - 1))
        echo "${mem}" > /sys/block/zram"${DEVNUMBER}"/disksize
        mkswap /dev/zram"${DEVNUMBER}"
        swapon -p 5 /dev/zram"${DEVNUMBER}"
done

其中NRDEVICES是CPU核心数4,totalmem是内存大小。根据上面的公司可以算出:
mem = (4051068 / 2 / 4)*1024.
乘上1024是为了把4051068的单位K编程byte。所以结果是494.51513671875M。
和输出结果一致。那么聪明的你当然想到了解决办法。

方案

修改公式将/2变为乘以2,这样内存就扩大到了每个区2G,共8G。当然你也可以选择倍数是1.5(注意,你需要先乘3再除以2.我没测试过小数).

# 打开zram文件
sudo vim /etc/systemd/nvzramconfig.sh
# 修改第18行公式为
mem=$((("${totalmem}" * 2 / "${NRDEVICES}") * 1024))
# 保存文件,重启电脑
sudo reboot
free -h

总接

Jetsonhacks的方法更加方便用户操作,但是其实原理很简单,就是将新的文件替换老的文件。我们可以用更直接的方法来替换公式。
感谢Jetsonhacks。

One More Thing

jetson nano的vnc很难用。与raspberry pi的体验差了很多。不建议使用。
另外不建议使用简陋的lightDM桌面。当不需要X桌面时,可以考虑完全关闭。
没有很好的磁盘备份软件,我准备下一步接用rpi-clone项目,做一个jetson-clone工程。敬请期待。多谢。

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值