Author Topic: Hardwere switch for dual boot.  (Read 5619 times)

0 Members and 1 Guest are viewing this topic.

Offline georgianTopic starter

  • Regular Contributor
  • *
  • Posts: 54
  • Country: at
Hardwere switch for dual boot.
« on: October 18, 2020, 08:34:58 pm »
Hello guys,

dose anybody know a "easy" solution for an hardware switch dual boot?
I could use an spdt switch to switch between two ssds before each boot but this way it will require one more ssd for shared data. If there is any other way to monitor the DTR pin from RS-232 port (or something like this) on each boot and then automatically selected the OS to boot accordingly, i could use only one SSD with one extra partition for shared data. I want to have windows server and Linux saver to learn and play with. I don't plan to keep the server near my working PC and have a keyboard and monitor attached each time I want to chose the OS.

Maybe there is any software that dose it and have it running on each OS, like apple has the bootcamp thing. This way i could reboot in another OS remotely.

Thank you in advance,
Georgian.
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 13026
Re: Hardwere switch for dual boot.
« Reply #1 on: October 18, 2020, 09:40:45 pm »
Probably the easiest option would be to program an ATmega32U4 based Arduino (e.g Leonardo or Micro) to emulate a HID keyboard, read the switch and send the required keystrokes to select an OS to a boot manager e.g. GNU GRUB.

Alternatively, GRUB can be fully controlled from a serial console, which you could access over a hard-wired connection or via a TCP/IP to serial  bridge.
« Last Edit: October 18, 2020, 09:43:28 pm by Ian.M »
 
The following users thanked this post: georgian

Offline Zbig

  • Frequent Contributor
  • **
  • Posts: 927
  • Country: pl
Re: Hardwere switch for dual boot.
« Reply #2 on: October 18, 2020, 09:48:21 pm »
Do you have any specific use case or requirement to go for dual boot instead of virtualization in this day and age?
 
The following users thanked this post: georgian

Offline georgianTopic starter

  • Regular Contributor
  • *
  • Posts: 54
  • Country: at
Re: Hardwere switch for dual boot.
« Reply #3 on: October 18, 2020, 10:17:17 pm »
Thank you for your answers.
I did think about the Leonardo as keyboard. The GNU grub method sounds good too. I have an industrial motherboard that i want to use and there is a custom bios on it without access to any settings. Just load setup defaults and save the settings. I'll see if this method works and if so how to chose what to boot.

There is no specific or use case. For now I'm using a raspberry pi as server to test C cgi code and and learn some mysql. The pi lacks support for windows server and I want to play around with windows server too. I don't have modern hardware to support virtualization.
 

Offline Red Squirrel

  • Super Contributor
  • ***
  • Posts: 2751
  • Country: ca
Re: Hardwere switch for dual boot.
« Reply #4 on: October 19, 2020, 01:16:32 am »
One way might be to keep both OS drives plugged in, but have a A/B switch that provides power to only one at a time.  I think that would work.

As for VMs sometimes there is a need to have raw level access, such as if it's a workstation or for gaming.  Working out of a VM is kinda cumbersome and you need some form of physical machine to physically interact with anyway.   
 
The following users thanked this post: I wanted a rude username

Offline rdl

  • Super Contributor
  • ***
  • Posts: 3667
  • Country: us
Re: Hardwere switch for dual boot.
« Reply #5 on: October 19, 2020, 01:53:41 am »
I have a machine with an Icy Dock in one of the front bays. It's a two slot 3.5 inch. I just insert whichever drive I want to boot from. I think switching the power would work as well.
 

Offline bw2341

  • Regular Contributor
  • *
  • Posts: 163
  • Country: ca
Re: Hardwere switch for dual boot.
« Reply #6 on: October 19, 2020, 05:15:52 am »
One way might be to keep both OS drives plugged in, but have a A/B switch that provides power to only one at a time.  I think that would work.
You can buy one! Search for "hard drive power switch" on Ebay or Aliexpress. You'll get no name switch boxes that fit in a drive bay or back panel card slot. I haven't used any of these myself.

The last time I was looking for these, I remember seeing fancy models with MOSFET switching and soft touch buttons. It looks like we're left with the cheap passive physical switch models now.
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6762
  • Country: fi
    • My home page and email address
Re: Hardwere switch for dual boot.
« Reply #7 on: October 19, 2020, 05:47:53 am »
Assuming it has free USB ports, I would use an ATtiny85 (a DigiSpark clone) with micronucleus on it (e.g, by getting a DigiSpark clone and programming it in the Arduino environment), and a slightly modified Grub to boot it.

You see, Grub has grub-core/commands/usbtest.c which only needs small changes to become a Grub scripting command that returns if an USB device with a specific vendor:product and version string is found.  That way, a simple Grub snippet can change the default OS to be booted, without interfering with the keyboard etc.

The DigiSpark clones (costing < USD $2 / EUR 2€ on eBay) have 5 free GPIO pins, so I'd connect a coded rotary switch – or, if you really just need to choose between two or three, a toggle switch – to (some) of the pins.  (The three-way one you wire backwards, with its common to e.g. VCC, and the three to separate GPIO pins, with pulldowns enabled or external pulldown resistors.  That way, exactly one of the pins is high with the two others low, depending on the switch state.)  Coded rotary switches with 2n positions typically have n+1 (or n+2) pins, with the common pin going to VCC or GND, and the other pins connected or disconnected based on the switch state.  (I used one on my first ATmega32u4-based USB Arcade Joystick, to choose the keycodes it would produce.)

When the DigiSpark is powered up, I'd have it report a specific (custom) Vendor:Product, with a version number depending on the GPIO pin states.  Optionally, if the pin states change, it'd simply detach and re-enumerate itself.

This way, the boot switch would not interfere with anything at all.  The Grub changes are quite simple, and the developers might even accept the new command – say, usb-find --vendor VVVV --product PPPP --serial S... which returns True if such an USB device is connected, and False otherwise – upstream, so you wouldn't have to re-add the command in everytime you update grub (which should be very rarely, though).

It'd make for a very interesting and not too hard project, if you're interested in microcontrollers (or Arduino environment programming), and don't mind patching Grub.  (It's not really a change per se, more an addition to the Grub sources.)
 
The following users thanked this post: I wanted a rude username

Offline bitwelder

  • Frequent Contributor
  • **
  • Posts: 972
  • Country: fi
Re: Hardwere switch for dual boot.
« Reply #8 on: October 19, 2020, 10:51:48 am »
I'm not sure that I understand the way it should be controlled, but in one case I set up a 'remote' lab PC that had two harddisks, one with Linux and one with Windows.
The Linux side had boot entries for both itself and the Windows side, and so it was possible to 'program' next boot with the command "grub2-reboot <boot-entry>". Only downside was that it took just an extra boot cycle to go from Windows to Windows again.
 
The following users thanked this post: georgian

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6762
  • Country: fi
    • My home page and email address
