USB programming as MBR Program - mbr

I was wondering if it's possible for the MBR to read data from the USB port?
I'm wanting it to load windows or linux depending on the value it's read from the usb port

You should start with / customise GRUB. As it stands, in the MBR you have very little device support so you'll either have to code your own or try and build on your BIOS's USB device support if that's exposed as an API.
GRUB has built-in OHCI and UHCI USB drivers http://grub.enbug.org/USBSupport . I doubt it'll do exactly what you want out-of-the-box but it'll be easier to customise that rather than start from scratch.

It's highly doubtful that you can fit it into the 512-byte MBR itself, but there's no technical reason it can't be done otherwise - you just need to bootstrap a mini-OS which can read the value, and then act as a chain loader to start the boot loader of the right OS: both GRUB and the Vista bootloader is capable of chain loading to the other, so there's no reason you couldn't do the same.
Having said that, writing said mini-OS could very well prove to be more trouble than it's worth. Customizing an existing bootloader like GRUB is probably your best bet.

Related

How does a modern operating system like Windows or Linux know the chipset specific memory map?

The memory map of the peripherals are defined by the chipset. However, modern operating systems like linux and Windows can boot from pretty much every chip (if compiled for the right architecture). As far as I know, the memory mapped devices like the USB Host are not included in the architecture standard. How can the OS still boot, load the drivers, and function? I suppose there must be some specification where the chipset is described.
Formulated a little different: How does the identification of the chipset work, what standards define the communication between the chipset and the processor so that it works on different hardwares and how does the kernel know the right physical addresses for the different peripherals?
Open systems typically use a device tree, which is a specification of the attached hardware, and how it is attached. There is another system, ACPI which supports legacy PCs. Either system permits an OS to locate and configure the buses and associated peripherals it needs.
It is never 100% as easy as that. For example, it is fine for the OS to know there is a scsi controller on bus 1 at address 1000; but if the code for the scsi driver isn't in the loaded os image, then this knowledge is of little use, as it has no way to load the driver.
The intel specification for ACPI attempts to fix this by having tiny driver implementations baked into the firmware of either the platform, the device itself, or both. Since the device doesn't necessarily know what sort of cpu it will run on, these mini drivers are written in a virtual instruction set which the host OS requires an interpreter for.
UEFI provides an alternate way have addressing the boot dependency via a more generic mechanism to use mini-boot drivers for the same purpose.

How to flash without STLINK

My STLINKV2 is not working anymore, not detected by Linux, it failed after the first successful flash. I ordered a new one but it will take 60+ days to arrive. Meanwhile I have heard on Youtube you can program Bluepills directly by connecting cut open USB cable to certain pins and then using a jumper. But I cannot get any precie information on this, is this really possible and how?
You should use the embedded bootloader. You can flash it through several interfaces. Look at AN2606, maybe you can find an already written flasher. Good luck STM32CubeProgrammer handle it.
If you intend to program it through usb, look also at AN3156 all protocols document are referred in chapter 2 of AN2606
THOSE AREN'T CUT OPEN USB CABLES they are USB to serial adapters for arduino's bootloader
They connect them like this:
The problem is that this requires the Arduino STM32 bootloader to be flashed in it.
Another option will be to use STM32CubeProg this program allows you to program your stm over
Serial
SPI
I2C
USB
You'll need to set the BOOT0 and BOOT1 pins to the correct value (HIGH slash LOW) to allow it to go in flash mode during boot.
Here is semi outdated tutorial which tells most of the steps to program a STM using serial. (the Flash Loader Demonstrator is outdated and you should use STM32CubeProg)

Implementation of USB device driver on my own OS based in Linux

I’m on process of developing my own Operating System based in Linux.
This week we’re aiming to implement very simple USB device driver , which is quite hard to get basic algorithm .
However commonly it’s hard to find out some sources aside from commercial linux system.
And I want to get some advice about this .
Plus, I do all these stuffs on Ubuntu , using QEMU emulator.
I’ve done simple file system and hard disk device driver so far.
Help me out how to implement USB device driver with very sime ideas.
Thank you !! :)
Implementing USB is quite the task. First you must have a working PCI(e) enumerator or other form of finding the USB controller. You then must find out which of the four most common controller types it happens to be. Each controller type is completely different from the previous and must contain its own driver. You also need a standard USB interface that is independent of the controller type.
Taking on the USB is quite the task, but in my opinion a very interesting and enjoyable task. Enjoyable enough, that I even wrote a book about how to do it. It explains how to find the controller(s) via the PCI(e) bus, how to setup this bus, how to detect the type of USB controller--UHCI, OHCI, EHCI, or xHCI--and how to send and receive data packets to/from attached devices. This book was written exactly for the purpose of those of us creating our own operating systems and adding USB support to them. The fact that you are basing your OS on Linux should not matter since the book does not rely upon any existing OS to accomplish this task, other than the example programs relying on memory allocation, which is easily modified for your developing platform.
Might I say that if you do take on this task, it will be a difficult task, but it will be an enjoyable task. In my opinion, the USB is the most enjoyable part of this hobby of ours.

How drivers work out of the box in x86 and not in embedded computers like Android phone

