I have standard dual-boot system: Ubuntu and Windows. Grub is configured to launch Windows by default.
Is there a way to create some kind of link in Windows, that would:
- restart Windows
- boot into Ubuntu
I have standard dual-boot system: Ubuntu and Windows. Grub is configured to launch Windows by default.
Is there a way to create some kind of link in Windows, that would:
You don't need to modify /boot/grub/grub.cfg like Michal Hagara suggested. This could break Ubuntu if you install a new kernel and doesn't update the e:\home\user\Grubshift\ubuntudefault\grub.cfg.
All you need to do is to create/copy a file /boot/grub/grubenv with following content
# GRUB Environment Block
next_entry=2
###########################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################
Where next_entry is the line of the next grub menu entry which should be started next time (starting from zero). So next_entry=2 would be the 3th line.
Grub will automatically remove the value after boot so next time you'll boot into your default OS again.
This is how grub-reboot works.
Here is what I have in mind:
I can be completely wrong with this approach, but I can't see, why it shouldn't work.
EDIT:
And also there is: http://www.paragon-drivers.com/extfs-windows/ which I have never tried.
1.Shortcut to restart Windows and boot Ubuntu
OK, down side of this is we will have to modify grub.cfg (/boot/grub/grub.cfg) directly (it is advised against - https://askubuntu.com/a/437341/402801),because there is no way to run update-grub from Windows... if you can live with that read further.
/home/user/Grubshift with 3 sub directories: backup (for backing up actual /boot/grub/grub.cfg), ubuntudefault (for storing grub.cfg with Ubuntu as default), windowsdefault (you've got the idea)After installation, Ubuntu is set as default, so copy that grub.cfg to your desired directory. I've got "Windows as default" config by modifying GRUB via grub-customizer (it's safer in my opinion), after that copy Windows grub.cfg to your desired directory
After that, open notepad and insert:
copy e:\boot\grub\grub.cfg /y e:\home\user\Grubshift\backup
copy e:\home\user\Grubshift\ubuntudefault\grub.cfg /y e:\boot\grub
shutdown /r /t 0
/y - option of copy command, suppresses prompting to confirm you want to overwrite an existing destination file
/r /t 0 - options of shutdown, 1. means reboot, 2. means immediately, without ugly messages popping up
Modify the path accordingly !!!
*.batshift.bat, right click on shorctur --> properties--> shortcut tab --> Run:minimized (that will get rid of CMD popping up)I have tried this at least 8 times, setting Windows as default
with grub-customizer ...
I'm not saying it's safe, but HEY!, we are messing with bootloader... that isn't safe
When it's fully working, we can get rid of GRUB menu completely, because it will always boot into right OS...
To sum it up: System reboots default to last active, reboots from windows to linux and vice versa using a simple script.
Under linux:
GRUB_DEFAULT=saved and GRUB_SAVEDEFAULT=true in /etc/default/grub sudo update-grubsee http://www.paragon-drivers.com/extfs-windows/
If /boot/grub/grubenv doesn't exist, create it using the answer from Germar
@echo off
"C:\Program Files (x86)\Paragon Software\ExtFS for Windows\extmounter" /mount disk1 L:
:CheckForFile
IF EXIST "L:\boot\grub\grubenv" GOTO FoundIt
GOTO CheckForFile
:FoundIt
sed -i -e '/next_entry/c\next_entry=0' L:/boot/grub/grubenv
"C:\Program Files (x86)\Paragon Software\ExtFS for Windows\extmounter" /umount disk1 L:
echo press enter to reboot
pause
shutdown -r -t 00
/mount disk1 L: with something specific to your system. You can find available disks using the extmounter /list command and the drive letter. Also, L: must not be already taken.reboot-linux.batrun as administrator to execute it sudo sed -i -e '/next_entry/c\next_entry=2' /boot/grub/grubenv
sudo reboot
next_entry=2 with whatever your windows entry is. ~/reboot_windows and mark as executable: chmod +x ~/reboot_windowsI use Arch instead of Ubuntu but the GRUB configuration should be the same.
What I don't really like about the previous anwsers is that they:
grub.cfg file directly, which is intended for permanent changesgrubenv in a way that corrupts the GRUB environment block, which results in warnings on Linux boot and breaks the grub-editenv commandSo first of all you need to setup GRUB to remeber the last system booted to (it's convenient for reboots anyway):
GRUB_DEFAULT=saved and GRUB_SAVEDEFAULT=true in
/etc/default/grubsudo update-grub (on Arch it's grub-mkconfig)There's this convenient command called grub-reboot which lets you one-shot boot into Windows. Very handy. Note that this keeps the last saved entry in GRUB, so when you go like Linux>grub-reboot to Windows>Windows>reboot it will reboot you back to Linux. To override this (unwanted IMO) behavior add another command afterward like this:
grub-reboot $name
grub-editenv /boot/grub/grubenv set saved_entry=$name
where $name is the name of Windows as it appears in GRUB. I explain it in detail below. After running these commands reboot the system.
So I decided to investigate what the Linux script does. It calls grub-editenv and sets the value of next_entry to the desired OS. I spent a few hours doing trial and error editing the grubenv file trying to replicate the result and managed to come up with a solution. It turns out that the GRUB environment block should always be kept exactly 1024 bytes long, that's why there are # signs at the end by default. Here's my PowerShell script. It might be a bit verbose but it gets the job done correctly.
function Get-ArrLength {
param (
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[string[]]$arr
)
$text = [string]::Join("`n", $arr)
($text | Measure-Object -Character).Characters
}
mountvol P: /S
P:
cd grub
cp grubenv grubenv.bak
$name = "Arch Linux"
$name_len = ($name | Measure-Object -Character).Characters
$arr = cat grubenv
$original_length = Get-ArrLength $arr
$arr = $arr -replace "next_entry=","next_entry=$name"
foreach ($a in $arr) {
if ($a -match "saved_entry=") {
$arr[$arr.IndexOf($a)] = "saved_entry=$name"
}
}
$candidate_length = Get-ArrLength $arr
if ($candidate_length -gt $original_length) {
$arr[$arr.Count-1] = $arr[$arr.Count-1].SubString(0,$arr[$arr.Count-1].Length-($candidate_length-$original_length))
} elseif ($candidate_length -lt $original_length) {
$arr[$arr.Count-1] = $arr[$arr.Count-1] + "#" * ($original_length-$candidate_length)
}
$contenttext = [string]::Join("`n", $arr)
sc grubenv ([byte[]][char[]] "$contenttext") -Encoding Byte
Restart-Computer
$name with the name of your installation
as it appears in GRUB. If it's within a GRUB subfolder, use the >
character as a path separator like so:
$name="subfolder_name>OS_entry_name". Instead of names you can also
use numbers where 0 is the first item as it appears in the GRUB
menu but going with names is more versatile should the entries order
change.P: in the lines mountvol P: /S and the following
is completely arbitrary and you can change it to any drive letter
that's available on your Windows system.Restart-Computer if you only want to change the GRUB entries and later reboot manually.grubenv.bak so if anything goes wrong you can always restore it by simply copying it back to grubenv.