Re: Hardwere switch for dual boot.
« Reply #9 on: October 19, 2020, 12:47:32 pm »
Wait, does the board have a physical RS-232 serial port, with an 8250/16550 compatible UART, on the motherboard?

If it does, then you indeed can just use one of the status pins on that port, if you make sure the Grub iorw module (iorw.mod) is enabled.  Then,
    inb -v MCE 0x3FE        (for first serial port)
    inb -v MCE 0x2EE        (for second serial port)
    inb -v MCE 0x2FE        (for third serial port)
    inb -v MCE 0x3EE        (for fourth serial port)
saves the port status pin states in Grub variable MCE, in hexadecimal, without a leading 0x.  The four low bits should be zero.  The high four bits correspond to CTS (bit 4), DSR (bit 5), RI (bit 6), and DCD (bit 7).  On an 9-pin serial connector, CTS is pin 8, DSR is pin 6, RI is pin 9, and DCD is pin 1; except that pin 1 and/or pin 9 may be connected to a positive supply voltage.

So, let's say you connect a SPDT switch, common to pin 8 on the 9-pin serial port connector, and the two options to pin 5 (signal ground) and pin 1 or 9, whichever has a positive voltage on it.  In your Grub configuration file,
    serial --unit=0
    inb -v MCE 0x3FE
    set MCE=0x$MCE
    if [ $MCE -eq 16 -o $MCE -eq 48 -o $MCE -eq 80 -o $MCE -eq 112 -o $MCE -eq 144 -o $MCE -eq 176 -o $MCE -eq 204 -o $MCE -eq 240 ]; then
        set default=1
    else
        set default=0
    fi
and the default will be either the first or the second boot entry, depending on the position of the switch.

If you do the same for pin 6 as you did for pin 8 above, then
    serial --unit=0
    inb -v MCE 0x3FE
    set MCE=0x$MCE
    if [ $MCE -eq 16 -o $MCE -eq 80 -o $MCE -eq 144 -o $MCE -eq 208 ]; then
        set default=1
    elif [ $MCE -eq 32 -o $MCE -eq 96 -o $MCE -eq 160 -o $MCE -eq 224 ]; then
        set default=2
    elif [ $MCE -eq 48 -o $MCE -eq 112 -o $MCE -eq 176 -o $MCE -eq 240 ]; then
        set default=3
    else
        set default=0
    fi
gives you four possibilities.  Note that one switch could be for a "fast boot" to the selected OS, with no wait in Grub, and the other just selects the boot entry.
« Last Edit: October 19, 2020, 12:49:22 pm by Nominal Animal »
 
The following users thanked this post: georgian

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: Hardwere switch for dual boot.
« Reply #10 on: October 19, 2020, 08:17:12 pm »
If you install an ext3/4 driver in Windows, it should be possible to set the next_entry variable in grub's environment file to select which OS will be started on next boot.
 
The following users thanked this post: georgian

Offline georgianTopic starter

  • Regular Contributor
  • *
  • Posts: 54
  • Country: at
Re: Hardwere switch for dual boot.
« Reply #11 on: October 19, 2020, 08:39:29 pm »
Wait, does the board have a physical RS-232 serial port, with an 8250/16550 compatible UART, on the motherboard?

If it does, then you indeed can just use one of the status pins on that port, if you make sure the Grub iorw module (iorw.mod) is enabled.  Then,
    inb -v MCE 0x3FE        (for first serial port)
    inb -v MCE 0x2EE        (for second serial port)
    inb -v MCE 0x2FE        (for third serial port)
    inb -v MCE 0x3EE        (for fourth serial port)
saves the port status pin states in Grub variable MCE, in hexadecimal, without a leading 0x.  The four low bits should be zero.  The high four bits correspond to CTS (bit 4), DSR (bit 5), RI (bit 6), and DCD (bit 7).  On an 9-pin serial connector, CTS is pin 8, DSR is pin 6, RI is pin 9, and DCD is pin 1; except that pin 1 and/or pin 9 may be connected to a positive supply voltage.

So, let's say you connect a SPDT switch, common to pin 8 on the 9-pin serial port connector, and the two options to pin 5 (signal ground) and pin 1 or 9, whichever has a positive voltage on it.  In your Grub configuration file,
    serial --unit=0
    inb -v MCE 0x3FE
    set MCE=0x$MCE
    if [ $MCE -eq 16 -o $MCE -eq 48 -o $MCE -eq 80 -o $MCE -eq 112 -o $MCE -eq 144 -o $MCE -eq 176 -o $MCE -eq 204 -o $MCE -eq 240 ]; then
        set default=1
    else
        set default=0
    fi
and the default will be either the first or the second boot entry, depending on the position of the switch.

If you do the same for pin 6 as you did for pin 8 above, then
    serial --unit=0
    inb -v MCE 0x3FE
    set MCE=0x$MCE
    if [ $MCE -eq 16 -o $MCE -eq 80 -o $MCE -eq 144 -o $MCE -eq 208 ]; then
        set default=1
    elif [ $MCE -eq 32 -o $MCE -eq 96 -o $MCE -eq 160 -o $MCE -eq 224 ]; then
        set default=2
    elif [ $MCE -eq 48 -o $MCE -eq 112 -o $MCE -eq 176 -o $MCE -eq 240 ]; then
        set default=3
    else
        set default=0
    fi
gives you four possibilities.  Note that one switch could be for a "fast boot" to the selected OS, with no wait in Grub, and the other just selects the boot entry.

This looks exactly like what I imagine. Doesn't sound very easy but i'll get there. I have to wait for my windows server DVD to arrive and I should be up and running. The motherboard has 4 physical RS-232 serial ports on board. No DB-9 socket on the it but all on one 40 pin header. No idea if they are 8250/16550 compatible, but why shouldn't they be?

To pull the pins high or low i will be using some esp-07 and small signal relays.

Thank you all so far and i'll be reporting my progress soon.
 

Offline NiHaoMike

  • Super Contributor
  • ***
  • Posts: 9184
  • Country: us
  • "Don't turn it on - Take it apart!"
    • Facebook Page
Re: Hardwere switch for dual boot.
« Reply #12 on: October 20, 2020, 03:19:48 am »
As for VMs sometimes there is a need to have raw level access, such as if it's a workstation or for gaming.  Working out of a VM is kinda cumbersome and you need some form of physical machine to physically interact with anyway.   
Might want to look at something like Xen which is designed to work at a much lower level than your typical VM solutions.
Cryptocurrency has taught me to love math and at the same time be baffled by it.

Cryptocurrency lesson 0: Altcoins and Bitcoin are not the same thing.
 

Offline Ed.Kloonk

  • Super Contributor
  • ***
  • Posts: 4000
  • Country: au
  • Cat video aficionado
Re: Hardwere switch for dual boot.
« Reply #13 on: October 20, 2020, 03:34:15 am »
Not sure how much cost might be a factor but I wanted to point out that the modern single board computers can mean you could have a discrete Linux system running for nearly the price of a hardware switching solution.

If you're interested, check out explaining computers on youtube for some honest reviews on the latest gizmos. You can evaluate if you want to keep going with x86 or select an ARM based board if you can select a suitable distro.

