diff --git a/_posts/2024-02-28-porting-gnome-part1.markdown b/_posts/2024-02-28-porting-gnome-part1.markdown
new file mode 100644
index 0000000..b183b00
--- /dev/null
+++ b/_posts/2024-02-28-porting-gnome-part1.markdown
@@ -0,0 +1,37 @@
+---
+layout: post
+title: "Porting GNOME to Managarm, Part 1"
+excerpt: "Managarm is a pragmatic microkernel-based OS with fully asynchronous I/O. We talk about porting GNOME to Managarm. This is part 1 in our journey towards GNOME."
+---
+Post written by Dennis Bonke ([@Dennisbonke](https://github.com/Dennisbonke)).
+
+# Porting GNOME to Managarm, part 1
+
+## Introduction
+In this post, we will be talking about porting GNOME to Managarm. This is likely going to be a multipart series, so stay tuned for later installments. In this part, we start out somewhat simple, by trying to port gnome-calculator, while getting a feel for the environment we're entering and getting some common dependencies out of the way. For readers who are unfamilar with [Managarm](https://github.com/managarm/managarm): it is a microkernel-based OS that supports asynchronicity throughout the entire system while also providing compatibility with lots of Linux software. Feel free to try out Managarm (e.g., in a virtual machine). [Our README](https://github.com/managarm/managarm) contains a download link for a nightly image and instruction for trying out the system.
+
+## GTK4
+The first step in this porting adventure was a quick look at the dependencies for gnome-calculator. We decided that the best way to go was to start with [libadwaita](https://gnome.pages.gitlab.gnome.org/libadwaita/). Looking at the dependencies there showed two issues, AppStream and GTK4. Thinking we wouldn't start with the hardest items around, we decided to tackle AppStream first.
+
+[AppStream](https://www.freedesktop.org/wiki/Distributions/AppStream/) is a cross-distro effort for providing metadata for software in the Linux ecosystem, and had a few small dependencies that were cross-compiled without issues. While [Beyond Linux From Scratch](https://www.linuxfromscratch.org/blfs/) (BLFS) listed elogind as a required dependency, we choose to ignore that as we'd like to avoid touching that for as long as possible. It also listed libxmlb and libyaml that we didn't have yet, but those were quickly ported over. AppStream itself turned out to be a bit more resistant, as the latest version (1.0.1 as of writing) requires a host tool of AppStream to cross compile. After a quick downgrade to 0.16.4 it configured fine, but decided to hardcode `/usr/include` as a directory to search for system headers. Those obviously aren't from [mlibc](https://github.com/managarm/mlibc), so that gave some compile errors. Nothing a quick meson.build patch couldn't fix. After another patch to tell AppStream that there is no way to get the physical memory total on Managarm yet, AppStream relented, and compiled fine.
+
+With AppStream out of the way, our attention turned to [GTK4](https://www.gtk.org/). Considering Managarm already has GTK+\-2 and GTK+\-3, a lot of the required dependencies were already ported over. BLFS mentions PyGObject, which is related to gobject-introspection, which we don't want to touch either if we can avoid it, so we ignored that. That left graphene and ISO-Codes left to port, which are fortunately quite easy and compiled without issues.
+
+So, with all the dependencies done, we could begin writing the recipe for GTK4. As it uses meson, we copied an already existing recipe using meson, like GTK+\-3 for example, and started from there. The first thing we do when writing recipes, is checking if BLFS (or in rare cases, LFS) has the package. We also check [Gentoo](https://packages.gentoo.org) for an ebuild if available. Together, those usually form the basis for the options to pass to configure (or in this case, meson). Then, we of course modify the source block to actually point to the git repo or release tarball of the port in question, and we change the name of the recipe too. As this is meson, we have no regeneration to do, so after updating the dependency list we're good to go configure GTK4!
+
+Unfortunately we noticed something weird happening during configure. Meson was pulling in a fallback glib project! It turns out that our glib was too far out of date, which meant that we were updating that first. Luckily that wasn't a big deal, after one small patch to a meson.build file that problem was eliminated. Back to GTK4 we went, and configure had no further issues. Compilation only gave one small complaint, which was `#include `, which was promptly put behind a preprocessor guard. After compilation was complete (no mlibc additions needed at all here), it was of course time to test it! So we booted into Weston, and ran gtk4-demo, and it crashed. There was a nice little assert being tripped, complaining about unsupported flags being passed to `sys_inotify_create()`, which is the syscall for `inotify_init()`. The unsupported flag was `IN_NONBLOCK`, which requires changes to the inotify subsystem of Managarm. For now, we've passed the flag through to posix, and log it there. With that fix made, gtk4-demo gave in and ran, giving the following screenshot
+
+
+
+## GObject-Introspection and vala
+Ideally, we wanted to do this quest without touching [GObject-Introspection](https://wiki.gnome.org/Projects/GObjectIntrospection) and [Vala](https://wiki.gnome.org/Projects/Vala), as that requires generating items at build time, and for gobject-introspection, that requires running binaries compiled for Managarm. Unfortunately that proved to be impossible. With the help of [@48cf](https://github.com/48cf/) Vala was solved by writing a wrapper script to force `--vapidir` to be passed to it in the case of `valac`, and in the case of `vapigen` it also needed to take `--girdir`. GObject-Introspection was not so kind, forcing us to patch it to take wrappers from the environment, writing two wrappers, one to run Managarm binaries on Linux using our Linux mlibc port and the use of patchelf, and one to emulate ldd with objdump.
+That in turn lead us to requiring `LD_LIBRARY_PATH` in mlibc, which we didn't have yet, so we [implemented that](https://github.com/managarm/mlibc/pull/967). After that we found a difference in the ABI between the Linux port and the Managarm port, which required us to rebuild the entire world. The patchwork for GObject-Introspection itself involved allowing an environment variable, `GI_LDD_WRAPPER`, to set the ldd-wrapper it should use. Then, finally, GObject-Introspection yielded. We tested out this new tool by rebuilding `at-spi2-core` with introspection data, as it had no dependencies on other introspection data packages. With a few additional environment variables passed in during configure and compilation, that also worked, paving the way towards the finish.
+
+## The road to gnome-calculator
+After getting GObject-Introspection to work, the next item on the list was rebuilding the entire GTK stack with introspection enabled, which we did on an as needed basis. Luckily there weren't many struggles here. After that, we moved on to [libgee](https://wiki.gnome.org/Projects/Libgee), which is old and for some reason didn't want to work with introspecion enabled, luckily it turns out we don't need the introspection data from libgee just yet. Then we moved to [gtksourceview5](https://wiki.gnome.org/Projects/GtkSourceView), which depends on GTK4, pcre2 and libxml2, all of which we have. Again, this proved to be no issue at all, and neither was [libadwaita](https://gnome.pages.gitlab.gnome.org/libadwaita/). So on to [gnome-calculator](https://wiki.gnome.org/Apps/Calculator) it was!
+After adding a few more ports to the PR, upstream was still lacking a libsoup 3.x port, gnome-calculator was no issue at all. Running it also proved no issue, giving us the following screenshot.
+
+
+
+## Conclusion
+In this blog post, we've taken on the task of porting the GNOME Desktop Environment to Managarm. We've seen and tackled a few of the hardest problems we might face on our road, such as GObject-Introspection. We also ported a few nice to have dependencies that we can use later on. Additionally, mlibc gained a new feature and we uncovered an abi incompatibility which we also fixed.
\ No newline at end of file
diff --git a/assets/2024-porting-gnome-part1/gnome-calculator-working.png b/assets/2024-porting-gnome-part1/gnome-calculator-working.png
new file mode 100644
index 0000000..cf6152f
Binary files /dev/null and b/assets/2024-porting-gnome-part1/gnome-calculator-working.png differ
diff --git a/assets/2024-porting-gnome-part1/gtk4-working.png b/assets/2024-porting-gnome-part1/gtk4-working.png
new file mode 100644
index 0000000..5011a1e
Binary files /dev/null and b/assets/2024-porting-gnome-part1/gtk4-working.png differ