[U-Boot] Multiple device support - none at all?

ksi at koi8.net ksi at koi8.net
Thu Mar 12 19:07:00 CET 2009


On Thu, 12 Mar 2009, Detlev Zundel wrote:

> Hello ksi (so I'll leave it at that),
> 
> > First of all, there are several bootable devices on a motherboard itself.
> > These days almost every motherboard has PATA and some kind of SATA RAID
> > controller onboard. Then, it can usually boot off of USB while having USB
> > keyboard/mouse. As for add-on devices, it usually CAN boot off of those
> > devices. They have their own BIOS for that that gets attached to the
> > motherboard's one when it initializes and those devices are added to the
> > boot table.
> 
> It may come as a surprise to you, but I actually also use such system :)
> 
> What I wanted to say is that your blatant "it allows me to choose from
> which device to boot from" does not coincide with my experiences in real
> life.  Moreover what you call "to boot from" is in the BIOS world the
> transfer of usually one block followed by a jump.  I have yet to see a
> BIOS booting Linux in a flexible way.  This is hardly comparably to the
> support (just think filesystems) that we have for ages in U-Boot.  

Yes, that's great, but that filesystem _MUST_ reside on a device connected
to _ONE_ particular controller. And it becomes even more complicated if you
have a keyboard (or console) on USB...

> But actually I think that this is not news to most people on the ML so
> I'll stop here.
> 
> >> As Jerry pointed out - booting embedded hardware used to be a comparably
> >> simple operation ;)
> >
> > There is a whole world beyond that keyhole... Embedded devices yes, but
> > there are other boards that don't fall in that category. My current MPC8548
> > based board is not an embedded one, it is full-blown mATX motherboard with
> > several USB controllers, PATA, SATA, Video Capture, VGA/LCD controller,
> > PCI-X/PCI/PCIe connectors etc.
> 
> Yes, and again, you may notice that U-Boot was meant for "embedded
> devices" so the "impedance mismatch" you now realize for "full-blown
> motherboards" was kind of to be expected...

It is supposed to be a "Universal" bootloader. Here is what wiki says:

=== Cut ===
Das U-Boot (Universal Bootloader, short for "Das Unterseeboot", German for
"the submarine") is a boot loader for a number of different computer
architectures, including PPC, ARM, AVR32, MIPS, x86, 68k, Nios, and
MicroBlaze. 
=== Cut ===

I'm not even talking about using several USB/I2C/SPI/Serial/whatever devices
concurently; it is only about being able to pick one of several at run
time...

That is actually not sufficient because we have one device that must be
enabled at all times -- the console. That means we must have one USB
controller permanently enabled if we use USB keyboard that in turn means the
boot device absolutely must reside on that same controller in current
architecture.

> > ******************************************************************
> > *  KSI at home    KOI8 Net  < >  The impossible we do immediately.  *
> > *  Las Vegas   NV, USA   < >  Miracles require 24-hour notice.   *
> > ******************************************************************
> 
> Miracles in 24 hours?  Ok, I'm looking forward to a device model
> implementation tomorrow evening then ;)

Eh, I did offer such a model for I2C :) And that model can be extended to
anything else. That is what I'm actually implementing for my new board. But
that goes into $(BOARD)/* because I simply don't have time for pushing it
into the U-Boot proper. I wasted 2+ weeks for I2C without any result (that
is not counting another couple of weeks I spent on that before starting
sending patches to the list.)

The model can be really simple. Just use an array of structures with
function pointers to several adapter drivers and make a simple wrapper
calling an appropriate function depending on device chosen (i.e. "current"
device.) Don't call all e.g. USB adapter submit message functions
"submit_XXX_msg" and link that only one that is chosen at compile time and
exported. Make them e.g. "adapter_submit_XXX_msg" instead, then do something
like this:

=== Cut ===
	Header file:
.
.
.
typedef struct usb_functions_mux {
        int     (*submit_bulk_msg)(struct usb_device *dev,
                                        unsigned long pipe,
                                        void *buffer,
                                        int transfer_len);
        int     (*sumbit_control_msg)(struct usb_device *dev,
                                        unsigned long pipe,
                                        void *buffer,
                                        int transfer_len,
                                        struct devrequest *setup);
        int     (*submit_int_msg)(struct usb_device *dev,
                                        unsigned long pipe,
                                        void *buffer,
                                        int transfer_len,
                                        int interval);
        void    (*usb_event_poll)(void);
        int     (*usb_lowlevel_init)(void);
        int     (*usb_lowlevel_stop)(void);

        char    *name;
        int     inited;
} usb_func_t;
.
.
.

	USB adapter driver:
.
.
.
usb_func_t      sm501_usb_func {
        .submit_bulk_msg        =       sm501_submit_bulk_msg;
        .submit_control_msg     =       sm501_submit_control_msg;
        .submit_int_msg         =       sm501_submit_int_msg;
        .usb_event_poll         =       sm501_usb_event_poll;
        .usb_lowlevel_init      =       sm501_usb_lowlevel_init;
        .usb_lowlevel_stop      =       sm501_usb_lowlevel_stop;
        .name                   =       "SM501_OHCI"
        .inited                 =       0;
}
.
.
.


	USB wrapper:
.
.
.
extern usb_func_t       sm501_usb_func;
extern usb_func_t       isp1563_usb_func;

static usb_func_t *usb_func[] = {
        &sm501_usb_func,
        &isp1563_usb_func,
};

int     cur_usb_adap = 0;
.
.
.
int submit_bulk_msg(struct usb_device *dev,
                                unsigned long pipe,
                                void *buffer,
                                int transfer_len)
{
	return usb_func[cur_usb_adap]->submit_bulk_msg(dev,
							pipe,
							buffer,
							transfer_len);
}
.
.
.
=== Cut ===

---
******************************************************************
*  KSI at home    KOI8 Net  < >  The impossible we do immediately.  *
*  Las Vegas   NV, USA   < >  Miracles require 24-hour notice.   *
******************************************************************


More information about the U-Boot mailing list