https://explainingcomputers.com/
iratus parum formica
 

Offline Berni

  • Super Contributor
  • ***
  • Posts: 5017
  • Country: si
Re: Hardwere switch for dual boot.
« Reply #14 on: October 20, 2020, 04:29:28 am »
As for VMs sometimes there is a need to have raw level access, such as if it's a workstation or for gaming.  Working out of a VM is kinda cumbersome and you need some form of physical machine to physically interact with anyway.

There is VM software out there that can pass trough devices into the VM. Most VMs support USB passtrough, but some also support entire PCIe slots to be put into the VM.

For example LinusTechTips used KVM to run 10 full on gaming VMs on a single CPU:
https://linustechtips.com/main/topic/599553-8-or-is-it-10-gamers-1-cpu/

Granted it did take a monsterous CPU to run that many threads and a weird motherboard to provide enough PCIe slots for that many graphics cards plus USB controllers for that many VMs. Such niche odd hardware was also a lot of headace to configure correctly. But in the end it worked, 10 gaming VMs running off a single PC and running modern games perfectly smoothly at full performance with no latency or stutter issues.

With KVM its possible to auto start and passtrough everything on startup. So you can even make a PC that starts botting trough a linux console, then suddenly shows the Windows 10 startup screen and boots into it and keeps running like that. Once booted you wouldn't even know you are inside a VM as all the USB ports would work as expected, only thing is that you would be missing some CPU threads. All while in the background KVM is also running 2 other linux VMs in the background of what is seemingly a Windows 10 PC once booted.

Besides when it comes to servers most of it runs of VMs anyway. The performance penalty of a VM is next to zero due to every modern CPU having hardware support for virtualization while running servers as VMs makes working with them a lot easier. They can be moved onto new faster hardware without the server even noticing or even having been shut down. If the server crashes to a point it wont even boot you can still remotely fix everything easily by just rolling the VM back to a known working state at the click of a button. Updates can be applied to a clone of the VM and tested they work before swapping that VM into live production. Servers for different tasks can be easily kept separated without needing multiple physical machines, so if one crashes or gets hacked or whatever bad happens to it the other servers keep running. On larger scales where multiple machines run multiple VMs then if one machine catches fire the VMs can be moved over to other machines automatically and restarted, once the machine is fixed and back up the VMs can be moved back onto it....etc
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6762
  • Country: fi
    • My home page and email address
Re: Hardwere switch for dual boot.
« Reply #15 on: October 20, 2020, 10:23:24 am »
To pull the pins high or low i will be using some esp-07 and small signal relays.
I would use P-channel MOSFETs (say, BSS84) using the 40-pin serial port connector voltage, each with a transistor to pull the gate down to ground to enable it, with optionally a digital isolator (say, Si8630) between the transistor bases and the microcontroller.  Three pins would give eight states, with just one isolator, three MOSFETs, three transistors, and nine (I think) resistors; maybe 1µF or 100nF decoupling capacitor or two.  Assuming there is a +15V (or whatever voltage the serial ports use) supply pin available.

Do you have documentation on the 40-pin(?) connector pinout?  Could you use a multimeter to measure if any of its pins has a supply voltage, and what that supply voltage is?  (Typically it is one of 5V, 9V, 12V, or 15V.)

