diff --git a/TODO b/TODO
index f3e1ea943..bc62720d6 100644
--- a/TODO
+++ b/TODO
@@ -1,9 +1,11 @@
 ☐ Save/load UI
 ✔ CPU @done(19-08-13 15:41)
 ✔ Memory @done(19-08-13 15:41)
+    ☐ Page tables
+    ☐ Skip N3DS RAM if unused
 ✔ DSP @done(19-08-13 15:41)
 ✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s)
-    ☐ Fix or ignore inverse map
+    ✔ Fix or ignore inverse map @done(19-12-23 12:46)
 ☐ App loader
 ☐ Archive manager
 ☐ Custom texture cache
@@ -58,8 +60,8 @@
         ☐ VM Manager @started(19-08-13 16:46)
             Just need to figure out backing_mem (a u8*)
         ✔ Wait object @done(19-08-13 16:46)
-    ☐ Service
-        ☐ AC
+    ☐ Service @started(19-12-23 12:49)
+        ☐ AC @started(19-12-23 12:48)
         ☐ ACT
         ☐ AM
         ☐ APT
diff --git a/src/common/construct.h b/src/common/construct.h
new file mode 100644
index 000000000..28f4cc349
--- /dev/null
+++ b/src/common/construct.h
@@ -0,0 +1,35 @@
+#include <boost/serialization/serialization.hpp>
+
+#define BOOST_SERIALIZATION_FRIENDS \
+    friend class boost::serialization::access; \
+    friend class construct_access;
+
+class construct_access {
+public:
+    template<class Archive, class T>
+    static inline void save_construct(Archive & ar, const T * t, const unsigned int file_version) {
+        t->save_construct(ar, file_version);
+    }
+    template<class Archive, class T>
+    static inline void load_construct(Archive & ar, T * t, const unsigned int file_version) {
+        T::load_construct(ar, t, file_version);
+    }
+};
+
+#define BOOST_SERIALIZATION_CONSTRUCT(T) \
+namespace boost { namespace serialization { \
+\
+    template<class Archive> \
+    inline void save_construct_data( \
+        Archive & ar, const T * t, const unsigned int file_version \
+    ){ \
+        construct_access::save_construct(ar, t, file_version); \
+    } \
+\
+    template<class Archive> \
+    inline void load_construct_data( \
+        Archive & ar, T * t, const unsigned int file_version \
+    ){ \
+        construct_access::load_construct(ar, t, file_version); \
+    } \
+}}
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index be3a20e79..da89ad39a 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -75,6 +75,10 @@ public:
     /// in each service must inherit from this.
     struct SessionDataBase {
         virtual ~SessionDataBase() = default;
+    private:
+        template <class Archive>
+        void serialize(Archive& ar, const unsigned int file_version) { }
+        friend class boost::serialization::access;
     };
 
 protected:
@@ -94,6 +98,7 @@ protected:
 
     struct SessionInfo {
         SessionInfo(std::shared_ptr<ServerSession> session, std::unique_ptr<SessionDataBase> data);
+        SessionInfo() = default;
 
         std::shared_ptr<ServerSession> session;
         std::unique_ptr<SessionDataBase> data;
diff --git a/src/core/hle/service/ac/ac.cpp b/src/core/hle/service/ac/ac.cpp
index 9d40b9661..acae47fd5 100644
--- a/src/core/hle/service/ac/ac.cpp
+++ b/src/core/hle/service/ac/ac.cpp
@@ -5,6 +5,7 @@
 #include <vector>
 #include "common/common_types.h"
 #include "common/logging/log.h"
+#include "common/archives.h"
 #include "core/core.h"
 #include "core/hle/ipc.h"
 #include "core/hle/ipc_helpers.h"
@@ -16,6 +17,8 @@
 #include "core/hle/service/ac/ac_u.h"
 #include "core/memory.h"
 
+SERIALIZE_EXPORT_IMPL(Service::AC::Module::Interface)
+
 namespace Service::AC {
 void Module::Interface::CreateDefaultConfig(Kernel::HLERequestContext& ctx) {
     IPC::RequestParser rp(ctx, 0x1, 0, 0);
diff --git a/src/core/hle/service/ac/ac.h b/src/core/hle/service/ac/ac.h
index f3554c876..12e304f59 100644
--- a/src/core/hle/service/ac/ac.h
+++ b/src/core/hle/service/ac/ac.h
@@ -6,6 +6,9 @@
 
 #include <array>
 #include <memory>
+#include <boost/serialization/base_object.hpp>
+#include <boost/serialization/shared_ptr.hpp>
+#include "common/construct.h"
 #include "core/hle/service/service.h"
 
 namespace Core {
@@ -139,6 +142,34 @@ public:
 
     protected:
         std::shared_ptr<Module> ac;
+
+    private:
+        template <class Archive>
+        void save_construct(Archive& ar, const unsigned int file_version) const
+        {
+            ar << ac;
+            ar << GetServiceName();
+            ar << GetMaxSessions();
+        }
+
+        template <class Archive>
+        static void load_construct(Archive& ar, Interface* t, const unsigned int file_version)
+        {
+            std::shared_ptr<Module> ac;
+            std::string name;
+            u32 max_sessions;
+            ar >> ac;
+            ar >> name;
+            ar >> max_sessions;
+            ::new(t)Interface(ac, name.c_str(), max_sessions);
+        }
+
+        template <class Archive>
+        void serialize(Archive& ar, const unsigned int file_version)
+        {
+            ar & boost::serialization::base_object<Kernel::SessionRequestHandler>(*this);
+        }
+        BOOST_SERIALIZATION_FRIENDS
     };
 
 protected:
@@ -153,8 +184,23 @@ protected:
     std::shared_ptr<Kernel::Event> close_event;
     std::shared_ptr<Kernel::Event> connect_event;
     std::shared_ptr<Kernel::Event> disconnect_event;
+
+private:
+    template <class Archive>
+    void serialize(Archive& ar, const unsigned int file_version)
+    {
+        ar & ac_connected;
+        ar & close_event;
+        ar & connect_event;
+        ar & disconnect_event;
+        // default_config is never written to
+    }
+    friend class boost::serialization::access;
 };
 
 void InstallInterfaces(Core::System& system);
 
 } // namespace Service::AC
+
+BOOST_SERIALIZATION_CONSTRUCT(Service::AC::Module::Interface)
+BOOST_CLASS_EXPORT_KEY(Service::AC::Module::Interface)
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index db6a0ad23..f05c15f23 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -85,6 +85,7 @@ private:
     using InvokerFn = void(ServiceFrameworkBase* object, HandlerFnP<ServiceFrameworkBase> member,
                            Kernel::HLERequestContext& ctx);
 
+    // TODO: Replace all these with virtual functions!
     ServiceFrameworkBase(const char* service_name, u32 max_sessions, InvokerFn* handler_invoker);
     ~ServiceFrameworkBase() override;
 
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h
index 9cdaff72d..d91732da9 100644
--- a/src/core/hle/service/sm/sm.h
+++ b/src/core/hle/service/sm/sm.h
@@ -11,6 +11,7 @@
 #include <boost/serialization/shared_ptr.hpp>
 #include <boost/serialization/string.hpp>
 #include <boost/serialization/unordered_map.hpp>
+#include <boost/serialization/split_member.hpp>
 #include "core/hle/kernel/client_port.h"
 #include "core/hle/kernel/object.h"
 #include "core/hle/kernel/server_port.h"
@@ -85,11 +86,23 @@ private:
     std::unordered_map<u32, std::string> registered_services_inverse;
 
     template <class Archive>
-    void serialize(Archive& ar, const unsigned int file_version)
+    void save(Archive& ar, const unsigned int file_version) const
     {
-        ar & registered_services;
-        ar & registered_services_inverse; // TODO: Instead, compute this from registered_services
+        ar << registered_services;
     }
+
+    template <class Archive>
+    void load(Archive& ar, const unsigned int file_version)
+    {
+        ar >> registered_services;
+        registered_services_inverse.clear();
+        for (const auto& pair : registered_services) {
+            registered_services_inverse.emplace(pair.second->GetObjectId(), pair.first);
+        }
+    }
+
+    BOOST_SERIALIZATION_SPLIT_MEMBER()
+
     friend class boost::serialization::access;
 };
 
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index a07cc2e13..7264e1ec4 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -56,7 +56,7 @@ private:
     std::array<bool, LINEAR_HEAP_SIZE / PAGE_SIZE> linear_heap{};
     std::array<bool, NEW_LINEAR_HEAP_SIZE / PAGE_SIZE> new_linear_heap{};
 
-    static_assert(sizeof(bool) == 1); // TODO: Maybe this isn't true?
+    static_assert(sizeof(bool) == 1);
     friend class boost::serialization::access;
     template<typename Archive>
     void serialize(Archive & ar, const unsigned int file_version)