Hardwere switch for dual boot. - Page 1
Forum section: electronics / general

author: georgian
author_rank: Regular Contributor
timestamp: October 18, 2020, 08:34:58 pm
content: 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.

author: Ian.M
author_rank: Super Contributor
timestamp: October 18, 2020, 09:40:45 pm
content: 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.

author: Zbig
author_rank: Frequent Contributor
timestamp: October 18, 2020, 09:48:21 pm
content: Do you have any specific use case or requirement to go for dual boot instead of virtualization in this day and age?

author: georgian
author_rank: Regular Contributor
timestamp: October 18, 2020, 10:17:17 pm
content: 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.

author: Red Squirrel
author_rank: Super Contributor
timestamp: October 19, 2020, 01:16:32 am
content: 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.

author: rdl
author_rank: Super Contributor
timestamp: October 19, 2020, 01:53:41 am
content: 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.

author: bw2341
author_rank: Regular Contributor
timestamp: October 19, 2020, 05:15:52 am
content: Quote from: Red Squirrel on October 19, 2020, 01:16:32 amYou 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.

author: Nominal Animal
author_rank: Super Contributor
timestamp: October 19, 2020, 05:47:53 am
content: Assuming it has free USB ports, I would use an ATtiny85 (a DigiSpark clone) withmicronucleuson 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 hasgrub-core/commands/usbtest.cwhich 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 2npositions 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 --vendorVVVV--productPPPP--serialS...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.)

author: bitwelder
author_rank: Super Contributor
timestamp: October 19, 2020, 10:51:48 am
content: 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.

author: Nominal Animal
author_rank: Super Contributor
timestamp: October 19, 2020, 12:47:32 pm
content: 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=0inb -v MCE 0x3FEset MCE=0x$MCEif [ $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 ]; thenset default=1elseset default=0fiand 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, thenserial --unit=0inb -v MCE 0x3FEset MCE=0x$MCEif [ $MCE -eq 16 -o $MCE -eq 80 -o $MCE -eq 144 -o $MCE -eq 208 ]; thenset default=1elif [ $MCE -eq 32 -o $MCE -eq 96 -o $MCE -eq 160 -o $MCE -eq 224 ]; thenset default=2elif [ $MCE -eq 48 -o $MCE -eq 112 -o $MCE -eq 176 -o $MCE -eq 240 ]; thenset default=3elseset default=0figives 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.

author: andersm
author_rank: Super Contributor
timestamp: October 19, 2020, 08:17:12 pm
content: 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.

author: georgian
author_rank: Regular Contributor
timestamp: October 19, 2020, 08:39:29 pm
content: Quote from: Nominal Animal on October 19, 2020, 12:47:32 pmThis 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.

author: NiHaoMike
author_rank: Super Contributor
timestamp: October 20, 2020, 03:19:48 am
content: Quote from: Red Squirrel on October 19, 2020, 01:16:32 amMight want to look at something like Xen which is designed to work at a much lower level than your typical VM solutions.

author: Ed.Kloonk
author_rank: Super Contributor
timestamp: October 20, 2020, 03:34:15 am
content: 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/

author: Berni
author_rank: Super Contributor
timestamp: October 20, 2020, 04:29:28 am
content: Quote from: Red Squirrel on October 19, 2020, 01:16:32 amThere 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

author: Nominal Animal
author_rank: Super Contributor
timestamp: October 20, 2020, 10:23:24 am
content: Quote from: georgian on October 19, 2020, 08:39:29 pmI 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 hardwareparallelport, 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 useiob -v LPTportto read the status pins (11, 10, 12, 13, 15), whereportis 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.

author: georgian
author_rank: Regular Contributor
timestamp: October 20, 2020, 06:48:47 pm
content: 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.

author: magic
author_rank: Super Contributor
timestamp: October 20, 2020, 07:55:48 pm
content: 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 sectorQuote from: georgian on October 20, 2020, 06:48:47 pmA 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.

author: S. Petrukhin
author_rank: Super Contributor
timestamp: October 21, 2020, 01:44:00 am
content: 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.

author: Nominal Animal
author_rank: Super Contributor
timestamp: October 21, 2020, 06:09:01 am
content: 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 andassumingRS-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.

author: Ian.M
author_rank: Super Contributor
timestamp: October 21, 2020, 07:28:00 am
content: 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.

author: Nominal Animal
author_rank: Super Contributor
timestamp: October 21, 2020, 08:23:25 am
content: Quote from: Ian.M on October 21, 2020, 07:28:00 amRight, 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?Quote from: Ian.M on October 21, 2020, 07:28:00 amThe 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...

