diff --git a/src/ipa/shim_dummy.cpp b/src/ipa/shim_dummy.cpp
index 4d28c2d..f2e6961 100644
--- a/src/ipa/shim_dummy.cpp
+++ b/src/ipa/shim_dummy.cpp
@@ -6,6 +6,14 @@
  */
 
 #include <iostream>
+#include <memory>
+
+#include <dlfcn.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 #include <libcamera/ipa/ipa_interface.h>
 #include <libcamera/ipa/ipa_module_info.h>
@@ -17,20 +25,87 @@ class ShimDummy : public IPAInterface
 public:
 	int init();
 	int init(const char *path);
+
+	void cleanup();
+
+private:
+	std::unique_ptr<IPAInterface> ipa_;
+
+	int sockets_[2];
+	int childPid_;
+	void *dlHandle_;
+
+	typedef IPAInterface *(*IPAIntfFactory)(void);
 };
 
 int ShimDummy::init()
 {
-	std::cout << "okay shim init without path" << std::endl;
+	std::cout << "initializing IPA via dummy shim!" << std::endl;
 	return 0;
 }
 
 int ShimDummy::init(const char *path)
 {
-	std::cout << "initializing dummy shim!" << std::endl;
+	std::cout << "initializing dummy shim! loading IPA from " << path
+		  << std::endl;
+
+	/* We know the IPA module is valid, otherwise IPAManager wouldn't
+	 * even give its path to us. */
+
+	// setup comm
+	if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets_)) {
+		int err = errno;
+		std::cerr << "Error opening sockets: " << strerror(errno)
+			  << std::endl;
+		return err;
+	}
+
+	// fork
+	if ((childPid_ = fork()) == -1) {
+		int err = errno;
+		std::cerr << "Failed to fork: " << strerror(errno) << std::endl;
+		return err;
+	} else if (childPid_) {
+		// we are parent
+		// we can read/write sockets_[1]
+		close(sockets_[0]);
+	} else {
+		// we are child
+		// we can read/write sockets_[0]
+		close(sockets_[1]);
+
+		dlHandle_ = dlopen(path, RTLD_LAZY);
+		if (!dlHandle_) {
+			std::cerr << "Failed to open IPA module: "
+				  << dlerror() << std::endl;
+			return -1;
+		}
+
+		void *symbol = dlsym(dlHandle_, "ipaCreate");
+		if (!symbol) {
+			std::cerr
+				<< "Failed to load ipaCreate() from IPA module shared object: "
+				<< dlerror();
+			dlclose(dlHandle_);
+			dlHandle_ = nullptr;
+			return -1;
+		}
+
+		IPAIntfFactory ipaCreate = reinterpret_cast<IPAIntfFactory>(symbol);
+		ipa_ = std::unique_ptr<IPAInterface>(ipaCreate());
+		exit(0);
+	}
+
 	return 0;
 }
 
+void ShimDummy::cleanup()
+{
+	if (dlHandle_)
+		dlclose(dlHandle_);
+	dlHandle_ = nullptr;
+}
+
 /*
  * External IPA module interface
  */
