I'm sponsoring this fast-track request for Freeman Liu.  The timer is
set to 06/22/2007.  (A brief summary: 2005/050 interfaces are now
Committed, patch/micro release binding.)


Background

        Many hardware devices contain some software to function correctly.
        Traditionally, this piece of software was stored in non-volatile 
        storage and thus called firmware. But recently, more and more 
        hardware vendors replaced the non-volatile memory with volatile
        one to lower cost. For example, Intel 3945 wifi card and Intel
        wusb devices. And the "firmware", which comes in the form
        of an image file, now needs to be downloaded into the hardware 
        before the hardware can fully function. 

        Most of other main-stream OSes provide interfaces to access firmware
        in raw-data format. But the shortage of the raw-data format is that 
        authentication check is not available. Therefore, we prefer to wrap
        the raw-data format firmware image in a kernel module so that we can
        sign and verify it by elfsign.
        
        In Solaris, the existing interfaces ddi_modopen, ddi_modsym and 
        ddi_modclose serve this purpose very well. These interfaces have been 
        used inside Sun for several cases including md, kcf and brandZ and are 
        mature. However, these interfaces are private ones and can not be 
        leveraged by hardware vendors and communities. 

        This proposal is a follow up to "ddi_modopen dynamically
        access a loadable kernel module" (PSARC 2005/050).  It is
        necessary to becoming familiar with that case to understand
        this issue.

Competitive Analysis

        Windows provides interfaces to load firmware and sign at the package
        level. Windows requires all kernel components signed for the 64-bit 
        platform.  A signature can be stored in the .cat file of a package 
        which contains the checksum of selected files in the packages.

        Linux adopts similar solution. For example, rpm provides signature
        function.

Proposal

        We propose to make the interfaces ddi_modopen, ddi_modclose and 
        ddi_modsym in 2005/050 Committed.

        We will use these interfaces to deliver separate firmware files on
        Solaris, and encourage other developers to use the interfaces in this 
        way as well.

        Compared to other solutions, this proposal has many advantages.
        First, it can enable drivers to load and unload the image dynamically.
        This avoids unnecessary waste of ram. Second, because dependency can
        be set between drivers and the firmware image module, the potential boot
        device can rely on this to load firmware. Third, it can signed to
        ensure the authentication.

        This proposal requires a patch release binding so that it can be 
        backported to S10 updates. But it will not be back ported to S9
        and earlier version for the same reason mentioned in 2005/050 that
        doing that requires many of the module loading bugs fixed in s10 
        to be back ported too.

Interfaces

    ------------------------------------------------------------------
    Interface Name              Stability       Comments
    ------------------------------------------------------------------

    KRTLD_MODE_FIRST            Commited        Mode argument to
                                                ddi_modopen(9F).

    ddi_modhandle_t             Commited        Opaque handle returned
                                                by ddi_modopen(9F).

    ddi_modopen(9F)             Commited        Peer of dlopen(3C)

    ddi_modsym(9F)              Commited        Peer of dlsym(3C)

    ddi_modclose(9F)            Commited        Peer of dlclose(3C)

Prototypes (defined in modctl.h)

    #define     KRTLD_MODE_FIRST        0x0001

    typedef struct __ddi_modhandle      *ddi_modhandle_t;

    extern ddi_modhandle_t              ddi_modopen(const char *modname,
                                            int mode, int *errnop);

    extern void                         *ddi_modsym(ddi_modhandle_t handle,
                                            const char *symname, int *errnop);

    extern int                          ddi_modclose(ddi_modhandle_t handle);

    #pragma unknown_control_flow(ddi_modopen, ddi_modsym, ddi_modclose)

Documentation
        Manpage for ddi_modopen, ddi_modsym and ddi_modclose will be added.

        A section about "Dynamic module access functions" will be added to
        Appendix B of "Writing Device Drivers".

        The dynamic way to fulfill the dependency of modules will be added  to
        the section "Module dependencies" of Chapter 20 of "Writing Device
        Drivers".

Boundary Condition
        This proposal does not cover the case to upgrade firmware in 
        non-volatile memory, such as flash. That always needs to stop
        the hardware and the upgrade process is usually done by a program
        provided by vendor.
        
        This proposal does not provide ways to avoid name conflict
        between the firmware image module. The module provider should
        name it reasonably to avoid that.

        This proposal does not cover the case to load raw-data format 
        firmware.

Reference
        http://sac.sfbay/PSARC/2005/050/
        RPM manpage: http://www.netadmintools.com/html/8rpm.man.html
        (Windows) Code Signing Best Practices: 
http://download.microsoft.com/download/a/f/7/af7777e5-7dcd-4800-8a0a-b18336565f5b/best_practices.doc

Reply via email to