I'm curious about how the drivers work out of the box in x86 motherboards, like display, USB controllers etc.
For example :
Booting a toy custom kernel in x86 can display to screen without doing any extra work on the drivers space, however for an Android phone which is an embedded system, it seems almost impossible to display to screen with my own toy custom kernel (as there is information out there available about the memory map of the device and how the display is interfaced with the device).
Why is that I/O works out of the box in x86 motherboards and doesn't on embedded computers?
x86 PC firmware has standard software interfaces (a lot like system calls), either modern UEFI or legacy BIOS int 0x10 and other interrupts.
The key point is that it's not just bare-metal x86, it's IBM PC-compatible which means software and even emulated legacy hardware like a PS/2 port, VGA, and even legacy interrupt controller.
If you didn't have all this help from firmware (for the benefit of bootloaders and toy OSes), you'd have a much harder job, e.g. needing at least a basic USB-hid and USB host-controller driver to get keyboard input. The lowest level function to handle a user input
Why is that I/O works out of the box in x86 motherboards and doesn't on embedded computers?
That's not your real question. Embedded machines have working I/O hardware, they just don't come with portable software APIs/ABIs wrapped around drivers as part of the firmware.
I think most vendor's SDK comes with functions to access the I/O hardware (after maybe doing some fiddling to get it into a usable state). i.e. to write your own driver for it.
Embedded doesn't need this in firmware because it's expected that the kernel will be customized for the hardware.
Wouldn't it be better to have a BIOS or UEFI for maximum portability? Does it have any drawbacks to include one?
Yes: code size in the boot ROM, and someone has to write + debug that code. This costs time and developer salary.
No point in booting up what's nearly an OS (a UEFI environment) just to load a kernel which is going to take over the HW anyway.
Also a downside in boot time: any code that runs other than loading the kernel where it wants to be is wasted CPU time that slows down the boot. Having a very lightweight interface that just lets you get your kernel loaded, and leaving all the I/O to it, makes sense for this.
Unlike x86 PCs, there's no expectation that you can use this hardware with an OS install disc / image you downloaded that isn't specifically customized for this hardware.
It's not intended to be easy for hobbyists to play with using training-wheels APIs. Real OSes on this hardware won't use such APIs so why provide them in the first place?

At boot time how OS determines all the hardware?

I have these related questions:
Does anybody know how an OS gets to know all hardware connected on the motherboard? (I guess this is called "Hardware Enumeration").
How does it determine what kind of hardware is residing at an specific IO address (i.e.: serial or parallel or whatever controller)?
How to code a system module which will do this job? (Assuming no OS loaded yet, just BIOS).
I know BIOS is just a validation and an user friendly interface to configure hardware at boot time with no real use after that for most modern OS's (win, Linux, etc). Besides I know that for the BIOS it should not be difficult to find all hardware because it is specifically tuned by the board manufacturer (who knows everything about it!). But for an OS or an application above BIOS that is a complete different story. Right?
Pre-PCI this was much more difficult, you needed a trick for each product, and even with that it was difficult to figure everything out. With usb and pci you can scan the busses to find a vendor and product id, from that you go into a product specific discovery (like the old days this can be difficult). Sometimes the details for that board are protected by NDA or worse you just dont get to know unless you work there on the right team.
The general approach is either based on detection (usb, pcie, etc vendor/product ids) you load a driver or write a driver for that family of product based on the documentation for that family of product. Since you mentioned BIOS, win, linux that implies X86 or a PC, and that pretty much covers the autodetectable. Beyond that you rely on the user who knows what hardware was installed in the system and a driver that came with it. or in some way you ask them what is installed (the specific printer at the end of a cable or out on the network if not auto detectable is an easy to understand example).
In short you take decades of experience in trying to succeed at this and apply it, and still fail from time to time since you are not in 100% control of all the hardware in the system, there are hundreds of vendors out there each doing their own thing.
BIOS enumerates the pci(e) for an x86 pc, for other platforms the OS might do it. The enumeration includes allocating address space for the device based on pci compliant rules. but within that address space you have to know how to program that specific board from vendor documentation if available.
Sorry my English is not very good.
Responding questions 1 and 2:
During the boot process, only the hardware modules strictly necessary to find and start the OS are loaded.
These hardware modules are: motherboard, hard drive, RAM, graphics card, keyboard, mouse, screen (that is detected by the graphics card), network card, CD / DVD, and a few extra peripherals such as USB units.
Each hardware module you connect to a computer has a controller that is like a small BIOS with all the information of the stored device: manufacturer, device type, protocols, etc
The detection process is very simple: the BIOS has hardcoded all the information about the motherboard, with all communication ports. At startup, the BIOS sends a signal to all system ports asking the questions "Who are you? What are you? How do you function?" and all attached devices answers by sending their information. In this way the computer knows how much RAM you have, if there is present a keyboard or a mouse, which storage devices are available, screen resolution, etc ...
Obviously, this process only works with the basic modules needed to boot the system, and does not work with complex peripherals that require specific drivers: printers, scanners, webcams ... all these complex peripherals are loaded by software once the OS has been charged.
Responding question 3:
If you wants to load a specific module during the boot, you must:
- Create a controller for this module.
- If the peripheral is too complex to load everything from the controller, you must to write all the proccess to control that module directly in the BIOS module, or reprogram the IPL to manage that specific module.
I hope I've helped
Actually, when you turn on your system, the BIOS starts the IPL (Initial program load) from ROM. For check the all connected devices are working good and also check the mandatory devices such as keyboard, CMOS, Hard disk and so on. If it is not success, it gives an error flag to the BIOS. The BIOS shows us the error through video devices.
If it is success, the control of boot is transferred to BIOS for further process.
The above all process are called POST (Power On Self Test).
Now the BIOS have the control. It checks all secondary memory devices for boot loader of the OS. If it hit, the bootloader's memory address is transferred to RAM.
The Ram started to execute the bootloader. Here only the os starts to run.
If the bootloader not hit, the bios shows us the boot failure error.
I hope your doubt clarified...