static struct cbmem_cons __iomem *cbmem_console;
 
+static ssize_t memconsole_coreboot_read(char *buf, loff_t pos, size_t count)
+{
+       return memory_read_from_buffer(buf, count, &pos,
+                                      cbmem_console->buffer_body,
+                                      min(cbmem_console->buffer_cursor,
+                                          cbmem_console->buffer_size));
+}
+
 static int memconsole_coreboot_init(phys_addr_t physaddr)
 {
        struct cbmem_cons __iomem *tmp_cbmc;
        if (!cbmem_console)
                return -ENOMEM;
 
-       memconsole_setup(cbmem_console->buffer_body,
-               min(cbmem_console->buffer_cursor, cbmem_console->buffer_size));
-
+       memconsole_setup(memconsole_coreboot_read);
        return 0;
 }
 
 
        };
 } __packed;
 
+static char *memconsole_baseaddr;
+static size_t memconsole_length;
+
+static ssize_t memconsole_read(char *buf, loff_t pos, size_t count)
+{
+       return memory_read_from_buffer(buf, count, &pos, memconsole_baseaddr,
+                                      memconsole_length);
+}
+
 static void found_v1_header(struct biosmemcon_ebda *hdr)
 {
        pr_info("memconsole: BIOS console v1 EBDA structure found at %p\n",
                hdr->v1.buffer_addr, hdr->v1.start,
                hdr->v1.end, hdr->v1.num_chars);
 
-       memconsole_setup(phys_to_virt(hdr->v1.buffer_addr), hdr->v1.num_chars);
+       memconsole_baseaddr = phys_to_virt(hdr->v1.buffer_addr);
+       memconsole_length = hdr->v1.num_chars;
+       memconsole_setup(memconsole_read);
 }
 
 static void found_v2_header(struct biosmemcon_ebda *hdr)
                hdr->v2.buffer_addr, hdr->v2.start,
                hdr->v2.end, hdr->v2.num_bytes);
 
-       memconsole_setup(phys_to_virt(hdr->v2.buffer_addr + hdr->v2.start),
-                        hdr->v2.end - hdr->v2.start);
+       memconsole_baseaddr = phys_to_virt(hdr->v2.buffer_addr + hdr->v2.start);
+       memconsole_length = hdr->v2.end - hdr->v2.start;
+       memconsole_setup(memconsole_read);
 }
 
 /*
 
 
 #include "memconsole.h"
 
-static char *memconsole_baseaddr;
-static size_t memconsole_length;
+static ssize_t (*memconsole_read_func)(char *, loff_t, size_t);
 
 static ssize_t memconsole_read(struct file *filp, struct kobject *kobp,
                               struct bin_attribute *bin_attr, char *buf,
                               loff_t pos, size_t count)
 {
-       return memory_read_from_buffer(buf, count, &pos, memconsole_baseaddr,
-                                      memconsole_length);
+       if (WARN_ON_ONCE(!memconsole_read_func))
+               return -EIO;
+       return memconsole_read_func(buf, pos, count);
 }
 
 static struct bin_attribute memconsole_bin_attr = {
        .read = memconsole_read,
 };
 
-void memconsole_setup(void *baseaddr, size_t length)
+void memconsole_setup(ssize_t (*read_func)(char *, loff_t, size_t))
 {
-       memconsole_baseaddr = baseaddr;
-       memconsole_length = length;
+       memconsole_read_func = read_func;
 }
 EXPORT_SYMBOL(memconsole_setup);
 
 int memconsole_sysfs_init(void)
 {
-       memconsole_bin_attr.size = memconsole_length;
        return sysfs_create_bin_file(firmware_kobj, &memconsole_bin_attr);
 }
 EXPORT_SYMBOL(memconsole_sysfs_init);
 
 #ifndef __FIRMWARE_GOOGLE_MEMCONSOLE_H
 #define __FIRMWARE_GOOGLE_MEMCONSOLE_H
 
+#include <linux/types.h>
+
 /*
  * memconsole_setup
  *
- * Initialize the memory console from raw (virtual) base
- * address and length.
+ * Initialize the memory console, passing the function to handle read accesses.
  */
-void memconsole_setup(void *baseaddr, size_t length);
+void memconsole_setup(ssize_t (*read_func)(char *, loff_t, size_t));
 
 /*
  * memconsole_sysfs_init