Home > Linux > Using a memory stick/memory card as swap memory on Linux

Using a memory stick/memory card as swap memory on Linux

My Lenovo T61 has a SD memory card slot.
So I thought why not use it as an “extention” of my memory.
I bought a cheap 4GB SD card and plugged it in there. Created some swap space on it and extended my memory with an additional 4Gb.
It’s not as quick as normal memory, but is quicker than swapping in and out from disk.
NOTE: From what I’m told, your normal SD card/USB stick isn’t really made for this kind of constant reading/writing, so don’t be surprised if it fails spectacularly without warning.
Update: After testing this for a while, I’ve concluded that it doesn’t work very well.
– If you’ve been working for a while and want to shutdown and go you wait forever for the memory card to flush to disk.
– When using another USB device it seems to slow down the card access, which slows down your machine’s responsiveness.

If you still want to try it for yourself here’s how it’s done:
I’m running OpenSuse 11.3, but these commands should be applicable to most Linux’s.

Creating the swap space

1. Insert your memory stick and check the dmesg output for the device name

SD would be something like mmcblk0 or sdd in the case of a usb stick

[  897.665998] mmc0: new high speed SDHC card at address b368
[  897.666029] mmc mmc0:b368: parent mmc0 should not be sleeping
[  897.666139] mmcblk0: mmc0:b368 NCard 3.78 GiB
[  897.666199]  mmcblk0: p1

[62557.294073] usb 2-1: new high speed USB device using ehci_hcd and address 2
[62557.412218] usb 2-1: New USB device found, idVendor=1307, idProduct=0163
[62557.412229] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[62557.412235] usb 2-1: Product: USB Mass Storage Device
[62557.412239] usb 2-1: Manufacturer: USBest Technology
[62557.412243] usb 2-1: SerialNumber: 00000000000123
[62557.412397] usb 2-1: configuration #1 chosen from 1 choice
[62557.412839] scsi5 : SCSI emulation for USB Mass Storage devices
[62557.413591] usb-storage: device found at 2
[62557.413594] usb-storage: waiting for device to settle before scanning
[62558.415235] scsi 5:0:0:0: Direct-Access     Ut163    USB2FlashStorage 0.00 PQ: 0 ANSI: 2
[62558.416738] sd 5:0:0:0: Attached scsi generic sg2 type 0
[62558.417186] usb-storage: device scan complete
[62558.434349] sd 5:0:0:0: [sdb] 1998847 512-byte logical blocks: (1.02 GB/975 MiB)
[62558.435220] sd 5:0:0:0: [sdb] Write Protect is off
[62558.435226] sd 5:0:0:0: [sdb] Mode Sense: 00 00 00 00
[62558.435228] sd 5:0:0:0: [sdb] Assuming drive cache: write through
[62558.445193] sd 5:0:0:0: [sdb] Assuming drive cache: write through
[62558.445211]  sdb: sdb1


2. Create a swap partition

Note: You could create a normal partition and swap file using dd, but that will add overhead, so I opted for a “raw” swap partition.

# fdisk /dev/mmcblk1
or
# fdisk /dev/sdb

Command (m for help): p

Disk /dev/sdb: 1023 MB, 1023409664 bytes
255 heads, 63 sectors/track, 124 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x91f72d24

Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1         124      995998+  82  Linux swap / Solaris

Command (m for help): d
Selected partition 1

Command (m for help): n
Command action
e   extended
p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-124, default 1):
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-124, default 124):
Using default value 124

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): L

