Skip to contentSkip to conversation

: fbcon module unloading

PATCH New Antonino Daplas 1 participant 1 message Feb 14, 2003

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 : fbcon module unloading

Hi James,

Although fbcon can be compiled as a module, it cannot be safely unloaded yet. If fbcon is unloaded, it typically results in a frozen box. Allowing fbcon to successfully unload may be not so useful with typical usage, but will be very helpful for developers. So here's a preliminary patch to allow unloading of fbcon.

The main logic of the patch is when a console driver calls take_over_console(), 'conswitchp' will be saved to 'defcsw'. When it calls give_up_console() later on, aside from just unmapping the console driver (which is what the original code does), it will also attempt to reinstall the default console using the saved 'defcsw'pointer.

To minimize complexity, only one driver will be allowed to 'take over' the console at a time. Succeeding calls to take_over_console() will fail unless the driver gives up the console.

I made this a kernel config option, marked DANGEROUS. Also, only drivers with an info->fbops->fb_release() hook will be allowed to unload. The fb_release() hook need not do anything. Currently, fbcon on top of vga16fb, rivafb or i810fb can be unloaded. I have tested this using dummycon and vgacon.

Upon unload, the restored console will be partially corrupted. Also, I think unicode mapped characters are not fully restored.

Any comments welcome.

Tony

drivers/char/vt.c +76 -4
diff -Naur linux-2.5.59-orig/drivers/char/vt.c linux-2.5.59/drivers/char/vt.c
@@ -109,6 +109,7 @@
 
 
 const struct consw *conswitchp;
+const struct consw *defcsw = NULL; /* for recovery of default console */
 
 /* A bitmap for codes <32. A bit of 1 indicates that the code
  * corresponding to that bit number invokes some special action
@@ -2571,10 +2572,14 @@
 	int i, j = -1;
 	const char *desc;
 
+	if (deflt && defcsw != NULL)
+		return;
 	desc = csw->con_startup();
 	if (!desc) return;
-	if (deflt)
+	if (deflt) {
+		defcsw = conswitchp;
 		conswitchp = csw;
+	}
 
 	for (i = first; i <= last; i++) {
 		int old_was_color;
@@ -2616,11 +2621,78 @@
 
 void give_up_console(const struct consw *csw)
 {
-	int i;
+	const char *desc;
+	int i, j = -1, first = -1, last = -1;
 
-	for(i = 0; i < MAX_NR_CONSOLES; i++)
-		if (con_driver_map[i] == csw)
+	for(i = 0; i < MAX_NR_CONSOLES; i++) {
+		if (con_driver_map[i] == csw) {
+			if (first == -1)
+				first = i;
+			last = i;
 			con_driver_map[i] = NULL;
+		}
+	}
+
+	if (defcsw == NULL)
+		return;
+	conswitchp = defcsw;
+	defcsw = NULL;
+
+	desc = conswitchp->con_startup();
+	if (!desc) return;
+
+	for (i = first; i <= last; i++) {
+		int old_was_color;
+		int currcons = i;
+
+		con_driver_map[i] = conswitchp;
+
+		if (!vc_cons[i].d || !vc_cons[i].d->vc_sw)
+			continue;
+		j = i;
+		if (IS_VISIBLE)
+			save_screen(i);
+		old_was_color = vc_cons[i].d->vc_can_do_color;
+		vc_cons[i].d->vc_sw->con_deinit(vc_cons[i].d);
+		visual_init(i, 0);
+		set_origin(i);
+
+		/*
+		 * partial reset_terminal()
+		 */
+		top = 0;
+		bottom = video_num_lines;
+		gotoxy(i, x, y);
+		save_cur(i);
+		update_attr(i);
+
+
+		/* If the console changed between mono <-> color, then
+		 * the attributes in the screenbuf will be wrong.  The
+		 * following resets all attributes to something sane.
+		 */
+		if (old_was_color != vc_cons[i].d->vc_can_do_color ||
+		    IS_VISIBLE)
+			clear_buffer_attributes(i);
+
+		if (IS_VISIBLE)
+			update_screen(i);
+		if (vc_cons[i].d->vc_tty) {
+			kill_pg(vc_cons[i].d->vc_tty->pgrp, SIGWINCH, 1);
+			vc_cons[i].d->vc_tty->winsize.ws_col = 
+				video_num_columns;
+			vc_cons[i].d->vc_tty->winsize.ws_row = 
+				video_num_lines;
+		}
+	}
+	printk("Console: switching ");
+	if (j >= 0)
+		printk("to %s %s %dx%d\n",
+		       vc_cons[j].d->vc_can_do_color ? "colour" : "mono",
+		       desc, vc_cons[j].d->vc_cols, vc_cons[j].d->vc_rows);
+	else
+		printk("to %s\n", desc);
+
 }
 
 #endif
drivers/video/console/Kconfig +13 -0
diff -Naur linux-2.5.59-orig/drivers/video/console/Kconfig linux-2.5.59/drivers/video/console/Kconfig
@@ -106,6 +106,19 @@
 	tristate "Framebuffer Console support"
 	depends on FB
 
+config FRAMEBUFFER_CONSOLE_UNLOAD
+	bool "Allow Framebuffer Console Module Unloading (DANGEROUS)"
+	depends on FRAMEBUFFER_CONSOLE=m
+	default n
+	---help---
+          If you say Y, the framebuffer console module can be unloaded 
+          and the console reverted to the default console driver that was
+          loaded at boot time.  Not all drivers support unloading, and even
+          if it does, it might leave you with a corrupted display.
+
+          Unless you are a framebuffer driver developer, or you really know
+          what you're doing, say N here.
+
 config PCI_CONSOLE
 	bool
 	depends on FRAMEBUFFER_CONSOLE
drivers/video/console/fbcon.c +91 -4

131 lines not on this page · raw message

drivers/video/vga16fb.c +2 -1
diff -Naur linux-2.5.59-orig/drivers/video/vga16fb.c linux-2.5.59/drivers/video/vga16fb.c
@@ -305,7 +305,8 @@
 
 	if (!cnt) {
 		memset(&par->state, 0, sizeof(struct vgastate));
-		par->state.flags = 8;
+		par->state.flags = VGA_SAVE_FONTS | VGA_SAVE_MODE |
+			VGA_SAVE_CMAP;
 		save_vga(&par->state);
 	}
 	atomic_inc(&par->ref_count);