Going by the instructions on the dm-cache github, to create a cache you need the kernel modules dm_mod and dm_cache loaded (assuming you already have a patched kernel)
Also you will need to access the dmsetup executable and presumably you want /dev to be populated so you can access the device on which you will create the cache.
As cjm already mentioned, to do this you will need to modify your initramfs, which is a file system that is loaded into memory before the hard disk is mounted.
luckily, dmsetup is already installed on the initramfs (This should always be the case, as it is needed for volume management; But to check use "lsinitramfs /initrd.img | grep dmsetup")
This leaves two things things which you will have to add to your initramfs: the two modules and the script to create the cache. For the modules, simply edit either /usr/share/initramfs-tools/modules or /etc/initramfs-tools/modules
Place your boot script in either /usr/share/initramfs-tools/local-premount or /etc/initramfs-tools/local-premount. Putting it in the local-premount subdirectory will ensure that the modules have been loaded and /dev is populated, but / has not been mounted yet. The script can be a normal sh script. Use the #!/bin/sh shebang and don't forget to make it executable. I assume you know how to write it yourself (otherwise, please provide more information)
run update-initramfs -u to apply the changes, and you should be set. Make sure you have an older kernel remaining to boot into if something goes wrong.
read 'man initramfs-tools' for general instructions on how to use initramfs-tools
Using dracut:
dracut uses a modular system to manage its bootup process. similarly to initramfs-tools, it possesses a hook called pre-mount, which you will want to use. To install your script, you will need to define a module which uses this hook:
mkdir /usr/lib/dracut/modules.d/40dm-cache
now edit the file /usr/lib/dracut/modules.d/40dm-cache/module-setup.sh
#!/bin/bash
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh
check() {
return 0
}
depends() {
return 0
}
install() {
inst_hook pre-mount 91 "$moddir/dm-cache.sh"
}
installkernel() {
instmods dm_mod
instmods dm_cache
}
and /usr/lib/dracut/modules.d/40dm-cache/dm-cache.sh
#!/bin/sh
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh
modprobe dm_mod
modprobe dm_cache
***here you insert your caching code. As before, dmsetup should be available at /sbin/dmsetup***
if you let check() return 255 instead of 0, the module will be loaded only if specified in dracut's config file (by returning 0, it will be loaded unconditionally)
Now to update the initrd:
dracut --force
a dracut reference guide: https://www.kernel.org/pub/linux/utils/boot/dracut/dracut.html