0  Empty           24  NEC DOS         81  Minix / old Lin bf  Solaris
1  FAT12           39  Plan 9          82  Linux swap / So c1  DRDOS/sec (FAT-
2  XENIX root      3c  PartitionMagic  83  Linux           c4  DRDOS/sec (FAT-
3  XENIX usr       40  Venix 80286     84  OS/2 hidden C:  c6  DRDOS/sec (FAT-
4  FAT16 <32M      41  PPC PReP Boot   85  Linux extended  c7  Syrinx
5  Extended        42  SFS             86  NTFS volume set da  Non-FS data
6  FAT16           4d  QNX4.x          87  NTFS volume set db  CP/M / CTOS / .
7  HPFS/NTFS       4e  QNX4.x 2nd part 88  Linux plaintext de  Dell Utility
8  AIX             4f  QNX4.x 3rd part 8e  Linux LVM       df  BootIt
9  AIX bootable    50  OnTrack DM      93  Amoeba          e1  DOS access
a  OS/2 Boot Manag 51  OnTrack DM6 Aux 94  Amoeba BBT      e3  DOS R/O
b  W95 FAT32       52  CP/M            9f  BSD/OS          e4  SpeedStor
c  W95 FAT32 (LBA) 53  OnTrack DM6 Aux a0  IBM Thinkpad hi eb  BeOS fs
e  W95 FAT16 (LBA) 54  OnTrackDM6      a5  FreeBSD         ee  GPT
f  W95 Ext'd (LBA) 55  EZ-Drive        a6  OpenBSD         ef  EFI (FAT-12/16/
10  OPUS            56  Golden Bow      a7  NeXTSTEP        f0  Linux/PA-RISC b
11  Hidden FAT12    5c  Priam Edisk     a8  Darwin UFS      f1  SpeedStor
12  Compaq diagnost 61  SpeedStor       a9  NetBSD          f4  SpeedStor
14  Hidden FAT16 <3 63  GNU HURD or Sys ab  Darwin boot     f2  DOS secondary
16  Hidden FAT16    64  Novell Netware  af  HFS / HFS+      fb  VMware VMFS
17  Hidden HPFS/NTF 65  Novell Netware  b7  BSDI fs         fc  VMware VMKCORE
18  AST SmartSleep  70  DiskSecure Mult b8  BSDI swap       fd  Linux raid auto
1b  Hidden W95 FAT3 75  PC/IX           bb  Boot Wizard hid fe  LANstep
1c  Hidden W95 FAT3 80  Old Minix       be  Solaris boot    ff  BBT
1e  Hidden W95 FAT1
Hex code (type L to list codes): 82
Changed system type of partition 1 to 82 (Linux swap / Solaris)

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
bullfrog:~ # fdisk -l /dev/sdb

Disk /dev/sdb: 1023 MB, 1023409664 bytes
255 heads, 63 sectors/track, 124 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x91f72d24

Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1         124      995998+  82  Linux swap / Solaris

3. Create the swap space using mkswap

bullfrog:~ # mkswap /dev/sdb1
mkswap: /dev/sdb1: warning: don't erase bootbits sectors
(DOS partition table detected). Use -f to force.
Setting up swapspace version 1, size = 995992 KiB
no label, UUID=797057c3-6dda-4eac-97e6-72137b68d300
bullfrog:~ # mkswap -f /dev/sdb1
Setting up swapspace version 1, size = 995992 KiB
no label, UUID=d2749570-d59c-4403-85bf-df881bf2393a

4. Enable the swap space

# swapon -p 1 /dev/sdb1

# swapon -s
Filename                                Type            Size    Used    Priority
/dev/sda6                               partition       2041160 0       -1
/dev/mmcblk0p1                          partition       3963840 62088   1
/dev/sdb1                               partition       995988  0       -2

5. That’s it.


Removing the swap space

NOTE: It’s VERY important to remove the swap space before you remove the memory stick. Failing to do so will crash your system and cause data loss.

Use the swapoff command to diable/remove swap space

bullfrog:~ # swapon -s
Filename                                Type            Size    Used    Priority
/dev/sda6                               partition       2041160 0       -1
/dev/mmcblk0p1                          partition       3963840 62084   1
/dev/sdb1                               partition       995988  0       -2
bullfrog:~ # swapoff /dev/sdb1
bullfrog:~ # swapon -s
Filename                                Type            Size    Used    Priority
/dev/sda6                               partition       2041160 0       -1
/dev/mmcblk0p1                          partition       3963840 62084   1

Suspend your machine with the card still in

If you suspend you laptop with the memory card still in won’t resume properly.
In my case I lost all my programs and data after the resume.
This is probably due to the usb devices being started after the os did.
So you can try and remember to run swapoff/swapon every time you suspend (Yeah right!) or script it.
OpenSuse uses pm-utils to take care of suspend-to-ram and disk (http://en.opensuse.org/Pm-utils)
All we need to do is add a little script as part of the suspend/resume process and all will be well.

Add the following code to a file in /etc/pm/sleep.d. Replacing /dev/mmcblk0p1 with the partition you created above, eg. /dev/sdb1
e.g. /etc/pm/sleep.d./11mmcswap (Is the 11 correct? Not sure, but it works)

#!/bin/bash
case $1 in
hibernate)
echo "Turning off sdcard swap"
swapoff /dev/mmcblk0p1
;;
suspend)
echo "Turning off sdcard swap"
swapoff /dev/mmcblk0p1
;;
thaw)
echo "Turning on sdcard swap"
swapon -p 1 /dev/mmcblk0p1
;;
resume)
echo "Turning on sdcard swap"
swapon -p 1 /dev/mmcblk0p1
;;
*)  echo "somebody is calling me totally wrong."
;;
esac

You can now suspend and resume.

To check if this works properly have a look at the log file for suspend in
/var/log/pm-suspend.log

You should see the following lines:

===== 2010-02-09 16:01:15.110058316 running hook: /etc/pm/sleep.d/11mmcswap =====
Turning off sdcard swap
......
===== 2010-02-09 16:01:38.641029946 running hook: /etc/pm/sleep.d/11mmcswap =====
Turning on sdcard swap
Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: