{"id":43397141,"url":"https://github.com/dagargo/emu3fs","last_synced_at":"2026-02-02T14:39:13.247Z","repository":{"id":17337555,"uuid":"20108829","full_name":"dagargo/emu3fs","owner":"dagargo","description":"Linux kernel module for the E-Mu EIII and EIV sampler filesystems","archived":false,"fork":false,"pushed_at":"2025-01-22T11:27:55.000Z","size":223,"stargazers_count":24,"open_issues_count":0,"forks_count":3,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-01-22T12:28:24.797Z","etag":null,"topics":["filesystem","linux-kernel"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dagargo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-05-23T17:56:07.000Z","updated_at":"2025-01-22T11:27:58.000Z","dependencies_parsed_at":"2022-09-10T15:50:36.841Z","dependency_job_id":"aa0bfb65-a779-4f84-ba1e-d077c4804d67","html_url":"https://github.com/dagargo/emu3fs","commit_stats":null,"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"purl":"pkg:github/dagargo/emu3fs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dagargo%2Femu3fs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dagargo%2Femu3fs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dagargo%2Femu3fs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dagargo%2Femu3fs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dagargo","download_url":"https://codeload.github.com/dagargo/emu3fs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dagargo%2Femu3fs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29013186,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-02T12:48:30.580Z","status":"ssl_error","status_checked_at":"2026-02-02T12:46:38.384Z","response_time":58,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["filesystem","linux-kernel"],"created_at":"2026-02-02T14:39:12.498Z","updated_at":"2026-02-02T14:39:13.239Z","avatar_url":"https://github.com/dagargo.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# emu3fs\n\nemu3fs is a Linux kernel module that allows you to read from and write to block devices formatted as E-Mu EIII filesystem. The Emulator samplers using this filesystem are the EIII series, the ESI series (which belongs to the EIII series) and the EIV series.\n\nCurrently, it has been verified to work with CDs, Zip drives and SD cards (used with [SCSI2SD](http://www.codesrc.com/mediawiki/index.php/SCSI2SD) and limited to 14 GB because that is the biggest size supported by the ESI 3.02 OS).\n\n## Installation\n\nSimply run `make \u0026\u0026 sudo make install \u0026\u0026 sudo depmod`. Note that you will need the Linux kernel headers to compile the module.\n\nAs emu3fs is outside the kernel tree, the `master` branch should not be used when compiling. Instead, the tag matching the kernel version the module is going be compiled against to should be checked out. If there is not a tag for such version, the closest ones might work as the API could be the same. Fixes and improvements implemented later would not be available for prior tags.\n\n## Usage\n\nOnce the module is inserted into the kernel (you might use `sudo modprobe emu3_fs` for this), you can mount the devices. You have 2 options here.\n\n* Mount an EIII block device with `sudo mount -t emu3 device mountpoint`.\n\n* Mount an EIV block device with `sudo mount -t emu4 device mountpoint`.\n\nThere are no differences between these two filesystems at the structure level. The only difference is that the root node is either the first directory on disk or the root directory respectively. The reason behind this is that EIV series allow to have directories, or folders as they call it, at the root level while older devices only give the user access to the first directory. Hence, it is possible but no recommended to mount an EIII disk as an `emu4` or vice versa.\n\nIf the filesystem type is not provided, `emu3` is used as default.\n\nIf you get the error below, use the `-t` option.\n\n```\nNTFS signature is missing.\nFailed to mount '/dev/loop0': Invalid argument\nThe device '/dev/loop0' doesn't seem to have a valid NTFS.\nMaybe the wrong device is used? Or the whole disk instead of a\npartition (e.g. /dev/sda, not /dev/sda1)? Or the other way around?\n```\n\n### Mounting ISO images\n\nISO images can be accessed through loop devices. In this example, we are using the `loop0` device.\n\n```\n$ sudo losetup /dev/loop0 image\n```\n\n### Mounting CDs and other drives\n\nCDs need to be mounted through a loop device when the CD reader is not SCSI. This is due to the fact that the EIII filesystem uses a 512 B block size, which is allowed in SCSI drives, and non SCSI drives have usually a 2 KiB block size. Notice that this applies as well to other drives that are not capable of providing 512 B block size.\nIf you are using a 512 B block size capable drive, like the `/dev/cdrom`, just do the following and forget about the loop devices.\n\n```\n$ sudo mount -t emu3 /dev/cdrom mountpoint\n```\n\n### Mounting SCSI2SD partitions\n\nSCSI2SD does not store partition information on the card. Therefore, mounting the card only allows to see the first partition. Nevertheless, `losetup` allows to mount arbitraty portions of the card.\n\nFirst, we need to know the starting points of each partition, either from a SCSI2SD configuration file, or from SCI2SD itself through `sci2sd-util`.\n\nFor example, a 16GB card could be splitted in 4 portions, which would give 4 offsets: 0, 7733504, 15467008 and 23200512 sectors. In order to calculate the offset for the `losetup` command, offsets in bytes have either to be multiplied the sector number by 512 or divide it by 2 in order to have the offset in KiB.\n\nIn this example, that will be 0, 3866752K, 7733504K and 11600256K.\n\nNext, we need to know the first available /dev/loop.\n\n```\n$ losetup -f\n/dev/loop20\n```\n\nThen, we can create the loop devices for our partitions.\n\n```\n$ sudo losetup /dev/loop20 /dev/sdb\n$ sudo losetup -o 3866752K /dev/loop21 /dev/sdb\n$ sudo losetup -o 7733504K /dev/loop22 /dev/sdb\n$ sudo losetup -o 11600256K /dev/loop23 /dev/sdb\n```\n\nAnd, finally, can be mount the loop devices as usual.\n\n## Bank numbers\n\nThe bank number is part of the structure stored on the device but it is **not** a part of the name. When a file is created, the lowest bank number available is used; when a file is deleted, the bank number it was using becomes available.\n\nWhile any command line tool will work for listing the content, there is no way to show the bank number with any of them as it is not an stardard file attribute. However, it is an extended file attribute and, therefore, it is possible to read and write it with `getfattr` and `setfattr`.\n\nThis is how it works.\n\n```\n$ getfattr -d -m \".*\" *\n# file: 12 String Guitar\nuser.bank.number=\"31\"\n\n# file: 4 Piece Horns 4M\nuser.bank.number=\"8\"\n\n# file: E3 Main Code\nuser.bank.number=\"109\"\n[...]\n\n$ getfattr -n \"user.bank.number\" Textural\\ Strings\n# file: Textural Strings\nuser.bank.number=\"6\"\n\n$ setfattr -n \"user.bank.number\" -v \"99\" Textural\\ Strings\n\n$ getfattr -n \"user.bank.number\" Textural\\ Strings\n# file: Textural Strings\nuser.bank.number=\"99\"\n```\n\nKeep in mind that setting a bank number does **not** alter the remaining ones so attention must be paid for repeated numbers as devices will show **only** the first one they find for a given bank number.\n\nAlternatively, an `lsemu3` command could be defined as follows.\n\n```\n#!/bin/bash\n\nif [ $# -eq 0 ]; then\n  lsemu3 * .*\n  exit $?\nfi\n\nif [ $# -eq 1 ]  \u0026\u0026 [ \"$1\" == \"-s\" ]; then\n  lsemu3 * | sort\n  exit ${PIPESTATUS[0]}\nfi\n\nif [ $# -gt 1 ] \u0026\u0026 [ \"$1\" == \"-s\" ]; then\n  shift\n  lsemu3 \"$@\" | sort\n  exit ${PIPESTATUS[0]}\nfi\n\ne=0\nt=0\nfor f in \"$@\"; do\n  t=$((t + 1))\n  [ ! -e \"$f\" ] \u0026\u0026 echo \"'$f' does not exist\" \u003e\u00262 \u0026\u0026 e=$((e + 1)) \u0026\u0026 continue\n  if [ -f \"$f\" ]; then\n    bn=$(getfattr -d -m user.bank.number \"$f\" 2\u003e /dev/null | grep -v \"^#\" | awk -F\\\" '{print $2}');\n    if [ -n \"$bn\" ]; then\n      if [ $bn -lt 100 ]; then\n        bn=$(printf \" B%02d \" $bn)\n      else\n        bn=$(printf \".%3d \" $bn)\n      fi\n    else\n      bn=\"F\"\n    fi\n  elif [ -d \"$f\" ]; then\n    bn=\"D\"\n  else\n    bn=\"?\"\n  fi\n\n  i=$(stat --printf=\"%i\" \"$f\")\n  s=$(stat --printf=\"%s\" \"$f\")\n  if [ $s -gt 1024 ]; then\n    s=$((s / 1024))\n    if [ $s -gt 1024 ]; then\n      s=$((s / 1024))M\n    else\n      s=${s}K\n    fi\n  else\n    s=${s}B\n  fi\n  printf \"%4s %9s %6s '$f'\\n\" $bn $i \"$s\"\ndone\n\n[ $e -gt 0 ] \u0026\u0026 [ $e -eq $t ] \u0026\u0026 exit 1\nexit 0\n```\n\nThis is how it works. The `-s` option sorts them by bank number and the second and third columns are the inode and the size respectively.\n\n```\n$ lsemu3 -s\n B00         5        1K 'E-mu Banks 1-44'\n B01         4        3M 'Full Arco String'\n B02         6        4M 'SecViolinTrils4M'\n B03         7        8M 'SecViolinTrils8M'\n B04         8        2M 'Solo Violin'\n[...]\n B42        46        3M 'StereoGrandPiano'\n B43        47        3M 'Flautas Bonita'\n B44        48        3M 'Tenor Sax'\n B99        10        3M 'Textural Strings'\n.109         3       64K 'E3 Main Code'\n```\n\nThis helps to detect banks with the same number and it is useful when reordering banks. Files with bank number greater or equal than 100 are not considered banks but they are still there.\n\n## About repeated filenames\n\nRemember that although Unix does **not allow** files with the same name in the same directory, the samplers **do allow** this and thus some commands might seem to behave strangely so try to avoid this scenario. In Unix, paths are unique and point to a single inode.\n\n```\nDefault Folder$ $ ls -li\ntotal 32\n4 -rw-r--r-- 1 user user 10738 ago 30 19:54 'Untitled Bank'\n4 -rw-r--r-- 1 user user 10738 ago 30 19:54 'Untitled Bank'\n4 -rw-r--r-- 1 user user 10738 ago 30 19:54 'Untitled Bank'\n```\n\nListing the bank number does not work either.\n\n```\nDefault Folder$ lsemu3\n B00     4     10738 'Untitled Bank'\n B00     4     10738 'Untitled Bank'\n B00     4     10738 'Untitled Bank'\n```\n\nHowever, it can be addressed easily although you still can not tell them apart.\n\n```\nDefault Folder$ mv Untitled\\ Bank Untitled\\ Bank\\ 2\n\nDefault Folder$ ls -li\ntotal 32\n5 -rw-r--r-- 1 user user 10738 ago 30 19:55 'Untitled Bank'\n5 -rw-r--r-- 1 user user 10738 ago 30 19:55 'Untitled Bank'\n4 -rw-r--r-- 1 user user 10738 ago 30 19:54 'Untitled Bank 2'\n\nDefault Folder$ mv Untitled\\ Bank Untitled\\ Bank\\ 3\n\nDefault Folder$ ls -li\ntotal 32\n6 -rw-r--r-- 1 user user 10738 ago 30 20:56 'Untitled Bank'\n5 -rw-r--r-- 1 user user 10738 ago 30 19:55 'Untitled Bank 2'\n4 -rw-r--r-- 1 user user 10738 ago 30 19:54 'Untitled Bank 3'\n\nDefault Folder$ lsemu3 -s\n B00     4     10738 'Untitled Bank 2'\n B01     5     10738 'Untitled Bank 3'\n B02     6     10738 'Untitled Bank'\n```\n\n## Testing\n\nYou can run some simple tests from the `tests` directory. The script mounts a clean image and run some commands on it. **Be aware that you will be asked for the root password** because some commands like `mount` requiere this.\n\n\n```\n$ ./tests.sh\n```\n\n## Related project\n\n[emu3bm](https://github.com/dagargo/emu3bm) is a EIII and EIV bank manager that allows a basic edition of presets and sample export and import.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdagargo%2Femu3fs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdagargo%2Femu3fs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdagargo%2Femu3fs/lists"}