├── LICENSE ├── README.md └── mkfs.cursed /LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cursedfs 2 | 3 | Make a disk image formatted with both ext2 and FAT, at once. 4 | 5 | ```bash 6 | ~/cursedfs% wget 'https://github.com/meithecatte/cursedfs/releases/download/v1.0/cursed.img' 7 | ~/cursedfs% sudo mount -o loop -t ext2 cursed.img mountpoint/ 8 | ~/cursedfs% ls mountpoint/ 9 | mkfs.cursed 10 | ~/cursedfs% sudo umount mountpoint/ 11 | ~/cursedfs% sudo mount -o loop -t msdos cursed.img mountpoint/ 12 | ~/cursedfs% ls mountpoint/ 13 | gudnuse.ogg 14 | ``` 15 | 16 | # Why? 17 | 18 | [I got nerd-sniped](https://twitter.com/Foone/status/1217162186130198529?s=20) 19 | 20 | # How? 21 | 22 | It turns out this is surprisingly simple to do: just create a FAT volume with a 23 | lot of reserved sectors and put the ext2 into the reserved sectors. This works 24 | because the filesystems choose different places to put their superblock: FAT 25 | uses the very first sector, while ext2 leaves the first kilobyte unused. 26 | 27 | # Can I write to the filesystems? 28 | 29 | Yes! When I first decided to do this, I thought writing to the image would 30 | surely break everything, but as it turns out, the method I've found means 31 | the filesystems don't conflict. 32 | -------------------------------------------------------------------------------- /mkfs.cursed: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | SIZE_EXT2=128 # sectors, max is 65535 4 | 5 | set -euxo pipefail 6 | EXT2_TMP="$(mktemp)" 7 | trap "rm $EXT2_TMP" EXIT 8 | 9 | truncate -s 4M cursed.img 10 | truncate -s "$((512*$SIZE_EXT2))" $EXT2_TMP 11 | mkfs.ext2 $EXT2_TMP 12 | mkfs.fat -R $SIZE_EXT2 cursed.img 13 | dd if=$EXT2_TMP of=cursed.img bs=512 skip=1 seek=1 conv=notrunc 14 | --------------------------------------------------------------------------------