If the board has a hardware parallel port, that would be even easier to use, because the voltages are between 0 and 5V on the parallel port.  Then, you could use a simple digital isolator (Si8630 for three bits, Si8640 for four bits, Si8650 for five bits, Si8660 for six bits) between the MCU and the parallel port.  (In Grub, you'd use iob -v LPT port to read the status pins (11, 10, 12, 13, 15), where portis 0x3BD, 0x379, or 0x279.)

If you need the parallel port for other stuff (and that's why you didn't mention it), add one (3 bit) or two (all 5 status bits) CD4053B to the status bits, with one bit from the digital isolator to control if the status bits are controlled by the parallel port device, or the microcontroller.  Something like this:

This parallel port circuit is nice in that if there is nothing on the MCU side of the circuit, the DB25F connector is pass-through to the computer.  When the MCU pulls MCU_EN high, then the computer sees MCU_B3 through MCU_/B7 (the last one inverted!) in port 0x3BD/0x379/0x279, allowing the MCU to pass a 5-bit value to Grub, but release the parallel port for normal use afterwards.
 

Offline georgianTopic starter

  • Regular Contributor
  • *
  • Posts: 54
  • Country: at
Re: Hardwere switch for dual boot.
« Reply #16 on: October 20, 2020, 06:48:47 pm »
Thank you all for your rich-full answers.

I do not have an LPT port. I do have the pinout of the COM1-4 header (see attached foto) and there is no voltage pin on it, but that is not a problem. I could get 12V from somewhere else on the motherboard. (It uses a single 12V power supply.)

Fintek F81216AD should be the controller for the COM ports and is an LPC to 4 UART + 9-bit Protocol IC.

It might be easier to use some Virtual machines but I have no experience with this things and I don't really want to learn now.
The main reason for this thing is to have Linux and Windows server each with a C compiler and mySql database so I can learn to code CGI software that is portable. I'm sure there are many other ways and alternative languages like python and so on, but I like to stick with C.

Thanks again and I'll report back this weekend with my progress.

**EDDIT: Yes the COM ports are 16550 asynchronous. So I shouldn't have any compatibility problems.
« Last Edit: October 20, 2020, 06:56:44 pm by georgian »
 

Offline magic

  • Super Contributor
  • ***
  • Posts: 7052
  • Country: pl
Re: Hardwere switch for dual boot.
« Reply #17 on: October 20, 2020, 07:55:48 pm »
If you don't like grub you could always code an equivalent in x86 assembly, write it to the MBR and make it chainload either grub or the Windows boot sector ;)

I do have the pinout of the COM1-4 header (see attached foto) and there is no voltage pin on it, but that is not a problem. I could get 12V from somewhere else on the motherboard. (It uses a single 12V power supply.)
A common trick in COM port dongles is to set two pins to opposite states such that they provide ±12V for your circuit. This would take writing something to the UART's registers before reading its state, but I'm not familiar with the details.

And I just came up with an almost 100% hardware solution:
use grub or any other multi-OS bootloader (even the one in Windows can be configured to chainload a Linux bootloader) and modify some old unused keyboard such that a switch or relay shorts its down arrow.
« Last Edit: October 20, 2020, 07:58:39 pm by magic »
 
The following users thanked this post: georgian

Offline S. Petrukhin

  • Super Contributor
  • ***
  • Posts: 1273
  • Country: ru
Re: Hardwere switch for dual boot.
« Reply #18 on: October 21, 2020, 01:44:00 am »
Doesn't the F8 or F5 key allow you to select an OS to boot that can be installed on the same SSD at the same time? In addition, you can use Oracle VM VirtualBox to run a second OS inside Windows.
And sorry for my English.
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6762
  • Country: fi
    • My home page and email address
Re: Hardwere switch for dual boot.
« Reply #19 on: October 21, 2020, 06:09:01 am »
Like Magic mentioned, we only need to initialize the serial port, and we can use TXD for our voltage source; this is because RS-232 TX is idle high.
(Edited: As Ian.M mentions, UART is different to RS-232, and I was thinking of UART and assuming RS-232 was just voltage-level converted.  Ouch.  Apologies.)

Therefore, I personally would try something like this, except instead of TXD take the supply voltage from somewhere else, perhaps the DTR or RTS pin:

Note that I am just a hobbyist wrt. the electronics, so any comments/criticism regarding the circuit is welcome, and probably warranted!
You might wish to pull CTS to ground (instead of leaving it floating), by the way.  I'm not sure if Grub supports simple math (outside comparisons), so that would ensure bit 4 in the status register would be zero, making comparisons easier.  (I do believe the low 4 bits are zero on read; need to check part D of Ralf Browns Interrupt List!)

The 680 Ohm resistors are intended to limit the current to 5mA per pin or so.  ACPL-247 has 1.0V to 1.2V forward voltage at 5mA, and (5 V - 1.2 V)/(680 Ohm) = 0.005588 A ≃ 5.6 mA.
1 kOhm resistors would also work fine, yielding about 4mA per pin.
The 4.7 kOhm resistors are a best guess based on the datasheet, and the fact that we don't want to try and pull too much current off the TX pin.  If there is leakage through the optocoupler, one might add small-signal diodes (ordinary ones, not Schottkys, just for the voltage drop) between the optocoupler outputs and CD4053B inputs; or say 47k pull-down resistors to (serial) GND.
I'm not sure, because I just a hobbyist.  :-[
« Last Edit: October 21, 2020, 08:19:44 am by Nominal Animal »
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 13026
Re: Hardwere switch for dual boot.
« Reply #20 on: October 21, 2020, 07:28:00 am »
Crazy-Crazy!  There wont be a positive voltage on TXD once the port is initialized unless a break condition is set.  Logic level serial port data lines idle high, however on a RS-232 serial port the levels are inverted,  positive voltage is logic '0', and negative voltage is logic '1'.  PC serial ports tend to accept 0V as logic '1' even though the official standard (currently TIA-232-F 1997) says that's out of spec. 

As you don't need to receive data from the PC, you can simply drive the lines you need from a suitable logic level converter, e.g. a 74HCT gate via a *SHORT* cable.   There's no need for isolation unless you are using cabled remote control, in which case, you'd be best off pulling the lines up to +12V locally and using high CTR optocouplers directly to pull them down when required,  each driven with current via a twisted pair in the cable, with a resistor across the LED so it doesn't turn on if the current is below the threshold.   
 
The following users thanked this post: Nominal Animal

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6762
  • Country: fi
    • My home page and email address
Re: Hardwere switch for dual boot.
« Reply #21 on: October 21, 2020, 08:23:25 am »
Crazy-Crazy!  There wont be a positive voltage on TXD once the port is initialized unless a break condition is set.
Right, thanks.  I did some more digging, and it looks like DTR and RTS could be used instead (were used in the olden days to power serial mice).  What do you think?

There's no need for isolation unless you are using cabled remote control
The OP mentioned they're using ESP-07, which is likely externally powered, so it can power up the board and control which OS it boots into, via WiFi or Bluetooth.  In this case, it is better/safer to have isolation, in my opinion, than rely on using isolated wall wart or battery for the MCU so that it will always share ground with the computer.  At least I like to use isolation, being my bumbly self...
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6762
  • Country: fi
    • My home page and email address
Re: Hardwere switch for dual boot.
« Reply #22 on: October 21, 2020, 08:50:33 am »
All the above written, I think an USB HID device based approach is superior.

In Grub, you can do
Code: [Select]
if keystatus; then
    keystatus --alt
    state=$?
    keystatus --ctrl
    state=${state}$?
    keystatus --shift
    state=${state}$?
else
    state=xxx
fi
to obtain the Shift, Control, and Alt, modifier key states.  The state variable will contain three characters, first character corresponding to Alt, second to Ctrl, and third to Shift.  If the corresponding key is pressed, it will be 0; if not pressed, 1.  (This is because in general, True corresponds to exit status 0, and False to 1.)  If the state checking is not supported, state will be xxx.  This yields eight "modes" Grub can choose from trivially:
Code: [Select]
if [ x${state} == x110 ]; then
    default=shift
elif [ x${state} == x101 ]; then
    default=ctrl
elif [ x${state} == x100 ]; then
    default=shift+ctrl
elif [ x${state} == x011 ]; then
    default=alt
elif [ x${state} == x010 ]; then
    default=shift+alt
elif [ x${state} == x001 ]; then
    default=ctrl+alt
elif [ x${state} == x000 ]; then
    default=shift+ctrl+alt
fi
where default is the special Grub variable that chooses which boot entry is used unless user intervenes.  You can obviously do anything you want inside the if clauses.

For USB keyboards, the modifier key state is contained within each keypress/release report.  This means that if you have two keyboards, and press a modifier key on one, pressing a standard key on the other will/should not have the modifier key applied.  Semi-unfortunately, Grub does combine modifier keys from all active terminals, so it is kind of important to have the USB HID device send the modifier key reports only until Grub has started, i.e. for say a second longer than the BIOS/EFI takes to run on the machine.

In a separate thread, I asked feedback for an ultra-cheap USB gamepad using WCH CH551G microcontroller with an 8051 core that one can buy from LCSC for under USD $0.40 apiece. This has a native USB interface, and the MCU series were extensively discussed here in this thread.  This would be basically perfect for such an use case.  You could, for example, connect it to any ESP via UART or SPI.

In fact, this gives me a project idea I could use with my ARM-based SBCs (that use U-Boot and not Grub, though): CH551G mini display controller with bootloader graphics, for use with small OLED or TFT display modules (controlled via 4-wire SPI):

One would need to add USB commands to Grub/U-Boot for loading prepared images and USB HID commands to for a proper query-response interface, but that would not be a big endeavour.  Without any changes to Grub, this circuit can be used for the Shift/Ctrl/Alt "messaging".

During proper OS use, the display could be exposed as a tiny framebuffer via USB Serial, HID, or even just as a bulk USB endpoint, so that one could use the display with e.g. a simple Python or C program, to show the appliance status...  One of my SBCs has 1.8V UART only, so the schematic includes 74LVC1T45 level shifters.  CH551G and CH552G have the same pinout, but CH552G has an ADC; P3.2 and P1.4 (and P1.1, connected to VUSB via a voltage divider) can be used for analog inputs.
« Last Edit: October 21, 2020, 01:41:29 pm by Nominal Animal »
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6762
  • Country: fi
    • My home page and email address
Re: Hardwere switch for dual boot.
« Reply #23 on: October 21, 2020, 11:14:04 pm »
As to the microcontroller to serial port interface, the following might make a lot more sense than the one with CD4053B above.  :-[


Note that the resistors are not in voltage divider configuration: the resistor to ground is first.
« Last Edit: October 21, 2020, 11:15:43 pm by Nominal Animal »
 
The following users thanked this post: georgian

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 13026
Re: Hardwere switch for dual boot.
« Reply #24 on: October 22, 2020, 12:24:38 pm »
I'm still not too happy with your latest circuit.

RS232 outputs are either current limited or have considerable series resistance as the standard requires them to be short-circuit proof.   Typically the output voltage will drop about a volt for every mA of load current.  Therefore the above circuit may not reach a high enough voltage to be 'seen' as logic '0' when three or more of the OPTOs are on.  The 4.7K resistors in series with the inputs do nothing useful and may form a potential divider with the input resistance, reducing the signal level. 

IIRC the DTR output should also be high, so combine DTR and RTS with a BAT54C common cathode dual Schottky diode to maximize the available current to feed the phototransistor collectors, and get rid of the series resistors.   Worst case, if the serial port has particularly weak outputs, you may need to increase the pulldowns to 10K.
 
The following users thanked this post: Nominal Animal

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6762
  • Country: fi
    • My home page and email address
Re: Hardwere switch for dual boot.
« Reply #25 on: October 22, 2020, 04:47:27 pm »
I really appreciate the criticism and advice, Ian.M!

So, here's the updated schematic:


Also, I sketched up a small board at EasyEda with pads for 0603, 0805, or through-hole 1/8 watt resistors, just to see what it'd look like in 2D and 3D.
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 13026
Re: Hardwere switch for dual boot.
« Reply #26 on: October 22, 2020, 07:53:56 pm »
Looks reasonable.  However depending on the OPTO's CTRR, and the PC serial port's actual thresholds, you may find you need more drive than you can get through a 680R resistor from a 3.3V logic level.  Also many MCUs have somewhat asymmetric I/O pin output drivers that sink better than they source, so consider bringing out all the OPTO-LED cathodes individually so you can choose to drive it with active low outputs.
« Last Edit: October 22, 2020, 08:09:54 pm by Ian.M »
 
The following users thanked this post: Nominal Animal

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6762
  • Country: fi
    • My home page and email address
Re: Hardwere switch for dual boot.
« Reply #27 on: October 23, 2020, 10:04:50 am »
Yes; the BOM does not contain the resistors, and in the description, I do mention using 470 Ohm resistors instead for 3.3V I/O (as ESP-07 uses, I just realized).  (On the RS-232 side, the status signal voltages are positive, high anything between 5V and 25V.)

The forward voltage of the ACPL-247 is 1.0-1.2 V, so 680 Ohm yields 5.6-5.9 mA on 5 V I/O, and 470 Ohm 4.5-4.9 mA on 3.3V.  The 5 mA driving current was a guess, based on the datasheet as it promises a minimum 100% CTR at 5V 5mA.  I suspect that 1 kOhm resistors would be fine (2mA driving current), and would definitely be preferred on the microcontroller side, but I don't see how to check if it would work in practice, other than testing.

I never even thought about using the I/O pins to sink instead of sourcing current – no real-world experience! – but now that you mentioned it, it makes a lot of sense.  If I recall correctly, DCE is inverted in the PC status port, so one has to deal with inversion anyway (which is just one XOR mask on the desired "status number" to pass to Grub).  I think I'll create a second version of the schematic and board, this time with 0603/0805 resistors only, and think a bit harder on the hand-solderability.

Again, your comments have been invaluable, Ian.M; thanks! ^-^
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6762
  • Country: fi
    • My home page and email address
Re: Hardwere switch for dual boot.
« Reply #28 on: October 23, 2020, 04:53:03 pm »
Okay, here is the updated schematic, board, and 3D views.  It's 1" by 0.8" or 25mm by 20mm, with three 2.1mm holes for fastening (16mm and 21mm between hole centers).





The resistor pads work for both 0603 and 0805 resistors, and the pads are larger than normal to make soldering them easier.  There is an additional through hole pad on the BAT54C diode output, in case there is just one supply on the output side so that one can omit the BAT54C.  Alternatively, if the output side is e.g. a microcontroller, one can tap off the BAT54C output to MCU power, and connect more than one supply to the BAT54C inputs.  Instead of marking resistor values, I labeled them RLIM (for the 470 Ohm current-limiting resistors) and RPULLDN for the pull-down resistors.
As of 2020-10-23, the components are supported by JLCPCB's SMT assembly service, but I tried to make it easy to solder.

The schematic and board files are in public domain here.
« Last Edit: October 23, 2020, 04:56:16 pm by Nominal Animal »
 

Offline georgianTopic starter

  • Regular Contributor
  • *
  • Posts: 54
  • Country: at
Re: Hardwere switch for dual boot.
« Reply #29 on: October 23, 2020, 09:36:41 pm »
Wait, does the board have a physical RS-232 serial port, with an 8250/16550 compatible UART, on the motherboard?

If it does, then you indeed can just use one of the status pins on that port, if you make sure the Grub iorw module (iorw.mod) is enabled.  Then,
    inb -v MCE 0x3FE        (for first serial port)
    inb -v MCE 0x2EE        (for second serial port)
    inb -v MCE 0x2FE        (for third serial port)
    inb -v MCE 0x3EE        (for fourth serial port)
saves the port status pin states in Grub variable MCE, in hexadecimal, without a leading 0x.  The four low bits should be zero.  The high four bits correspond to CTS (bit 4), DSR (bit 5), RI (bit 6), and DCD (bit 7).  On an 9-pin serial connector, CTS is pin 8, DSR is pin 6, RI is pin 9, and DCD is pin 1; except that pin 1 and/or pin 9 may be connected to a positive supply voltage.

So, let's say you connect a SPDT switch, common to pin 8 on the 9-pin serial port connector, and the two options to pin 5 (signal ground) and pin 1 or 9, whichever has a positive voltage on it.  In your Grub configuration file,
    serial --unit=0
    inb -v MCE 0x3FE
    set MCE=0x$MCE
    if [ $MCE -eq 16 -o $MCE -eq 48 -o $MCE -eq 80 -o $MCE -eq 112 -o $MCE -eq 144 -o $MCE -eq 176 -o $MCE -eq 204 -o $MCE -eq 240 ]; then
        set default=1
    else
        set default=0
    fi
and the default will be either the first or the second boot entry, depending on the position of the switch.

If you do the same for pin 6 as you did for pin 8 above, then
    serial --unit=0
    inb -v MCE 0x3FE
    set MCE=0x$MCE
    if [ $MCE -eq 16 -o $MCE -eq 80 -o $MCE -eq 144 -o $MCE -eq 208 ]; then
        set default=1
    elif [ $MCE -eq 32 -o $MCE -eq 96 -o $MCE -eq 160 -o $MCE -eq 224 ]; then
        set default=2
    elif [ $MCE -eq 48 -o $MCE -eq 112 -o $MCE -eq 176 -o $MCE -eq 240 ]; then
        set default=3
    else
        set default=0
    fi
gives you four possibilities.  Note that one switch could be for a "fast boot" to the selected OS, with no wait in Grub, and the other just selects the boot entry.

I got my windows and Linux up and running and with the use of keyboard i can select which OS I want to boot. Everything good so far.

First i tried to add the set default="2" at the beginning of the grub.cfg file(located in /boot/grub/grub.cfg) and it didn't select the windows as default.
After some more tries I added the line just after the 00_header END and it worked. It did select the windows as default and after the timeout it booted just fine. So far so good.

The problems started after. There is no voltage on the pin 1(DCD) or 9(RI) so I used 12V from the MB in series with a 470Ω resistor. Common pin from spdt to DB-9 pin 8(CTS), one pin from spdt to DB-9 pin 5(GND) and the other pin from spdt to one 470Ω resistor and then 12V.

As seen in the attached picture, i wrote the other lines of code and un-commented the single set default="2" line.
It doesn't work. I flipped the switch to any position and did some restarts with no change.

Did I load the iorw module at the right time? is there any may to debug this using some print commands?

Thanks again for all the support.

**EDIT: the "sudo ls /boot/grub/i386-pc/" command show the the iorw.mod file is there. I have ubuntu server 20.04
« Last Edit: October 23, 2020, 09:40:39 pm by georgian »
 

Offline ebclr

  • Super Contributor
  • ***
  • Posts: 2329
  • Country: 00
Re: Hardwere switch for dual boot.
« Reply #30 on: October 24, 2020, 12:22:18 am »
"I want to have a windows server and Linux saver to learn and play with. I don't plan to keep the server near my working PC"

Why not using windows WLS, you can have both running at the same time,
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6762
  • Country: fi
    • My home page and email address
Re: Hardwere switch for dual boot.
« Reply #31 on: October 24, 2020, 01:00:50 pm »
After some more tries I added the line just after the 00_header END and it worked. It did select the windows as default and after the timeout it booted just fine. So far so good.
Yes, you do need to examine the entire Grub startup script and see when default is set; it can also be set by a load_env command.  I recommend you get familiar with the Grub manual.

The problems started after. There is no voltage on the pin 1(DCD) or 9(RI) so I used 12V from the MB in series with a 470Ω resistor. Common pin from spdt to DB-9 pin 8(CTS), one pin from spdt to DB-9 pin 5(GND) and the other pin from spdt to one 470Ω resistor and then 12V.
Right; if you look at my post just before yours, you'll see a much better approach.  The idea is to use serial --unit N to initialize the serial port (but not used as an input if there is no corresponding terminal_input command); this causes RTS and DTR to go high, so they can be used as the positive supply voltage.

It doesn't work. I flipped the switch to any position and did some restarts with no change.
Right, we need a debugging print right about here.  That would be echo, as listed in the Grub manual. For example,
Code: [Select]
insmod iorw
serial --port=0x3F8
serial --port=0x2E8
serial --port=0x2F8
serial --port=0x3E8
sleep 1
inb -v com1 0x3FE
inb -v com2 0x2EE
inb -v com3 0x2FE
inb -v com4 0x3EE
echo "COM1=${com1} COM2=${com2} COM3=${com3} COM4=${com4}"
This will display the four COM port's status bytes, as obtained by inb.  I don't think the sleep is necessary, but it would be a good idea to verify it makes no difference.

Why not using windows WLS, you can have both running at the same time,
Because WSL is not Linux, it is a compatibility layer effort by Microsoft to stop developers from switching from Windows to Linux?  It is equivalent to using Wine on Linux.
Most things work, a lot of things do not.  Learning the native environment – both ways, mind you! – is better than learning just the compatibility layer and thinking its quirks are normal part of that OS.
« Last Edit: October 24, 2020, 01:03:19 pm by Nominal Animal »
 

Offline georgianTopic starter

  • Regular Contributor
  • *
  • Posts: 54
  • Country: at
Re: Hardwere switch for dual boot.
« Reply #32 on: October 24, 2020, 05:12:40 pm »
I got it working!
Thank you for all your help and information so far.
Here is what I have added to the grub.cfg file
Code: [Select]
echo -e "Loading iorw.mod Module\n"
insmod iorw
serial --port=0x3F8
inb -v com1 0x3FE
echo -e "COM1 state: ${com1}\n"
inv -v com1 0x3FE
#There should one space between [ and $ otherwise grub throws command error and the if will be true!
#"-eq" means is equal -> in C "=="
#"-o" means or -> in C "||"
if [ $com1 -eq 10 -o $com1 -eq 11]; then
  echo -e "Switch is ON!\nCTS is HIGH, We should boot Windows now!\n"
  set default="2"
else
  echo -e "Switch is OFF!\nCTS is LOW, We should boot Ubuntu now!\n"
  set default="0"
fi
echo "Booting auto-selected OS"
sleep 3

The reason i have to check if port is 10 or 11 is because first time i read the port gives 11, sometimes other number and second time it gives the correct number. I have tried in the grub command line all 4 inputs (CTS, DSR, RI, DCD) and they all "work".
in grub command line i first type:
Code: [Select]
insmod iorw
serial --port=0x3F8
inb -v com1 0x3FE
echo -e "COM1 state: ${com1}\n"
everything is low, so i get a 0. I set CTS HIGH, all other LOW (with 10k pull-down)
Code: [Select]
inb -v com1 0x3FE
echo -e "COM1 state: ${com1}\n"
and ii get 11. No change on the switches, read the port again
Code: [Select]
inb -v com1 0x3FE
echo -e "COM1 state: ${com1}\n"
and ii get 10. No metter how many time i read the port i get 10. No set the CTS LOW and DSR HIGH. All other LOW. Again, read the port one and echo the result.
Code: [Select]
inb -v com1 0x3FE
echo -e "COM1 state: ${com1}\n"
I get 23. Read again and echo the result i get 20. Read again and still 20. DSR LOW and RI HIGH, all other LOW. Read port and echo the result i get 46. Read again and echo the result I get 40 and so on for all other pins.
Why do i have to read twice? must be something that i'm doing wrong.
Attached is a photo with the way i send the commands.
« Last Edit: October 24, 2020, 05:18:53 pm by georgian »
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6762
  • Country: fi
    • My home page and email address
Re: Hardwere switch for dual boot.
« Reply #33 on: October 24, 2020, 06:02:49 pm »
Part D of Ralf Brown's Interrupt List explains the following in PORTS.B file for the hardware serial port registers:
Code: [Select]
PORT 03F8-03FF - Serial port (8250,8250A,8251,16450,16550,16550A,etc.) COM1
Range: PORT 02E8h-02EFh (COM2), PORT 02F8h-02FFh (typical non-PS/2 COM3), and
  PORT 03E8h-03EFh (typical non-PS/2 COM4)
Note: chips overview:
8250  original PC, specified up to 56Kbd, but mostly runs
       only 9600Bd, no scratchregister, bug: sometimes shots
       ints without reasons
8250A, 16450, 16C451: ATs, most chips run up to 115KBd,
       no bug: shots no causeless ints
8250B: PC,XT,AT, pseudo bug: shots one causeless int for
compatibility with 8250, runs up to 56KBd
16550, 16550N, 16550V: early PS/2, FIFO bugs
16550A,16550AF,16550AFN,16550C,16C551,16C552: PS/2, FIFO ok
82510: laptops & industry, multi emulation mode
(default=16450), special-FIFO.
8251: completely different synchronous SIO chip, not compatible!
SeeAlso: INT 14/AH=00h"SERIAL"

03F8  -W  serial port, transmitter holding register (THR), which contains the
  character to be sent. Bit 0 is sent first.
bit 7-0   data bits when DLAB=0 (Divisor Latch Access Bit)
03F8  R-  receiver buffer register (RBR), which contains the received
  character. Bit 0 is received first
bit 7-0   data bits when DLAB=0 (Divisor Latch Access Bit)
03F8  RW  divisor latch low byte (DLL) when DLAB=1 (see #P0876)
03F9  RW  divisor latch high byte (DLM) when DLAB=1 (see #P0876)
03F9  RW  interrupt enable register (IER) when DLAB=0 (see #P0877)
03FA  R-  interrupt identification register (see #P0878)
Information about a pending interrupt is stored here. When the ID
  register is addressed, thehighest priority interrupt is held, and
  no other interrupts are acknowledged until the CPU services that
  interrupt.
03FA  -W  16650 FIFO Control Register (FCR) (see #P0879)
03FB  RW  line control register (LCR) (see #P0880)
03FC  RW  modem control register (see #P0881)
03FD  R-  line status register (LSR) (see #P0882)
03FE  R-  modem status register (MSR) (see #P0883)
03FF  RW  scratch register (SCR)
(not used for serial I/O; available to any application using 16450,
  16550) (not present on original 8250)

(Table P0876)
Values for serial port divisor latch registers:
 Some baudrates (using standard 1.8432 Mhz clock):
       baudrate    divisor DLM  DLL
    50    2304   09h 00h
    75    1536   06h 00h
   110    1047   04h 17h
   134,5    857   03h 59h
   150     768   03h 00h
   300     384   01h 80h
   600     192   00h C0h
  1200      96   00h 60h
  1800      64   00h 40h
  2000      58   00h 3Ah
  2400      48   00h 30h
  3600      32   00h 20h
  4800      24   00h 18h
  7200      16   00h 10h
  9600      12   00h 0Ch
19200       6   00h 06h
38400       3   00h 03h
57600       2   00h 02h
115200       1   00h 01h
Note: MIDI baudrate 32250Bd with 4Mhz quarz for c't MIDI interface
  following c't 01/1991:   '14400'   00h 08h

Bitfields for serial port interrupt enable register (IER):
Bit(s) Description (Table P0877)
 7-6 reserved (0)
 5 (82510) "timer"
(other) reserved (0)
 4 (82510) "transmit machine"
(other) reserved (0)
 3 modem-status interrupt enable
 2 receiver-line-status interrupt enable
 1 transmitter-holding-register empty interrupt enable
 0 received-data-available interrupt enable
  (also 16550(A) timeout interrupt)
Note: 16550(A) will interrupt with a timeout if data exists in the FIFO
  and isn't read within the time it takes to receive four bytes or if
  no data is received within the time it takes to receive four bytes
SeeAlso: #P0878

Bitfields for serial port interrupt identification register (IIR):
Bit(s) Description (Table P0878)
 7-6 =00  reserved on 8250, 8251, 16450
=01  if FIFO queues enabled but unusable (16550 only)
=11  if FIFO queues are enabled (16550A only) (see also #P0879)
 6-5 used by 82510 for bank select (00 = default bank0)
 5-4 reserved (0)
 3-1 identify pending interrupt with the highest priority
110 (16550,82510) timeout interrupt pending
101 (82510) timer interrupt (see #P0877)
100 (82510) transmit machine (see #P0877)
011 receiver line status interrupt. priority=highest
010 received data available register interrupt. pr.=second
001 transmitter holding register empty interrupt. pr.=third
000 modem status interrupt. priority=fourth
 0 =0 interrupt pending. contents of register can be used as a pointer
  to the appropriate interrupt service routine
=1 no interrupt pending
Notes: interrupt pending flag uses reverse logic, 0=pending, 1=none
interrupt will occur if any of the line status bits are set
THRE bit is set when THRE register is emptied into the TSR
SeeAlso: #P0877

Bitfields for serial port FIFO control register (FCR):
Bit(s) Description (Table P0879)
 7-6 received data available interrupt trigger level (16550)
00  1 byte
01  4 bytes
10  8 bytes
11 14 bytes
 6-5 =00  (used to enable 4 byte Rx/Tx FIFOs on 82510???)
=10 ???
 5-4 reserved (00)
 3 change RXRDY  TXRDY pins from mode 0 to mode 1
 2 clear XMIT FIFO
 1 clear RCVR FIFO
 0 enable clear XMIT and RCVR FIFO queues
 4-0 (other purpose on 82510???)
Notes: bit 0 must be set in order to write to other FCR bits
bit 1 when set the RCVR FIFO is cleared and this bit is reset
  the receiver shift register is not cleared
bit 2 when set the XMIT FIFO is cleared and this bit is reset
  the transmit shift register is not cleared
due to a hardware bug, 16550 FIFOs don't work correctly (this
  was fixed in the 16550A)
SeeAlso: #P0878

Bitfields for serial port Line Control Register (LCR):
Bit(s) Description (Table P0880)
 7 =1  divisor latch access bit (DLAB)
=0  receiver buffer, transmitter holding, or interrupt enable register
  access
 6 set break enable. serial ouput is forced to spacing state and remains
  there.
 5-3 PM2 PM1 PM0
x   x 0 = no parity
0   0 1 = odd parity
0   1 1 = even parity
1   0 1 = high parity (sticky)
1   1 1 = low parity (sticky)
x   x 1 = software parity
 2 stop bit length (STB/SBL)
0  one stop bit
1  2 stop bits with (word length 6, 7, 8)
   1.5 stop bits with word length 5
 1-0 (WLS1-0, CL1-0)
00 word length is 5 bits
01 word length is 6 bits
10 word length is 7 bits
11 word length is 8 bits
SeeAlso: #P0881,#P0882,#P0883

Bitfields for serial port Modem Control Register (MCR):
Bit(s) Description (Table P0881)
 7-6 reserved (0)
 5 (82510 only) state of OUT0 pin
 4 loopback mode for diagnostic testing of serial port
output of transmitter shift register is looped back to receiver
  shift register input. In this mode, transmitted data is received
  immediately so that the CPU can verify the transmit data/receive
  data serial port paths.
If OUT2 is disabled, there is no official way to generate an IRQ
  during loopback mode.
 3 auxiliary user-designated output 2 (OUT2)
because of external circuity OUT2 must be 1 to master-intr-enableing.
BUG: Some Toshiba Laptops utilize this bit vice versa, newer Toshiba
  machines allow assignment of the bit's polarity in system setup.
82050: This bit is only effective, if the chip is being used with an
  externally-generated clock.
 2 =1/0  auxiliary user-designated output 1 (OUT1)
should generally be cleared!!
Some external hardware, e.g. c't MIDI interface (and compatibles) use
  this bit to change the 8250 input clock from 1,8432 MHz to 4Mhz
  (enabling MIDI-conformant baudrates) and switching to
  MIDI-compatible current loop connectors.
 1 force request-to-send active (RTS)
 0 force data-terminal-ready active (DTR)
SeeAlso: #P0880,#P0882,#P0883

Bitfields for serial port Line Status Register (LSR):
Bit(s) Description (Table P0882)
 7 =0  reserved
=1  on some chips produced by UMC
 6 transmitter shift and holding registers empty
 5 transmitter holding register empty (THRE)
Controller is ready to accept a new character to send.
 4 break interrupt. the received data input is held in the zero bit
  state longer than the time of start bit + data bits + parity bit +
  stop bits.
 3 framing error (FE). the stop bit that follows the last parity or data
  bit is a zero bit
 2 parity error (PE). Character has wrong parity
 1 overrun error (OE). a character was sent to the receiver buffer
  before the previous character in the buffer could be read. This
  destroys the previous character.
 0 data ready. a complete incoming character has been received and sent
  to the receiver buffer register.
SeeAlso: #P0880,#P0881,#P0883

Bitfields for serial port Modem Status Register (MSR):
Bit(s) Description (Table P0883)
 7 data carrier detect (-DCD)
 6 ring indicator (-RI)
 5 data set ready (-DSR)
 4 clear to send (-CTS)
 3 delta data carrier detect (DDCD)
 2 trailing edge ring indicator (TERI)
 1 delta data set ready (DDSR)
 0 delta clear to send (DCTS)
Notes: bits 0-3 are reset when the CPU reads the MSR
bit 4 is the Modem Control Register RTS during loopback test
bit 5 is the Modem Control Register DTR during loopback test
bit 6 is the Modem Control Register OUT1 during loopback test
bit 7 is the Modem Control Register OUT2 during loopback test
SeeAlso: #P0880,#P0881,#P0882

The most important one is the last table, explaining the eight bits of port 0x3FE, Modem Status Register (MSR):
  • Bit 7 (128): DCD. This reflects the DCD pin state.
  • Bit 6 (64): RI. This reflects the RI pin state.
  • Bit 5 (32): DSR. This reflects the DSR pin state.
  • Bit 4 (16): CTS. This reflects the CTS pin state.
  • Bit 3 (8): Delta DCD. This is set when the DCD state has changed since last read of this register.
  • Bit 2 (4): Trailing edge RI. This is set when RI has transitioned from low to high since this register was read last.
  • Bit 1 (2): Delta DSR.  This is set if DSR has changed since last read of this register.
  • Bit 0 (1): Delta CTS.  This is set if CTS has changed since last read of this register.
I'm no longer convinced I know whether the four high bits are inverted or not... so check that.  However, inb sets the environment variable value to hexadecimal without a leading 0x, so the values you see (10, 11, 20, 23) are actually 0x10=16, 0x11=17, 0x20=32, 0x23=35.  And yes, those values make perfect sense.  (I hope this post explains why and how.)

Code: [Select]
if [ $com1 -eq 10 -o $com1 -eq 11]; then

Before you do this, you need to add
    com1=0x$com1
so that Grub parses it correctly as a hexadecimal number.  It definitely is a hexadecimal number, as Grub uses grub_snprintf(buf, sizeof (buf), "%x", value) to construct it.

The reason i have to check if port is 10 or 11 is because first time i read the port gives 11, sometimes other number and second time it gives the correct number.
Yes, this is because the four low bits (right-side hexadecimal digit) is a "delta" value, telling whether the status lines have changed since the last read of the register.

Essentially, if you read it twice in succession, and the input pin states do not change in between, the low bits should be all zeros (so you get 0x10, 0x20, 0x30, ..., 0xF0).
It is perfectly okay to read the register twice in succession, e.g.
    inb -v com1 0x3FE
    inb -v com1 0x3FE
    com1=0x$com1
to hopefully clear the low four bits that aren't that interesting.  I don't think Grub has built-in arithmetic or binary operators, otherwise com1=$[0x$com1 & 0xF0] would have been extremely useful for this.  Also note that the value you are treating as a decimal is actually hexadecimal, because inb does not set the leading 0x, the values you get just happen to look like normal decimal values!

We could rely on the regexp command, though:
    inb -v com1 0x3FE
    regexp --set 1:com1 '^[0-9A-Fa-f]*([0-9A-Fa-f])[0-9A-Fa-f]$' 00$com1
    com1=0x$com1
in which case com1 matches a number between 0-15, as if it had been divided by 16.  The idea is that the POSIX extended regular expression in single quotes matches any number of hex digits, then remembers one hex digit, then matches one hex digit; and the command stores the first parenthesized match back to com1.  The string it operates on has two zeros prepended, so that the regexp works correctly even when com1 contains only a single hex digit.  (But do check it for bugs, I haven't tested it.)
 

Offline LeonR

  • Regular Contributor
  • *
  • Posts: 158
  • Country: br
  • PC hardware enthusiast
Re: Hardwere switch for dual boot.
« Reply #34 on: October 24, 2020, 11:18:47 pm »
Is there any specific reason to go for a complex solution to a very simple problem?

Grab a couple of those or similar and just turn on the one with the OS you need booting:

https://www.aliexpress.com/item/32814146574.html

Alternatively, if it is a server-grade equipment you'll probably have IPMI, so you can remotely manage the system's BIOS and toggle the boot disk. Or even choose whichever OS you want to boot using GRUB, etc.
 

Offline georgianTopic starter

  • Regular Contributor
  • *
  • Posts: 54
  • Country: at
Re: Hardwere switch for dual boot.
« Reply #35 on: October 25, 2020, 09:11:07 am »
Is there any specific reason to go for a complex solution to a very simple problem?

Grab a couple of those or similar and just turn on the one with the OS you need booting:

https://www.aliexpress.com/item/32814146574.html

Alternatively, if it is a server-grade equipment you'll probably have IPMI, so you can remotely manage the system's BIOS and toggle the boot disk. Or even choose whichever OS you want to boot using GRUB, etc.
I don't want to have 2 HDDs. I want one with more partitions. It's just a motherboard, so no remote access to bios.
This solutions is not complex at all. It's just a few lines of code on the grub config file. So far  ;D
 

Offline Doctorandus_P

  • Super Contributor
  • ***
  • Posts: 3766
  • Country: nl
Re: Hardwere switch for dual boot.
« Reply #36 on: October 31, 2020, 05:01:10 am »
TL:DR.

Addition:
The simplest way is probably to use your BIOS to select a boot disk.
You select one disk as default, and with holding a button during boot (usually F8 I think) you can get a boot menu to select a disk to boot from.

No extra hardware needed.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf