Guide to add zRAM on the Synology DiskStation DS212j

My Synology DiskStation DS212j has gotten slower over the years ever since I bought in 2012. DSM operating system security and software upgrades introduced feature bloat that required more memory and caused memory to page to disk. Wikipedia gives an amazing overview of why paging is bad and why zRAM is amazing for memory constrained PCs.

zram (also called zRAM and, initially, compcache) is a Linux kernel feature that provides a form of virtual memory compression. zram increases performance by avoiding paging to disk and using a compressed block device in RAM instead, inside which paging takes place until it is necessary to use the swap space on a hard disk drive. Since using zram is an alternative way to provide swapping on RAM, zram allows Linux to make a better use of RAM when swapping/paging is required, especially on older computers with less RAM installed.

Pretty cool, huh? The Android community often uses zRAM as a way to bring back older devices back to life and I figured I could do the same with my aging DiskStation that only came with 256MB of RAM compared to the more recent DS216 that comes with twice that at 512MB.

I successfully compiled and added the zRAM module to my DS212j and wanted to share the steps. My DS212j uses the Linux kernel 2.6.32 so this guide should be applicable to any Synology DS that uses the same kernel.


Setting up the DSM 6.1 Tool Chain

Synology has provided excellent documentation on how to compile kernel modules. You should follow their tutorial on how to setup the toolkit to compile the kernel.

Steps for the DS212j are roughly:

  1. Setup toolkit:
    mkdir -p /toolkit
    cd /toolkit
    git clone https://github.com/SynologyOpenSource/pkgscripts-ng.git
    cd /toolkit/pkgscripts-ng/
    ./EnvDeploy -v 6.1 -p 6281

Compiling the 2.6.32 Kernel

You will need to follow the Synology documentation to compile kernel modules here in order to build the LZO kernel module. This is a dependent kernel module for zRAM.

Steps are roughly:

  1. Download the kernel source for the closest branch that is currently deployed on your Synology: https://sourceforge.net/projects/dsgpl/files/Synology%20NAS%20GPL%20Source/

  2. Extract the source to /toolkit/build_env/ds.x64-6.1/root/

  3. Enter the tool chain chroot:

    chroot /toolkit/build_env/ds.x64-6.1 /bin/bash
    cd root/linux-2.6.32
    cp synoconfigs/88f6281 .config
    export ARCH="arm"
    export CROSS_COMPILE="/usr/local/arm-marvell-linux-gnueabi/bin/arm-marvell-linux-gnueabi-"
    make oldconfig
    make menuconfig

  4. Build LZO modules because they’re dependencies for zRAM.
    Enter Cryptographic API to select LZO compression algorithm as a module. Exit and save.

  5. make prepare
    make modules

  6. Copy lzo_compress.ko, lzo_decompress.ko, lzo.ko to your Synology

Compiling the Compcache Kernel Module

I have successfully compiled the Compcache 0.6.2 kernel module and gotten it to work with the stock 2.6.32 kernel. The latest version doesn’t seem to work so we’re going to stick with 0.6.2 where we will follow the Compcache documentation here.

  1. cd /root/
  2. Download Compcache 0.6.2 module source:
    wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/compcache/compcache-0.6.2.tar.gz
    tar -xzf compcache-0.6.2.tar.gz
    cd compcache-0.6.2
    export KERNEL_BUILD_PATH=/root/linux-2.6.32
    make
  3. Copy ramzswap.ko to your Synology

Installation

  1. Copy kernel modules to Synology DSM

  2. Test kernels by inserting them

  3. /sbin/insmod /lib/modules/lzo_decompress.ko
    /sbin/insmod /lib/modules/lzo_compress.ko
    /sbin/insmod /lib/modules/lzo.ko
    /sbin/insmod /lib/modules/ramzswap.ko disksize_kb=131072
    /sbin/swapon /dev/ramzswap0 -p 5
  4. Enable swap with:

    /sbin/swapon /dev/ramzswap0 -p 5

  5. Verify everything worked by checking dmesg for errors
    nschimme@NilsDiskStation:~$ dmesg | grep -E "(ramzswap|lzo)"
    [ 100.500000] alg: No test for lzo (lzo-generic)
    [ 100.550000] ramzswap: num_devices not specified. Using default: 1
    [ 100.550000] ramzswap: /dev/ramzswap0 initialized: disksize_kb=131072
    [ 100.560000] ramzswap: Invalid ioctl 21297
    [ 101.560000] Adding 131064k swap on /dev/ramzswap0. Priority:5 extents:1 across:131064k SS
    nschimme@NilsDiskStation:~$
  6. Add above insmod/swapon commands to /etc/rc.local to make the changes permanent

zRAM Results

It’s super effective! I’ve noticed that there was roughly ~100MB of paged memory usually and I’ve managed to get it all to fit within ~30MB of compressed memory space rather than going down to the hard drive. Responsiveness in the DSM OS has greatly improved as a result.

nschimme@NilsDiskStation:~$ free -m
total        used        free      shared  buff/cache   available
              total        used        free      shared  buff/cache   available
Mem:            243          79          60           3         104         123
Swap:          2175          94        2081
nschimme@NilsDiskStation:~$ swapon
NAME           TYPE      SIZE  USED PRIO
/dev/md1       partition   2G    0B   -1
/dev/ramzswap0 partition 128M 94.9M    5
nschimme@NilsDiskStation:~$ sudo rzscontrol /dev/ramzswap0 --stats
DiskSize:	  131072 kB
NumReads:	    9890
NumWrites:	   26730
FailedReads:	       0
FailedWrites:	       0
InvalidIO:	       0
NotifyFree:	       0
ZeroPages:	    7231
GoodCompress:	      78 %
NoCompress:	       2 %
PagesStored:	   19499
PagesUsed:	    6640
OrigDataSize:	   77996 kB
ComprDataSize:	   26200 kB
MemUsedTotal:	   26560 kB
nschimme@NilsDiskStation:~$