author: Nominal Animal
author_rank: Super Contributor
timestamp: October 21, 2020, 08:50:33 am
content: All the above written, I think an USB HID device based approach is superior.In Grub, you can doCode:if keystatus; thenkeystatus --altstate=$?keystatus --ctrlstate=${state}$?keystatus --shiftstate=${state}$?elsestate=xxxfito obtain the Shift, Control, and Alt, modifier key states. Thestatevariable 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,statewill bexxx. This yields eight "modes" Grub can choose from trivially:Code:if [ x${state} == x110 ]; thendefault=shiftelif [ x${state} == x101 ]; thendefault=ctrlelif [ x${state} == x100 ]; thendefault=shift+ctrlelif [ x${state} == x011 ]; thendefault=altelif [ x${state} == x010 ]; thendefault=shift+altelif [ x${state} == x001 ]; thendefault=ctrl+altelif [ x${state} == x000 ]; thendefault=shift+ctrl+altfiwheredefaultis 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, Grubdoes combine modifier keysfrom 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 aseparate thread, I asked feedback for an ultra-cheap USB gamepad using WCH CH551G microcontroller with an 8051 core that one can buy from LCSC forunder USD $0.40 apiece. This has a native USB interface, and the MCU series were extensively discussed here inthis 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.

author: Nominal Animal
author_rank: Super Contributor
timestamp: October 21, 2020, 11:14:04 pm
content: 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.

author: Ian.M
author_rank: Super Contributor
timestamp: October 22, 2020, 12:24:38 pm
content: 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.

author: Nominal Animal
author_rank: Super Contributor
timestamp: October 22, 2020, 04:47:27 pm
content: I really appreciate the criticism and advice, Ian.M!So, here's the updated schematic:Also, I sketched up a small board atEasyEdawith pads for 0603, 0805, or through-hole 1/8 watt resistors, just to see what it'd look like in 2D and 3D.

author: Ian.M
author_rank: Super Contributor
timestamp: October 22, 2020, 07:53:56 pm
content: 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.

author: Nominal Animal
author_rank: Super Contributor
timestamp: October 23, 2020, 10:04:50 am
content: 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!

author: Nominal Animal
author_rank: Super Contributor
timestamp: October 23, 2020, 04:53:03 pm
content: 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 RPULLDNfor 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 domainhere.

author: georgian
author_rank: Regular Contributor
timestamp: October 23, 2020, 09:36:41 pm
content: Quote from: Nominal Animal on October 19, 2020, 12:47:32 pmI 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

author: ebclr
author_rank: Super Contributor
timestamp: October 24, 2020, 12:22:18 am
content: "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,

author: Nominal Animal
author_rank: Super Contributor
timestamp: October 24, 2020, 01:00:50 pm
content: Quote from: georgian on October 23, 2020, 09:36:41 pmYes, 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 theGrub manual.Quote from: georgian on October 23, 2020, 09:36:41 pmRight; if you look at my post just before yours, you'll see a much better approach. The idea is to useserial --unitNto initialize the serial port (but not used as an input if there is no correspondingterminal_inputcommand); this causes RTS and DTR to go high, so they can be used as the positive supply voltage.Quote from: georgian on October 23, 2020, 09:36:41 pmRight, we need a debugging print right about here. That would beecho, as listed in the Grub manual. For example,Code:insmod iorwserial --port=0x3F8serial --port=0x2E8serial --port=0x2F8serial --port=0x3E8sleep 1inb -v com1 0x3FEinb -v com2 0x2EEinb -v com3 0x2FEinb -v com4 0x3EEecho "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.Quote from: ebclr on October 24, 2020, 12:22:18 amBecause 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.

author: georgian
author_rank: Regular Contributor
timestamp: October 24, 2020, 05:12:40 pm
content: I got it working!Thank you for all your help and information so far.Here is what I have added to the grub.cfg fileCode:echo -e "Loading iorw.mod Module\n"insmod iorwserial --port=0x3F8inb -v com1 0x3FEecho -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]; thenecho -e "Switch is ON!\nCTS is HIGH, We should boot Windows now!\n"set default="2"elseecho -e "Switch is OFF!\nCTS is LOW, We should boot Ubuntu now!\n"set default="0"fiecho "Booting auto-selected OS"sleep 3The 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:insmod iorwserial --port=0x3F8inb -v com1 0x3FEecho -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:inb -v com1 0x3FEecho -e "COM1 state: ${com1}\n"and ii get 11. No change on the switches, read the port againCode:inb -v com1 0x3FEecho -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:inb -v com1 0x3FEecho -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.

