-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2157189
commit a72e007
Showing
9 changed files
with
783 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
build | ||
.vscode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#! /bin/sh | ||
exec tail -n +3 ${0} | ||
# Look for hardware switch device by its hard-coded filesystem ID | ||
search --no-floppy --label --set hdswitch GRUB-SWITCH | ||
|
||
# If found, read dynamic config file and select appropriate entry for each position | ||
if [ "${hdswitch}" ] ; then | ||
source ($hdswitch)/switch.cfg | ||
|
||
if [ "${os_hw_switch}" == "l" ] ; then | ||
# Boot Linux | ||
set default="0" #change this to your Linux entry number | ||
set timeout=0 | ||
elif [ "${os_hw_switch}" == "w" ] ; then | ||
# Boot Windows | ||
set default="2" #change this to your windows entry number | ||
set timeout=0 | ||
elif [ "${os_hw_switch}" == "s" ] ; then | ||
# default with infinite timeout | ||
set default="${GRUB_DEFAULT}" | ||
set timeout=-1 | ||
else | ||
# Fallback to default | ||
set default="${GRUB_DEFAULT}" | ||
set timeout="${GRUB_TIMEOUT}" | ||
fi | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
cmake_minimum_required(VERSION 3.13...3.27) | ||
|
||
set(PROJECT_NAME grubswitch) | ||
|
||
|
||
#pull in the PICO SDK | ||
include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake) | ||
|
||
project(${PROJECT_NAME} C CXX ASM) | ||
set(CMAKE_C_STANDARD 11) | ||
set(CMAKE_CXX_STANDARD 17) | ||
|
||
set(PICO_EXAMPLES_PATH ${PROJECT_SOURCE_DIR}) | ||
|
||
#init the sdk | ||
pico_sdk_init() | ||
|
||
add_executable(${PROJECT_NAME} | ||
src/main.c | ||
src/msc_disk.c | ||
src/usb_descriptors.c | ||
) | ||
|
||
target_include_directories(${PROJECT_NAME} PRIVATE | ||
src/) | ||
|
||
#pull in pico_stdlib | ||
target_link_libraries(${PROJECT_NAME} pico_stdlib tinyusb_device) | ||
|
||
# pico_enable_stdio_usb(${PROJECT_NAME} 0) | ||
# pico_enable_stdio_uart(${PROJECT_NAME} 1) | ||
|
||
#create uf2 | ||
pico_add_extra_outputs(${PROJECT_NAME}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# GRUB switch | ||
|
||
This is a simple physical switch to control GRUB2 inspired by a [simplar project | ||
for STM32](https://github.com/stecman/hw-boot-selection), but implemented on the | ||
Raspberry Pi Pico (developed on RP2040-Zero, but any Pico should be good). | ||
|
||
The code is using an SPDT On-Off-On switch, one side selects Linux, the other | ||
Windows, while in the middle selection, the GRUB menu stays on indefinately - | ||
but this should be very easy to modify. | ||
|
||
I needed this, because I have a strange dual boot setup where my monitor usually | ||
turns on with the input that is not the default from my UEFI setup. | ||
|
||
## Build and install | ||
|
||
An uf2 binary is available as release for easy testing. | ||
|
||
Install the [pico-SDK](https://github.com/raspberrypi/pico-sdk), cmake and | ||
arm-eabi-gcc. | ||
|
||
Make sure to set the environemnt variable PICO_SDK_PATH to point the folder | ||
where your pico-SDK is (e.g. `export PICO_SDK_PATH=/usr/share/pico-sdk`). | ||
|
||
Then continue with the usual cmake setup: | ||
|
||
```bash | ||
mkdir build | ||
cd build | ||
cmake .. | ||
make | ||
``` | ||
|
||
Finally, install the generated `build/grubswitch.uf2` on the Pico. It will | ||
reboot as a FAT16 drive, labeled "GRUB-SWITCH". | ||
|
||
The switch should be connected to pin28 and pin29 if the code is used | ||
unmodified. | ||
|
||
## Setup GRUB | ||
|
||
Copy [49_switch](49_switch) to `/etc/grub.d`. Modify the entry numbers | ||
highlighted with comments. Make sure it's executable and run `update-grub` as | ||
root. | ||
|
||
## Modification | ||
|
||
The letters set by the switch are defined in [msc_disk.h](src/msc_disk.h). The | ||
switch is read in [main.c](src/main.c). The filesystem and filename are defined | ||
in [msc_dis.c](src/msc_disk.c) - although I wouldn't recommend changing this | ||
unless you have to. | ||
|
||
## Inspiration | ||
|
||
This project was developed based on the following: | ||
|
||
* [The ST implementation of the same | ||
idea](https://github.com/stecman/hw-boot-selection) | ||
* [Another pico | ||
implementation](https://www.hackster.io/Madrajib/hardware-boot-select-switch-using-pico-a3e3d5) | ||
I just didn't like that it's a documentation on how to modify an example | ||
* [A nice demonstration project of USB | ||
MSC](https://github.com/brendena/pico_drag_n_drop_programmer) with a lot of | ||
links and explanation video. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
#include "tusb.h" | ||
#include "pico/stdlib.h" | ||
#include "msc_disk.h" | ||
|
||
#define GPIO_LINUX 28 | ||
#define GPIO_WINDOWS 29 | ||
|
||
/*------------- MAIN -------------*/ | ||
int main(void) | ||
{ | ||
|
||
// init device stack on configured roothub port | ||
tusb_init(); | ||
|
||
gpio_init(GPIO_LINUX); | ||
gpio_init(GPIO_WINDOWS); | ||
gpio_set_dir(GPIO_LINUX, false); | ||
gpio_set_dir(GPIO_WINDOWS, false); | ||
gpio_pull_up(GPIO_LINUX); | ||
gpio_pull_up(GPIO_WINDOWS); | ||
|
||
|
||
while (1) | ||
{ | ||
tud_task(); // tinyusb device task | ||
|
||
if ( !gpio_get(GPIO_LINUX) && !gpio_get(GPIO_WINDOWS)){ | ||
setSwitchValue(CONFIG_DEFAULT); | ||
} else if ( !gpio_get(GPIO_LINUX)){ | ||
setSwitchValue(CONFIG_LINUX); | ||
} else if ( !gpio_get(GPIO_WINDOWS)){ | ||
setSwitchValue(CONFIG_WINDOWS); | ||
} else { //neither are pulled down, switch in the middle | ||
setSwitchValue(CONFIG_STOP); | ||
} | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
//--------------------------------------------------------------------+ | ||
// Device callbacks | ||
//--------------------------------------------------------------------+ | ||
|
||
// Invoked when device is mounted | ||
void tud_mount_cb(void) | ||
{ | ||
} | ||
|
||
// Invoked when device is unmounted | ||
void tud_umount_cb(void) | ||
{ | ||
} | ||
|
||
// Invoked when usb bus is suspended | ||
// remote_wakeup_en : if host allow us to perform remote wakeup | ||
// Within 7ms, device must draw an average of current less than 2.5 mA from bus | ||
void tud_suspend_cb(bool remote_wakeup_en) | ||
{ | ||
(void) remote_wakeup_en; | ||
} | ||
|
||
// Invoked when usb bus is resumed | ||
void tud_resume_cb(void) | ||
{ | ||
} |
Oops, something went wrong.