diff --git a/data/templates/grub/grub_common.j2 b/data/templates/grub/grub_common.j2
index 78df3f48c..278ffbf2c 100644
--- a/data/templates/grub/grub_common.j2
+++ b/data/templates/grub/grub_common.j2
@@ -1,22 +1,23 @@
 # load EFI video modules
 if [ "${grub_platform}" == "efi" ]; then
     insmod efi_gop
     insmod efi_uga
 fi
 
 # create and activate serial console
 function setup_serial {
     # initialize the first serial port by default
     if [ "${console_type}" == "ttyS" ]; then
         serial --unit=${console_num}
     else
         serial --unit=0
     fi
     terminal_output --append serial console
     terminal_input --append serial console
 }
 
 setup_serial
 
-# find root device
-#search --no-floppy --fs-uuid --set=root ${root_uuid}
+{% if search_root %}
+{{ search_root }}
+{% endif %}
diff --git a/data/templates/grub/grub_compat.j2 b/data/templates/grub/grub_compat.j2
index 935172005..887d5d0bd 100644
--- a/data/templates/grub/grub_compat.j2
+++ b/data/templates/grub/grub_compat.j2
@@ -1,58 +1,63 @@
 {# j2lint: disable=S6 #}
 ### Generated by VyOS image-tools v.{{ tools_version }} ###
 {% macro menu_name(mode) -%}
 {% if mode == 'normal' -%}
     VyOS
 {%- elif mode == 'pw_reset' -%}
     Lost password change
 {%- else -%}
     Unknown
 {%- endif %}
 {%- endmacro %}
 {% macro console_name(type) -%}
 {% if type == 'tty' -%}
     KVM
 {%- elif type == 'ttyS' -%}
     Serial
 {%- elif type == 'ttyUSB' -%}
     USB
 {%- else -%}
     Unknown
 {%- endif %}
 {%- endmacro %}
 {% macro console_opts(type) -%}
 {% if type == 'tty' -%}
     console=ttyS0,115200 console=tty0
 {%- elif type == 'ttyS' -%}
     console=tty0 console=ttyS0,115200
 {%- elif type == 'ttyUSB' -%}
     console=tty0 console=ttyUSB0,115200
 {%- else -%}
     console=tty0 console=ttyS0,115200
 {%- endif %}
 {%- endmacro %}
 {% macro passwd_opts(mode) -%}
 {% if mode == 'pw_reset' -%}
     init=/opt/vyatta/sbin/standalone_root_pw_reset
 {%- endif %}
 {%- endmacro %}
 set default={{ default }}
 set timeout={{ timeout }}
 {% if console_type == 'ttyS' %}
 serial --unit={{ console_num }} --speed=115200
 {% else %}
 serial --unit=0 --speed=115200
 {% endif %}
 terminal_output --append serial
 terminal_input serial console
-{% if efi %}
-insmod efi_gop
-insmod efi_uga
+{% for mod in modules %}
+insmod {{ mod }}
+{% endfor %}
+{% if root %}
+set root={{ root }}
+{% endif %}
+{% if search_root %}
+{{ search_root }}
 {% endif %}
 
 {% for v in versions %}
 menuentry "{{ menu_name(v.bootmode) }} {{ v.version }} ({{ console_name(v.console_type) }} console)" {
     linux /boot/{{ v.version }}/vmlinuz {{ v.boot_opts }} {{ console_opts(v.console_type) }} {{ passwd_opts(v.bootmode) }}
     initrd /boot/{{ v.version }}/initrd.img
 }
 {% endfor %}
diff --git a/python/vyos/system/compat.py b/python/vyos/system/compat.py
index aa9b0b4b5..319c3dabf 100644
--- a/python/vyos/system/compat.py
+++ b/python/vyos/system/compat.py
@@ -1,307 +1,316 @@
 # Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
 # License as published by the Free Software Foundation; either
 # version 2.1 of the License, or (at your option) any later version.
 #
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # Lesser General Public License for more details.
 #
 # You should have received a copy of the GNU Lesser General Public License
 # along with this library.  If not, see <http://www.gnu.org/licenses/>.
 
 from pathlib import Path
 from re import compile, MULTILINE, DOTALL
 from functools import wraps
 from copy import deepcopy
 from typing import Union
 
 from vyos.system import disk, grub, image, SYSTEM_CFG_VER
 from vyos.template import render
 
 TMPL_GRUB_COMPAT: str = 'grub/grub_compat.j2'
 
 # define regexes and variables
 REGEX_VERSION = r'^menuentry "[^\n]*{\n[^}]*\s+linux /boot/(?P<version>\S+)/[^}]*}'
 REGEX_MENUENTRY = r'^menuentry "[^\n]*{\n[^}]*\s+linux /boot/(?P<version>\S+)/vmlinuz (?P<options>[^\n]+)\n[^}]*}'
 REGEX_CONSOLE = r'^.*console=(?P<console_type>[^\s\d]+)(?P<console_num>[\d]+).*$'
 REGEX_SANIT_CONSOLE = r'\ ?console=[^\s\d]+[\d]+(,\d+)?\ ?'
 REGEX_SANIT_INIT = r'\ ?init=\S*\ ?'
 REGEX_SANIT_QUIET = r'\ ?quiet\ ?'
 PW_RESET_OPTION = 'init=/opt/vyatta/sbin/standalone_root_pw_reset'
 
 
 class DowngradingImageTools(Exception):
     """Raised when attempting to add an image with an earlier version
     of image-tools than the current system, as indicated by the value
     of SYSTEM_CFG_VER or absence thereof."""
     pass
 
 
 def mode():
     if grub.get_cfg_ver() >= SYSTEM_CFG_VER:
         return False
 
     return True
 
 
 def find_versions(menu_entries: list) -> list:
     """Find unique VyOS versions from menu entries
 
     Args:
         menu_entries (list): a list with menu entries
 
     Returns:
         list: List of installed versions
     """
     versions = []
     for vyos_ver in menu_entries:
         versions.append(vyos_ver.get('version'))
     # remove duplicates
     versions = list(set(versions))
     return versions
 
 
 def filter_unparsed(grub_path: str) -> str:
     """Find currently installed VyOS version
 
     Args:
         grub_path (str): a path to the grub.cfg file
 
     Returns:
         str: unparsed grub.cfg items
     """
     config_text = Path(grub_path).read_text()
     regex_filter = compile(REGEX_VERSION, MULTILINE | DOTALL)
     filtered = regex_filter.sub('', config_text)
     regex_filter = compile(grub.REGEX_GRUB_VARS, MULTILINE)
     filtered = regex_filter.sub('', filtered)
     regex_filter = compile(grub.REGEX_GRUB_MODULES, MULTILINE)
     filtered = regex_filter.sub('', filtered)
     # strip extra new lines
     filtered = filtered.strip()
     return filtered
 
 
+def get_search_root(unparsed: str) -> str:
+    unparsed_lines = unparsed.splitlines()
+    search_root = next((x for x in unparsed_lines if 'search' in x), '')
+    return search_root
+
+
 def sanitize_boot_opts(boot_opts: str) -> str:
     """Sanitize boot options from console and init
 
     Args:
         boot_opts (str): boot options
 
     Returns:
         str: sanitized boot options
     """
     regex_filter = compile(REGEX_SANIT_CONSOLE)
     boot_opts = regex_filter.sub('', boot_opts)
     regex_filter = compile(REGEX_SANIT_INIT)
     boot_opts = regex_filter.sub('', boot_opts)
     # legacy tools add 'quiet' on add system image; this is not desired
     regex_filter = compile(REGEX_SANIT_QUIET)
     boot_opts = regex_filter.sub(' ', boot_opts)
 
     return boot_opts
 
 
 def parse_entry(entry: tuple) -> dict:
     """Parse GRUB menuentry
 
     Args:
         entry (tuple): tuple of (version, options)
 
     Returns:
         dict: dictionary with parsed options
     """
     # save version to dict
     entry_dict = {'version': entry[0]}
     # detect boot mode type
     if PW_RESET_OPTION in entry[1]:
         entry_dict['bootmode'] = 'pw_reset'
     else:
         entry_dict['bootmode'] = 'normal'
     # find console type and number
     regex_filter = compile(REGEX_CONSOLE)
     entry_dict.update(regex_filter.match(entry[1]).groupdict())
     entry_dict['boot_opts'] = sanitize_boot_opts(entry[1])
 
     return entry_dict
 
 
 def parse_menuentries(grub_path: str) -> list:
     """Parse all GRUB menuentries
 
     Args:
         grub_path (str): a path to GRUB config file
 
     Returns:
         list: list with menu items (each item is a dict)
     """
     menuentries = []
     # read configuration file
     config_text = Path(grub_path).read_text()
     # parse menuentries to tuples (version, options)
     regex_filter = compile(REGEX_MENUENTRY, MULTILINE)
     filter_results = regex_filter.findall(config_text)
     # parse each entry
     for entry in filter_results:
         menuentries.append(parse_entry(entry))
 
     return menuentries
 
 
 def prune_vyos_versions(root_dir: str = '') -> None:
     """Delete vyos-versions files of registered images subsequently deleted
     or renamed by legacy image-tools
 
     Args:
         root_dir (str): an optional path to the root directory
     """
     if not root_dir:
         root_dir = disk.find_persistence()
 
     for version in grub.version_list():
         if not Path(f'{root_dir}/boot/{version}').is_dir():
             grub.version_del(version)
 
 
 def update_cfg_ver(root_dir:str = '') -> int:
     """Get minumum version of image-tools across all installed images
 
     Args:
         root_dir (str): an optional path to the root directory
 
     Returns:
         int: minimum version of image-tools
     """
     if not root_dir:
         root_dir = disk.find_persistence()
 
     prune_vyos_versions(root_dir)
 
     images_details = image.get_images_details()
     cfg_version = min(d['tools_version'] for d in images_details)
 
     return cfg_version
 
 
 def get_default(menu_entries: list, root_dir: str = '') -> Union[int, None]:
     """Translate default version to menuentry index
 
     Args:
         menu_entries (list): list of dicts of installed version boot data
         root_dir (str): an optional path to the root directory
 
     Returns:
         int: index of default version in menu_entries or None
     """
     if not root_dir:
         root_dir = disk.find_persistence()
 
     grub_cfg_main = f'{root_dir}/{grub.GRUB_CFG_MAIN}'
 
     image_name = image.get_default_image()
 
     sublist = list(filter(lambda x: x.get('version') == image_name,
                         menu_entries))
     if sublist:
         return menu_entries.index(sublist[0])
 
     return None
 
 
 def update_version_list(root_dir: str = '') -> list[dict]:
     """Update list of dicts of installed version boot data
 
     Args:
         root_dir (str): an optional path to the root directory
 
     Returns:
         list: list of dicts of installed version boot data
     """
     if not root_dir:
         root_dir = disk.find_persistence()
 
     grub_cfg_main = f'{root_dir}/{grub.GRUB_CFG_MAIN}'
 
     # get list of versions in menuentries
     menu_entries = parse_menuentries(grub_cfg_main)
     menu_versions = find_versions(menu_entries)
 
     # get list of versions added/removed by image-tools
     current_versions = grub.version_list(root_dir)
 
     remove = list(set(menu_versions) - set(current_versions))
     for ver in remove:
         menu_entries = list(filter(lambda x: x.get('version') != ver,
                                    menu_entries))
 
     add = list(set(current_versions) - set(menu_versions))
     for ver in add:
         last = menu_entries[0].get('version')
         new = deepcopy(list(filter(lambda x: x.get('version') == last,
                                    menu_entries)))
         for e in new:
             boot_opts = e.get('boot_opts').replace(last, ver)
             e.update({'version': ver, 'boot_opts': boot_opts})
 
         menu_entries = new + menu_entries
 
     return menu_entries
 
 
 def grub_cfg_fields(root_dir: str = '') -> dict:
     """Gather fields for rendering grub.cfg
 
     Args:
         root_dir (str): an optional path to the root directory
 
     Returns:
         dict: dictionary for rendering TMPL_GRUB_COMPAT
     """
     if not root_dir:
         root_dir = disk.find_persistence()
 
     grub_cfg_main = f'{root_dir}/{grub.GRUB_CFG_MAIN}'
 
     fields = {'default': 0, 'timeout': 5}
     # 'default' and 'timeout' from legacy grub.cfg
     fields |= grub.vars_read(grub_cfg_main)
+
     fields['tools_version'] = SYSTEM_CFG_VER
     menu_entries = update_version_list(root_dir)
     fields['versions'] = menu_entries
+
     default = get_default(menu_entries, root_dir)
     if default is not None:
         fields['default'] = default
 
-    p = Path('/sys/firmware/efi')
-    if p.is_dir():
-        fields['efi'] = True
-    else:
-        fields['efi'] = False
+    modules = grub.modules_read(grub_cfg_main)
+    fields['modules'] = modules
+
+    unparsed = filter_unparsed(grub_cfg_main).splitlines()
+    search_root = next((x for x in unparsed if 'search' in x), '')
+    fields['search_root'] = search_root
 
     return fields
 
 
 def render_grub_cfg(root_dir: str = '') -> None:
     """Render grub.cfg for legacy compatibility"""
     if not root_dir:
         root_dir = disk.find_persistence()
 
     grub_cfg_main = f'{root_dir}/{grub.GRUB_CFG_MAIN}'
 
     fields = grub_cfg_fields(root_dir)
     render(grub_cfg_main, TMPL_GRUB_COMPAT, fields)
 
 
 def grub_cfg_update(func):
     """Decorator to update grub.cfg after function call"""
     @wraps(func)
     def wrapper(*args, **kwargs):
         ret = func(*args, **kwargs)
         if mode():
             render_grub_cfg()
         return ret
     return wrapper
diff --git a/src/system/grub_update.py b/src/system/grub_update.py
index da1986e9d..366a85344 100644
--- a/src/system/grub_update.py
+++ b/src/system/grub_update.py
@@ -1,107 +1,104 @@
 #!/usr/bin/env python3
 #
 # Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
 #
 # This file is part of VyOS.
 #
 # VyOS is free software: you can redistribute it and/or modify it under the
 # terms of the GNU General Public License as published by the Free Software
 # Foundation, either version 3 of the License, or (at your option) any later
 # version.
 #
 # VyOS is distributed in the hope that it will be useful, but WITHOUT ANY
 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 # details.
 #
 # You should have received a copy of the GNU General Public License along with
 # VyOS. If not, see <https://www.gnu.org/licenses/>.
 
 from pathlib import Path
 from sys import exit
 
 from vyos.system import disk, grub, image, compat, SYSTEM_CFG_VER
 from vyos.template import render
 
 
 def cfg_check_update() -> bool:
     """Check if GRUB structure update is required
 
     Returns:
         bool: False if not required, True if required
     """
     current_ver = grub.get_cfg_ver()
     if current_ver and current_ver >= SYSTEM_CFG_VER:
         return False
 
     return True
 
 
 if __name__ == '__main__':
     if image.is_live_boot():
         exit(0)
 
     # Skip everything if update is not required
     if not cfg_check_update():
         exit(0)
 
     # find root directory of persistent storage
     root_dir = disk.find_persistence()
 
     # read current GRUB config
     grub_cfg_main = f'{root_dir}/{grub.GRUB_CFG_MAIN}'
     vars = grub.vars_read(grub_cfg_main)
     modules = grub.modules_read(grub_cfg_main)
     vyos_menuentries = compat.parse_menuentries(grub_cfg_main)
     vyos_versions = compat.find_versions(vyos_menuentries)
     unparsed_items = compat.filter_unparsed(grub_cfg_main)
-
+    # compatibilty for raid installs
+    search_root = compat.get_search_root(unparsed_items)
+    common_dict = {}
+    common_dict['search_root'] = search_root
     # find default values
     default_entry = vyos_menuentries[int(vars['default'])]
     default_settings = {
         'default': grub.gen_version_uuid(default_entry['version']),
         'bootmode': default_entry['bootmode'],
         'console_type': default_entry['console_type'],
         'console_num': default_entry['console_num']
     }
     vars.update(default_settings)
 
-    # print(f'vars: {vars}')
-    # print(f'modules: {modules}')
-    # print(f'vyos_menuentries: {vyos_menuentries}')
-    # print(f'unparsed_items: {unparsed_items}')
-
     # create new files
     grub_cfg_vars = f'{root_dir}/{grub.CFG_VYOS_VARS}'
     grub_cfg_modules = f'{root_dir}/{grub.CFG_VYOS_MODULES}'
     grub_cfg_platform = f'{root_dir}/{grub.CFG_VYOS_PLATFORM}'
     grub_cfg_menu = f'{root_dir}/{grub.CFG_VYOS_MENU}'
     grub_cfg_options = f'{root_dir}/{grub.CFG_VYOS_OPTIONS}'
 
     Path(image.GRUB_DIR_VYOS).mkdir(exist_ok=True)
     grub.vars_write(grub_cfg_vars, vars)
     grub.modules_write(grub_cfg_modules, modules)
-    # Path(grub_cfg_platform).write_text(unparsed_items)
-    grub.common_write()
+    grub.common_write(grub_common=common_dict)
     render(grub_cfg_menu, grub.TMPL_GRUB_MENU, {})
     render(grub_cfg_options, grub.TMPL_GRUB_OPTS, {})
 
     # create menu entries
     for vyos_ver in vyos_versions:
         boot_opts = None
         for entry in vyos_menuentries:
             if entry.get('version') == vyos_ver and entry.get(
                     'bootmode') == 'normal':
                 boot_opts = entry.get('boot_opts')
         grub.version_add(vyos_ver, root_dir, boot_opts)
 
     # update structure version
     cfg_ver = compat.update_cfg_ver(root_dir)
     grub.write_cfg_ver(cfg_ver, root_dir)
 
     if compat.mode():
         compat.render_grub_cfg(root_dir)
     else:
         render(grub_cfg_main, grub.TMPL_GRUB_MAIN, {})
 
     exit(0)