This outlines how to get into the BIOS of the DS918+ using the serial header.
It is entirely possible this is done in a more complicated method than is required, but this is how I got it working and this is documenting that process
You'll need a FAT-formatted USB mounted at <YOUR_USB_MOUNT_DIR>
- You'll need to install packages to get grub and edk2 to build. I don't remember what they are with the exception of the x86_64 gcc cross-compiler
- You could probably skip building grub and just build the UEFI shell, but having the custom grub was useful when I was messing around with this
- If someone knows why my arrow keys didn't work with UEFI consoles set to a vt100, that would greatly simplify things
- When booting a non-DSM OS, the power LED kept blinking instead of going solid. Not sure what caused that
- There must be some setting I changed in the BIOS or UEFI shell as when I shut down the machine (either through
shutdownor holding the power button), it will immediately power back up - When booting into the BIOS the speaker really likes to beep a lot. I have no idea what causes it to happen or not
The DS918+ isn't limited to booting off of the USB DOM. You can boot off of any USB that has files of the following directory structure:
efi/
└── boot/
├── SynoBootLoader.efi
└── <Whatever config file the .efi is looking for>
There is some inconsistency on which USB device is probed first, but typically an external USB will be probed before the internal USB DOM
I used a Raspberry Pi 3 B for everything in this
Firstly, configure the rpi to have its serial enabled per raspi-config
| Raspberry Pi | DS918+ UART |
|---|---|
| pin 8 (TX) | pin 6 (RX) |
| pin 10 (RX) | pin 4 (TX) |
| pin 6 (GND) | pin 2 (GND) |
To connect:
screen /dev/serial0 115200
This should enable you to see the Synology GRUB menu when powering up the DS918+. It should look something like this:
GNU GRUB version 2.00
Press "CTRL-C" for boot menu or it boots automatically in 1s.
And when you press CTRL-C:
GNU GRUB version 2.00
+--------------------------------------------------------------------------+
|SYNOLOGY_1 |
|SYNOLOGY_2 |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
+--------------------------------------------------------------------------+
Use the ^ and v keys to select which entry is highlighted.
Press enter to boot the selected OS, `e' to edit the commands
before booting or `c' for a command-line.
We need a new GRUB so that we can chainload into a UEFI shell. The GRUB included with the DS918+ doesn't have the chain module. We can either build/find modules compatible with GRUB 2.00 (which is possible) but I found it simpler to simply build a GRUB 2.12
This is built on a Raspberry Pi 3 B, so make sure you have an x86_64 gcc cross compiler installed
Synology included some custom GRUB modules, some that are used in the boot process, and more relevant in this case, the Serial module. The Serial module is needed because until recently you couldn't specify a serial port through a PCI or UART address, but modern GRUB takes care of that.
Important: While the GRUB manual says you can use --port=pci,XX:XX.X, I wasn't able to get that to work in this case and had to use the UART addressing. The included grub.cfg contains code to identify the UART address for the default serial port of the DS918+ (00:18.2)
cd grub
./bootstrap
./configure --target=x86_64-linux-gnu --with-platform=efi
make -j
Next we need to build an .efi to copy onto our USB.
You can either bake in the required modules (what the block shows) or you can copy all the modules from grub-core onto the USB using something like cp grub-core/*.mod <YOUR_USB_MOUNT_DIR>/efi/boot/x86_64-efi/
# This is the list of modules from the default `SynoBootLoader.efi` minus the `serial` and `syno` modules
export default_mods="boot bufio crypto datetime echo ext2 extcmd fat fshelp gettext help linux minicmd mmap multiboot net normal part_gpt part_msdos priority_queue reboot relocator search_fs_file search_fs_uuid search_label search terminal terminfo video"
# Don't *need* efifwsetup but it's nice to have
export added_mods="serial chain efifwsetup"
./grub-mkimage -d grub-core -p /efi/boot -O x86_64-efi -o SynoBootLoader.efi $default_mods $added_mods
cp SynoBootLoader.efi <YOUR_USB_MOUNT_DIR>/efi/boot/
unset added_mods
unset default_mods
This grub will look for /efi/boot/grub.cfg as the config file. The grub.cfg in this repo will drop you right into the grub prompt
Because the chain module is baked in to this grub, you're able to chainload whatever you want which is useful in this case, as we want to chainload a UEFI shell.
There actually is a UEFI shell built in to the DS918+. But it's both heavily restricted and useless if you can't get any I/O.
In this case we build a new UEFI shell with a handful of useful modules and then chainload into it from the GRUB we just built.
edk2 has newer methods of building than the method I use, but I couldn't get those to work so this details the old method of building edk2.
# from project root
cd edk2
# If not cloned with recursive
git submodule init
git submodule update
make -C BaseTools
source edksetup.sh
To build the shell and modules:
(The trailing - is needed in the GCC_BIN assignment)
GCC_BIN=x86_64-linux-gnu- build -a X64 -b RELEASE -t GCC -p ShellPkg/ShellPkg.dsc
GCC_BIN=x86_64-linux-gnu- build -a X64 -b RELEASE -t GCC -p MdeModulePkg/MdeModulePkg.dsc
We only need the shell and a few modules. The shell goes into /efi/boot/ on the USB and the modules can go in any directory on the USB device.
cp Build/Shell/RELEASE_GCC/X64/ShellPkg/Application/Shell/Shell/OUTPUT/Shell.efi <YOUR_USB_MOUNT_DIR>/efi/boot/
mkdir -p <YOUR_USB_MOUNT_DIR>/efi/tools/ #if it doesn't exist
cp Build/MdeModule/RELEASE_GCC/X64/SerialDxe.efi <YOUR_USB_MOUNT_DIR>/efi/tools/
cp Build/MdeModule/RELEASE_GCC/X64/TerminalDxe.efi <YOUR_USB_MOUNT_DIR>/efi/tools/
# If you don't care about booting off of NVMe drives you can skip this
cp Build/MdeModule/RELEASE_GCC/X64/NvmExpressDxe.efi <YOUR_USB_MOUNT_DIR>/efi/tools/
# This file will run when you chainload Shell.efi and will set up the serial I/O
cp ../serial-startup.nsh <YOUR_USB_MOUNT_DIR>/efi/boot/startup.nsh
Your USB should look something like this:
/efi/
├── boot
│ ├── grub.cfg
│ ├── Shell.efi
│ ├── startup.nsh
│ └── SynoBootLoader.efi
└── tools
├── NvmExpressDxe.efi
├── SerialDxe.efi
└── TerminalDxe.efi
From the grub shell:
chainloader /efi/boot/Shell.efi
boot
The first time the chainloading, the startup.nsh script will execute, putting you back in the grub prompt.
Important: You may need to run reset in grub after running the chainload to make the console mappings propagate
Run the chainload command again. If you don't get output similar to the following, check your USB directory structure.
UEFI Interactive Shell v2.2
EDK II
UEFI v2.50 (INSYDE Corp., 0x57301018)
Mapping table
FS0: Alias(s):HD0d0b:;BLK1:
PciRoot(0x0)/Pci(0x15,0x0)/USB(0x3,0x0)/HD(1,GPT,52E06AC1-951D-4BAC-9B18-3F0821438255,0x800,0x10000)
FS1: Alias(s):HD0i0b:;BLK4:
PciRoot(0x0)/Pci(0x15,0x0)/USB(0x8,0x0)/HD(1,GPT,351A076A-604C-4230-9E5E-2E5FD9D7C73B,0x800,0x1D327B0)
BLK0: Alias(s):
PciRoot(0x0)/Pci(0x15,0x0)/USB(0x3,0x0)
BLK2: Alias(s):
PciRoot(0x0)/Pci(0x15,0x0)/USB(0x3,0x0)/HD(2,GPT,99421BB0-B00A-430C-BCDE-E41AB10FE55D,0x10800,0x2A000)
BLK3: Alias(s):
PciRoot(0x0)/Pci(0x15,0x0)/USB(0x8,0x0)
Press ESC in 5 seconds to skip startup.nsh or any other key to continue.
Press ESC. If you're luckier than I was, you can try running reset -fwui. In my experience it will either:
- Bring you to the BIOS menu but you won't be able to use your arrow keys (if your
startup.nshis setting the terminal to vt100 - not what theserial-startup.nshdoes by default) - Look like nothing's happening as you're using TTY Term which requires a different serial driver be loadet
To boot into the BIOS with the proper drivers loaded you have two options:
As the DS918+ looks for SynoBootLoader.efi, we rename our Shell.efi. This then will run the startup.nsh script, load the drivers, and exit, which drops you into the BIOS menu
# On your host machine with your USB mounted
mv <YOUR_USB_MOUNT_DIR>/efi/boot/Shell.efi <YOUR_USB_MOUNT_DIR>/efi/boot/SynoBootLoader.efi
With this you need to
- Figure out what device your
Shell.efiis on - Add a boot option as the first option
This method tends to be more fragile as if you add/remove devices, the boot option tends to disappear.
# In the UEFI shell
map -c
# Find the device that has your Shell.efi file through ls on each of the devices printed in the mapping table
# In my case the device is HD0i0b
bcfg boot add 0 HD0i0b:\efi\boot\Shell.efi "UEFI Shell"
reset
Regardless of which option you used, you should be presented with a BIOS screen on boot/reboot:
Front Page
Front Page
┌────────────────────────────────────────────────────────────────────────────────────┬─────────────────────────────────────────┐
│Continue │This selection will direct the system to │
│>Boot Manager │continue to booting process │
│>Device Manager │ │
│>Boot From File │ │
│>Administer Secure Boot │ │
│>Setup Utility │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
└────────────────────────────────────────────────────────────────────────────────────┴─────────────────────────────────────────┘
F1 Help Enter Select > SubMenu
^/v Select Item
Go into Setup Utility to configure any options. In particular, Advanced > Console Redirection to turn on console redirection in the BIOS so that if your UEFI variables get reset you can still go into the BIOS. (Note: This will change your terminal type from TTY to vt100)
Important: If you turn on console redirection, make sure you set AutoRefresh to Disabled otherwise the BIOS will put some character on your screen which ruins the commands you're trying to type in grub or UEFI.