author: Nominal Animal
author_rank: Super Contributor
timestamp: October 24, 2020, 06:02:49 pm
content: Part D ofRalf Brown's Interrupt Listexplains the following inPORTS.Bfile for the hardware serial port registers:Code:PORT 03F8-03FF - Serial port (8250,8250A,8251,16450,16550,16550A,etc.) COM1Range:PORT 02E8h-02EFh (COM2), PORT 02F8h-02FFh (typical non-PS/2 COM3), andPORT 03E8h-03EFh (typical non-PS/2 COM4)Note:chips overview:8250 original PC, specified up to 56Kbd, but mostly runsonly 9600Bd, no scratchregister, bug: sometimes shotsints without reasons8250A, 16450, 16C451: ATs, most chips run up to 115KBd,no bug: shots no causeless ints8250B: PC,XT,AT, pseudo bug: shots one causeless int forcompatibility with 8250, runs up to 56KBd16550, 16550N, 16550V: early PS/2, FIFO bugs16550A,16550AF,16550AFN,16550C,16C551,16C552: PS/2, FIFO ok82510: 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 thecharacter to be sent. Bit 0 is sent first.bit 7-0data bits when DLAB=0 (Divisor Latch Access Bit)03F8 R- receiver buffer register (RBR), which contains the receivedcharacter. Bit 0 is received firstbit 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 IDregister is addressed, thehighest priority interrupt is held, andno other interrupts are acknowledged until the CPU services thatinterrupt.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):baudratedivisorDLM DLL50230409h 00h75153606h 00h110104704h 17h134,5 85703h 59h15076803h 00h30038401h 80h60019200h C0h12009600h 60h18006400h 40h20005800h 3Ah24004800h 30h36003200h 20h48002400h 18h72001600h 10h96001200h 0Ch19200600h 06h38400300h 03h57600200h 02h115200100h 01hNote:MIDI baudrate 32250Bd with 4Mhz quarz for c't MIDI interfacefollowing c't 01/1991: '14400'00h 08hBitfields for serial port interrupt enable register (IER):Bit(s)Description(Table P0877)7-6reserved (0)5(82510) "timer"(other) reserved (0)4(82510) "transmit machine"(other) reserved (0)3modem-status interrupt enable2receiver-line-status interrupt enable1transmitter-holding-register empty interrupt enable0received-data-available interrupt enable(also 16550(A) timeout interrupt)Note:16550(A) will interrupt with a timeout if data exists in the FIFOand isn't read within the time it takes to receive four bytes or ifno data is received within the time it takes to receive four bytesSeeAlso: #P0878Bitfields 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-5used by 82510 for bank select (00 = default bank0)5-4reserved (0)3-1identify pending interrupt with the highest priority110(16550,82510) timeout interrupt pending101(82510) timer interrupt (see #P0877)100(82510) transmit machine (see #P0877)011receiver line status interrupt. priority=highest010received data available register interrupt. pr.=second001transmitter holding register empty interrupt. pr.=third000modem status interrupt. priority=fourth0=0 interrupt pending. contents of register can be used as a pointerto the appropriate interrupt service routine=1 no interrupt pendingNotes:interrupt pending flag uses reverse logic, 0=pending, 1=noneinterrupt will occur if any of the line status bits are setTHRE bit is set when THRE register is emptied into the TSRSeeAlso: #P0877Bitfields for serial port FIFO control register (FCR):Bit(s)Description(Table P0879)7-6received data available interrupt trigger level (16550)00 1 byte01 4 bytes10 8 bytes11 14 bytes6-5=00 (used to enable 4 byte Rx/Tx FIFOs on 82510???)=10 ???5-4reserved (00)3change RXRDY TXRDY pins from mode 0 to mode 12clear XMIT FIFO1clear RCVR FIFO0enable clear XMIT and RCVR FIFO queues4-0(other purpose on 82510???)Notes:bit 0 must be set in order to write to other FCR bitsbit 1 when setthe RCVR FIFO is cleared and this bit is resetthe receiver shift register is not clearedbit 2 when setthe XMIT FIFO is cleared and this bit is resetthe transmit shift register is not cleareddue to a hardware bug, 16550 FIFOs don't work correctly (thiswas fixed in the 16550A)SeeAlso: #P0878Bitfields 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 registeraccess6set break enable. serial ouput is forced to spacing state and remainsthere.5-3PM2 PM1 PM0x x0 = no parity0 01 = odd parity0 11 = even parity1 01 = high parity (sticky)1 11 = low parity (sticky)x x1 = software parity2stop bit length (STB/SBL)0 one stop bit1 2 stop bits with (word length 6, 7, 8)1.5 stop bits with word length 51-0(WLS1-0, CL1-0)00 word length is 5 bits01 word length is 6 bits10 word length is 7 bits11 word length is 8 bitsSeeAlso: #P0881,#P0882,#P0883Bitfields for serial port Modem Control Register (MCR):Bit(s)Description(Table P0881)7-6reserved (0)5(82510 only) state of OUT0 pin4loopback mode for diagnostic testing of serial portoutput of transmitter shift register is looped back to receivershift register input. In this mode, transmitted data is receivedimmediately so that the CPU can verify the transmit data/receivedata serial port paths.If OUT2 is disabled, there is no official way to generate an IRQduring loopback mode.3auxiliary 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 Toshibamachines allow assignment of the bit's polarity in system setup.82050: This bit is only effective, if the chip is being used with anexternally-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) usethis bit to change the 8250 input clock from 1,8432 MHz to 4Mhz(enabling MIDI-conformant baudrates) and switching toMIDI-compatible current loop connectors.1force request-to-send active (RTS)0force data-terminal-ready active (DTR)SeeAlso: #P0880,#P0882,#P0883Bitfields for serial port Line Status Register (LSR):Bit(s)Description(Table P0882)7=0 reserved=1 on some chips produced by UMC6transmitter shift and holding registers empty5transmitter holding register empty (THRE)Controller is ready to accept a new character to send.4break interrupt. the received data input is held in the zero bitstate longer than the time of start bit + data bits + parity bit +stop bits.3framing error (FE). the stop bit that follows the last parity or databit is a zero bit2parity error (PE). Character has wrong parity1overrun error (OE). a character was sent to the receiver bufferbefore the previous character in the buffer could be read. Thisdestroys the previous character.0data ready. a complete incoming character has been received and sentto the receiver buffer register.SeeAlso: #P0880,#P0881,#P0883Bitfields for serial port Modem Status Register (MSR):Bit(s)Description(Table P0883)7data carrier detect (-DCD)6ring indicator (-RI)5data set ready (-DSR)4clear to send (-CTS)3delta data carrier detect (DDCD)2trailing edge ring indicator (TERI)1delta data set ready (DDSR)0delta clear to send (DCTS)Notes:bits 0-3 are reset when the CPU reads the MSRbit 4 is the Modem Control Register RTS during loopback testbit 5 is the Modem Control Register DTR during loopback testbit 6 is the Modem Control Register OUT1 during loopback testbit 7 is the Modem Control Register OUT2 during loopback testSeeAlso: #P0880,#P0881,#P0882The 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,inbsets the environment variable value tohexadecimal 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.)Quote from: georgian on October 24, 2020, 05:12:40 pmBefore you do this, you need to addcom1=0x$com1so that Grub parses it correctly as a hexadecimal number. It definitely is a hexadecimal number, as Grub usesgrub_snprintf(buf, sizeof (buf), "%x", value)to construct it.Quote from: georgian on October 24, 2020, 05:12:40 pmYes, 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 0x3FEinb -v com1 0x3FEcom1=0x$com1to hopefully clear the low four bits that aren't that interesting. I don't think Grub has built-in arithmetic or binary operators, otherwisecom1=$[0x$com1 & 0xF0]would have been extremely useful for this. Also note that the value you are treating as a decimal is actually hexadecimal, becauseinbdoes 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 0x3FEregexp --set 1:com1 '^[0-9A-Fa-f]*([0-9A-Fa-f])[0-9A-Fa-f]$' 00$com1com1=0x$com1in which casecom1matches a number between 0-15, as if it had been divided by 16. The idea is that thePOSIX extended regular expressionin 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 tocom1. The string it operates on has two zeros prepended, so that the regexp works correctly even whencom1contains only a single hex digit. (But do check it for bugs, I haven't tested it.)

author: LeonR
author_rank: Regular Contributor
timestamp: October 24, 2020, 11:18:47 pm
content: 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.htmlAlternatively, 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.

author: georgian
author_rank: Regular Contributor
timestamp: October 25, 2020, 09:11:07 am
content: Quote from: LeonR on October 24, 2020, 11:18:47 pmI 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

author: Doctorandus_P
author_rank: Super Contributor
timestamp: October 31, 2020, 05:01:10 am
content: 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.