diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c
index 1f9128f6f..29abb0c9b 100644
--- a/grub-core/loader/i386/bsd.c
+++ b/grub-core/loader/i386/bsd.c
@@ -76,6 +76,7 @@ static int is_elf_kernel, is_64bit;
 static grub_uint32_t openbsd_root;
 static struct grub_relocator *relocator = NULL;
 static struct grub_openbsd_ramdisk_descriptor openbsd_ramdisk;
+static grub_int32_t openbsd_force_legacy_console = 0;
 
 struct bsd_tag
 {
@@ -134,6 +135,7 @@ static const struct grub_arg_option openbsd_opts[] =
     {"config", 'c', 0, N_("Change configured devices."), 0, 0},
     {"single", 's', 0, N_("Boot into single mode."), 0, 0},
     {"kdb", 'd', 0, N_("Enter in KDB on boot."), 0, 0},
+    {"legacy", 'l', 0, N_("Use legacy boot structure."), 0, 0},
     {"root", 'r', 0, N_("Set root device."), "wdXY", ARG_TYPE_STRING},
     {"serial", 'h', GRUB_ARG_OPTION_OPTIONAL,
      N_("Use serial console."),
@@ -147,7 +149,7 @@ static const struct grub_arg_option openbsd_opts[] =
 static const grub_uint32_t openbsd_flags[] =
 {
   OPENBSD_RB_ASKNAME, OPENBSD_RB_HALT, OPENBSD_RB_CONFIG,
-  OPENBSD_RB_SINGLE, OPENBSD_RB_KDB, 0
+  OPENBSD_RB_SINGLE, OPENBSD_RB_KDB, OPENBSD_RB_LEGACY, 0
 };
 
 #define OPENBSD_ROOT_ARG (ARRAY_SIZE (openbsd_flags) - 1)
@@ -821,6 +823,25 @@ grub_openbsd_boot (void)
   grub_err_t err;
   grub_size_t tag_buf_len;
 
+  if (openbsd_force_legacy_console || ! is_64bit ||
+      (openbsd_ramdisk.osrelease < 7003 && openbsd_ramdisk.osrelease > 0))
+    {
+      struct bsd_tag *tag;
+      for (tag = tags; tag; tag = tag->next)
+	if (tag->type == OPENBSD_BOOTARG_CONSOLE)
+	  {
+	    struct grub_openbsd_bootarg_console *s =
+	      (struct grub_openbsd_bootarg_console *) tag -> data;
+	    struct grub_openbsd_bootarg_console_legacy l_serial;
+	    grub_memset (&l_serial, 0, sizeof (l_serial));
+	    l_serial.device = s -> device;
+	    l_serial.speed = s -> speed;
+	    l_serial.addr = -1;
+	    grub_memcpy (tag -> data, &l_serial, sizeof(l_serial));
+	    tag -> len = sizeof(l_serial);
+	  }
+    }
+
   err = grub_bsd_add_mmap ();
   if (err)
     return err;
@@ -1604,6 +1625,8 @@ grub_cmd_openbsd (grub_extcmd_context_t ctxt, int argc, char *argv[])
 
   kernel_type = KERNEL_TYPE_OPENBSD;
   bootflags = grub_bsd_parse_flags (ctxt->state, openbsd_flags);
+  openbsd_force_legacy_console = bootflags & OPENBSD_RB_LEGACY;
+  bootflags &= ~OPENBSD_RB_LEGACY;
 
   if (ctxt->state[OPENBSD_ROOT_ARG].set && ctxt->state[OPENBSD_ROOT_ARG].arg != NULL)
     {
diff --git a/grub-core/loader/i386/bsdXX.c b/grub-core/loader/i386/bsdXX.c
index 09d909f1b..4943f995f 100644
--- a/grub-core/loader/i386/bsdXX.c
+++ b/grub-core/loader/i386/bsdXX.c
@@ -582,12 +582,14 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file,
 				   struct grub_openbsd_ramdisk_descriptor *desc)
 {
   unsigned symoff, stroff, symsize, strsize, symentsize;
+  Elf_Shdr *rodata, *shdr = NULL;
 
   {
     grub_err_t err;
     Elf_Ehdr e;
-    Elf_Shdr *s, *shdr = NULL;
+    Elf_Shdr *s, *strtab;
     Elf_Shnum shnum;
+    char *strarr;
 
     err = read_headers (file, filename, &e, &shdr);
     if (err != GRUB_ERR_NONE)
@@ -596,6 +598,55 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file,
 	return err;
       }
 
+    for (s = (Elf_Shdr *) shdr;
+	 s < (Elf_Shdr *) (shdr + e.e_shnum * e.e_shentsize);
+	 s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
+      if (s->sh_type == SHT_STRTAB)
+	break;
+    if (s >= (Elf_Shdr *) ((char *) shdr + e.e_shnum * e.e_shentsize))
+      {
+	grub_free (shdr);
+	return GRUB_ERR_NONE;
+      }
+    strtab = s;
+
+    strarr = grub_malloc (strtab->sh_size);
+    if (!strarr)
+      {
+	grub_free (shdr);
+        return grub_errno;
+      }
+
+    if (grub_file_seek (file, strtab->sh_offset) == (grub_off_t) -1)
+      {
+	grub_free (strarr);
+	grub_free (shdr);
+	return grub_errno;
+      }
+    if (grub_file_read (file, strarr, strtab->sh_size) != (grub_ssize_t) strtab->sh_size)
+      {
+        grub_free (strarr);
+        grub_free (shdr);
+        if (! grub_errno)
+          return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
+			     filename);
+        return grub_errno;
+      }
+
+    for (s = (Elf_Shdr *) shdr;
+	 s < (Elf_Shdr *) (shdr + e.e_shnum * e.e_shentsize);
+	 s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
+      if (s->sh_type == SHT_PROGBITS &&
+	  grub_strcmp (&strarr[s->sh_name], ".rodata") == 0)
+	break;
+    grub_free (strarr);
+    if (s >= (Elf_Shdr *) ((char *) shdr + e.e_shnum * e.e_shentsize))
+      {
+	grub_free (shdr);
+	return GRUB_ERR_NONE;
+      }
+    rodata = s;
+
     err = grub_elf_get_shnum (&e, &shnum);
     if (err != GRUB_ERR_NONE)
       {
@@ -620,24 +671,27 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file,
     s = (Elf_Shdr *) ((grub_uint8_t *) shdr + e.e_shentsize * s->sh_link);
     stroff = s->sh_offset;
     strsize = s->sh_size;
-    grub_free (shdr);
   }
   {
-    Elf_Sym *syms, *sym, *imagesym = NULL, *sizesym = NULL;
+    Elf_Sym *syms, *sym, *imagesym = NULL, *sizesym = NULL, *osrelsym = NULL;
     unsigned i;
     char *strs;
 
     syms = grub_malloc (symsize);
     if (!syms)
-      return grub_errno;
-
+      {
+	grub_free (shdr);
+	return grub_errno;
+      }
     if (grub_file_seek (file, symoff) == (grub_off_t) -1)
       {
+        grub_free (shdr);
 	grub_free (syms);
 	return grub_errno;
       }
     if (grub_file_read (file, syms, symsize) != (grub_ssize_t) symsize)
       {
+        grub_free (shdr);
 	grub_free (syms);
 	if (! grub_errno)
 	  return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
@@ -648,18 +702,21 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file,
     strs = grub_malloc (strsize);
     if (!strs)
       {
+        grub_free (shdr);
 	grub_free (syms);
 	return grub_errno;
       }
 
     if (grub_file_seek (file, stroff) == (grub_off_t) -1)
       {
+        grub_free (shdr);
 	grub_free (syms);
 	grub_free (strs);
 	return grub_errno;
       }
     if (grub_file_read (file, strs, strsize) != (grub_ssize_t) strsize)
       {
+        grub_free (shdr);
 	grub_free (syms);
 	grub_free (strs);
 	if (! grub_errno)
@@ -679,9 +736,51 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file,
 	  imagesym = sym;
 	if (grub_strcmp (strs + sym->st_name, "rd_root_size") == 0)
 	  sizesym = sym;
-	if (imagesym && sizesym)
+	if (grub_strcmp (strs + sym->st_name, "osrelease") == 0)
+	  osrelsym = sym;
+	if (imagesym && sizesym && osrelsym)
 	  break;
       }
+    if (osrelsym)
+      {
+	char *p;
+	int major, minor;
+	grub_size_t sz;
+	char osrel[16];
+	stroff = ((osrelsym->st_value - rodata->sh_addr) + rodata->sh_offset);
+	if (grub_file_seek (file, stroff) == (grub_off_t) -1)
+	  {
+	    grub_free (shdr);
+	    grub_free (syms);
+	    grub_free (strs);
+	    return grub_errno;
+	  }
+	sz = sizeof(osrel) < osrelsym->st_size ? sizeof(osrel) : osrelsym->st_size;
+	if (grub_file_read (file, osrel, sz) != (grub_ssize_t) sz)
+	  {
+	    grub_free (shdr);
+	    grub_free (syms);
+	    grub_free (strs);
+	    return grub_errno;
+	  }
+	osrel[sz - 1] = '\0';
+	major = minor = 0;
+	for (p = osrel; *p != '\0'; p++)
+	  if (*p >= '0' && *p <= '9')
+	    major = major * 10 + *p - '0';
+	  else
+	    break;
+	if (*p == '.')
+	  p++;
+	for (; *p != '\0'; p++)
+	  if (*p >= '0' && *p <= '9')
+	    minor = minor * 10 + *p - '0';
+	  else
+	    break;
+	desc->osrelease = major * 1000 + minor;
+      }
+    grub_free (shdr);
+
     if (!imagesym || !sizesym)
       {
 	grub_free (syms);
diff --git a/include/grub/i386/bsd.h b/include/grub/i386/bsd.h
index 523dd8621..adcccb36b 100644
--- a/include/grub/i386/bsd.h
+++ b/include/grub/i386/bsd.h
@@ -108,6 +108,7 @@ struct grub_openbsd_ramdisk_descriptor
   grub_size_t max_size;
   grub_uint8_t *target;
   grub_uint32_t *size;
+  grub_uint32_t osrelease;
 };
 
 grub_err_t grub_openbsd_find_ramdisk32 (grub_file_t file,
diff --git a/include/grub/i386/openbsd_bootarg.h b/include/grub/i386/openbsd_bootarg.h
index 8c28246d5..bc6e64ac1 100644
--- a/include/grub/i386/openbsd_bootarg.h
+++ b/include/grub/i386/openbsd_bootarg.h
@@ -71,7 +71,7 @@ struct grub_openbsd_bootargs
   grub_uint32_t ba_next;
 } GRUB_PACKED;
 
-struct grub_openbsd_bootarg_console
+struct grub_openbsd_bootarg_console_legacy
 {
   grub_uint32_t device;
   grub_uint32_t speed;
@@ -79,6 +79,17 @@ struct grub_openbsd_bootarg_console
   grub_uint32_t frequency;
 };
 
+struct grub_openbsd_bootarg_console
+{
+  grub_uint32_t device;
+  grub_uint32_t speed;
+  grub_uint64_t addr;
+  grub_int32_t  freq;
+  grub_uint32_t flags;
+  grub_int32_t  reg_width;
+  grub_int32_t  reg_shift;
+};
+
 struct grub_openbsd_bootarg_pcibios
 {
   grub_uint32_t characteristics;
diff --git a/include/grub/i386/openbsd_reboot.h b/include/grub/i386/openbsd_reboot.h
index 3f6571a44..1c2cf354e 100644
--- a/include/grub/i386/openbsd_reboot.h
+++ b/include/grub/i386/openbsd_reboot.h
@@ -69,6 +69,8 @@
 #define OPENBSD_RB_SERCONS	(1 << 13) /* use serial console if available */
 #define OPENBSD_RB_USERREQ	(1 << 14) /* boot() called at user request (e.g. ddb) */
 
+#define OPENBSD_RB_LEGACY	(1 << 31) /* Use legacy serial console structure */
+
 #define OPENBSD_B_DEVMAGIC	0xa0000000
 #define OPENBSD_B_ADAPTORSHIFT	24
 #define OPENBSD_B_CTRLSHIFT	20
