Index: kernel/genarch/src/drivers/ega/ega.c
===================================================================
--- kernel/genarch/src/drivers/ega/ega.c	(revision d1582b502edcb7bfeef771a2019538f265e7e27c)
+++ kernel/genarch/src/drivers/ega/ega.c	(revision 2ab8ab3c0a1e9771074c6e9d07ec1bf5e87ddafc)
@@ -568,15 +568,33 @@
 }
 
-static void ega_redraw(outdev_t *dev)
-{
-	ega_instance_t *instance = (ega_instance_t *) dev->data;
-
-	irq_spinlock_lock(&instance->lock, true);
-
+static void ega_redraw_internal(ega_instance_t *instance)
+{
 	memcpy(instance->addr, instance->backbuf, EGA_VRAM_SIZE);
 	ega_move_cursor(instance);
 	ega_show_cursor(instance);
-
+}
+
+static void ega_redraw(outdev_t *dev)
+{
+	ega_instance_t *instance = (ega_instance_t *) dev->data;
+
+	irq_spinlock_lock(&instance->lock, true);
+	ega_redraw_internal(instance);
 	irq_spinlock_unlock(&instance->lock, true);
+}
+
+/** EGA was mapped or unmapped.
+ *
+ * @param arg EGA instance
+ */
+static void ega_mapped_changed(void *arg)
+{
+	ega_instance_t *instance = (ega_instance_t *) arg;
+
+	if (!instance->parea.mapped) {
+		irq_spinlock_lock(&instance->lock, true);
+		ega_redraw_internal(instance);
+		irq_spinlock_unlock(&instance->lock, true);
+	}
 }
 
@@ -621,4 +639,6 @@
 	instance->parea.unpriv = false;
 	instance->parea.mapped = false;
+	instance->parea.mapped_changed = ega_mapped_changed;
+	instance->parea.arg = (void *) instance;
 	ddi_parea_register(&instance->parea);
 
Index: kernel/genarch/src/fb/fb.c
===================================================================
--- kernel/genarch/src/fb/fb.c	(revision d1582b502edcb7bfeef771a2019538f265e7e27c)
+++ kernel/genarch/src/fb/fb.c	(revision 2ab8ab3c0a1e9771074c6e9d07ec1bf5e87ddafc)
@@ -516,4 +516,19 @@
 }
 
+/** Framebuffer was mapped or unmapped.
+ *
+ * @param arg Framebuffer instance
+ */
+static void fb_mapped_changed(void *arg)
+{
+	fb_instance_t *instance = (fb_instance_t *) arg;
+
+	if (!instance->parea.mapped) {
+		spinlock_lock(&instance->lock);
+		fb_redraw_internal(instance);
+		spinlock_unlock(&instance->lock);
+	}
+}
+
 /** Initialize framebuffer as a output character device
  *
@@ -661,4 +676,6 @@
 	instance->parea.unpriv = false;
 	instance->parea.mapped = false;
+	instance->parea.mapped_changed = fb_mapped_changed;
+	instance->parea.arg = (void *) instance;
 	ddi_parea_register(&instance->parea);
 
Index: kernel/generic/include/ddi/ddi.h
===================================================================
--- kernel/generic/include/ddi/ddi.h	(revision d1582b502edcb7bfeef771a2019538f265e7e27c)
+++ kernel/generic/include/ddi/ddi.h	(revision 2ab8ab3c0a1e9771074c6e9d07ec1bf5e87ddafc)
@@ -42,5 +42,5 @@
 
 /** Structure representing contiguous physical memory area. */
-typedef struct {
+typedef struct parea {
 	/** Link to @c pareas ordered dictionary */
 	odlink_t lpareas;
@@ -54,4 +54,8 @@
 	/** Indicate whether the area is actually mapped. */
 	bool mapped;
+	/** Called when @c mapped field has changed */
+	void (*mapped_changed)(void *);
+	/** Callback argument */
+	void *arg;
 } parea_t;
 
@@ -59,4 +63,5 @@
 extern void ddi_parea_init(parea_t *);
 extern void ddi_parea_register(parea_t *);
+extern void ddi_parea_unmap_notify(parea_t *);
 
 extern void *pio_map(void *, size_t);
Index: kernel/generic/include/mm/as.h
===================================================================
--- kernel/generic/include/mm/as.h	(revision d1582b502edcb7bfeef771a2019538f265e7e27c)
+++ kernel/generic/include/mm/as.h	(revision 2ab8ab3c0a1e9771074c6e9d07ec1bf5e87ddafc)
@@ -236,4 +236,5 @@
 		size_t frames;
 		bool anonymous;
+		struct parea *parea;
 	};
 
Index: kernel/generic/src/ddi/ddi.c
===================================================================
--- kernel/generic/src/ddi/ddi.c	(revision d1582b502edcb7bfeef771a2019538f265e7e27c)
+++ kernel/generic/src/ddi/ddi.c	(revision 2ab8ab3c0a1e9771074c6e9d07ec1bf5e87ddafc)
@@ -107,4 +107,15 @@
 }
 
+/** Norify physical area has been unmapped.
+ *
+ * @param parea Physical area
+ */
+void ddi_parea_unmap_notify(parea_t *parea)
+{
+	parea->mapped = false;
+	if (parea->mapped_changed != NULL)
+		parea->mapped_changed(parea->arg);
+}
+
 /** Map piece of physical memory into virtual address space of current task.
  *
@@ -204,4 +215,6 @@
 
 map:
+	backend_data.parea = parea;
+
 	if (!as_area_create(TASK->as, flags, FRAMES2SIZE(pages),
 	    AS_AREA_ATTR_NONE, &phys_backend, &backend_data, virt, bound)) {
Index: kernel/generic/src/mm/backend_phys.c
===================================================================
--- kernel/generic/src/mm/backend_phys.c	(revision d1582b502edcb7bfeef771a2019538f265e7e27c)
+++ kernel/generic/src/mm/backend_phys.c	(revision 2ab8ab3c0a1e9771074c6e9d07ec1bf5e87ddafc)
@@ -38,4 +38,5 @@
 
 #include <assert.h>
+#include <ddi/ddi.h>
 #include <typedefs.h>
 #include <mm/as.h>
@@ -101,8 +102,11 @@
 {
 	/*
-	 * Nothing to do.
 	 * The anonymous frames, if any, are released in
 	 * phys_destroy_shared_data().
 	 */
+
+	/* Notify parea has been unmapped */
+	if (area->backend_data.parea != NULL)
+		ddi_parea_unmap_notify(area->backend_data.parea);
 }
 
