⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 firmware-loading-debacle

📁 CNC 的开放码,EMC2 V2.2.8版
💻
字号:
debacle: a complete and ludicrous failure; a rout, as of an army;    a great disaster; a fiascoThe Mesa Anything I/O boards have FPGAs that need to be programmedwith firmware (such as HostMot2) before they can do anything useful.The firmware is stored on the host computer.  The host computer sendsthe firmware to the Anything I/O board at startup, using a communicationmechanism very similar to the mechanism it uses to communicate with thefirmware during normal operation later.Each board has several possible HostMot2 firmwares it can run, eachproviding different combinations of quadrature counters, PWM generators,step/dir generators, etc.  The user must decide which firmware to runon which board.When emc2 is installed as a Debian package, the firmware files areinstalled in /lib/firmware/hm2.  When emc2 is compiled from source andrun-in-place (RIP), the firmware files are located in the user's sandbox,usually in a random user-chosen directory.  The user may have severaldifferent sandboxes, each using RIP.There are two reasonable-seeming ways to send the firmware to the boards:via the normal kernel driver, or via a separate userspace utility.1.  kernel driver loads firmware    The 2.6 kernel has a mechanism that allows a device driver to    request a firmware file; udev fetches the file and delivers it to    the driver.  The mechanism is documented in the linux kernel source,    in Documentation/firmware_class/README.  It's widely used and well    supported.    The default solution would of course be to use this existing    infrastructure to accomplish firmware loading.  The driver would    accept a modparam string where the user specified the firmware to    load on each board.  If the user did not specify a firmware name, the    driver would not try to program the FPGA, or it might use a default    one.  A typical firmware name might be "hm2/7i43/SVST4_4S.BIT".    udev would deliver the requested firmware and the driver would    program the FPGA.    There are several reasons this solution would be desirable:        Having all the code that talks to the boards in one place (the        device driver) is natural and simple.        The kernel has full, unfettered access to the boards, whereas        access to PCI and EPP devices from userspace is awkward.        This solution avoids issues with userspace library availability,        library version skew, etc, though at the expense of kernel        version skew.  The kernel firmware interface has been stable        for a long time now, so this seems like a good trade.    Unfortunately the kernel firmware interface has shortcomings that    make it awkward to use with emc2.    The standard kernel firmware loading userspace helper searches for    firmware in a small set of standard system directories (/lib/firmware    & friends).  This would work great when emc2 is installed by .deb    package, but wouldnt work out-of-the-box with RIP: the firmware    helper doesnt know to look in the user's sandbox.    RIP with the standard userspace helper would thus require that the    user symlink their sandboxes' firmware directories into /lib/firmware.    This would violate the system's integrity by placing files in the    public part of the filesystem without going through the package    manager.    One way to avoid that problem would be to tweak udev to allow    kernel drivers to specify absolute paths to the firmware    they want.  udev is flexible, and it's possible to provide    alternate firmware helper scripts to handle loading firmwares    from other places.  Some documentation on how to do this is here:    <http://reactivated.net/writing_udev_rules.html>.  This would require    installing a custom udev rule in /etc/udev/rules.d (emc2 already does    this, to tweak the permissions of the rtai fifos) and installing a    custom firmware helper.    The driver's firmware modparam would specify the absolute path to    the firmware file to load on each board, and the custom userspace    firmware helper would fetch the file and deliver it to the driver.    This would work well, except...  The kernel imposes a 30-character    limit on the filename of the requested firmware (FIRMWARE_NAME_MAX    in include/linux/firmware.h).  Firmwares in sandboxes tend to be    in deeply nested subdirectories, with paths much longer than this.    So absolute firmware paths are basically infeasible.  Custom udev    firmware helpers can't help with this, it's a kernel limitation.    The firmware name length limitation also affects the "symlink    sandboxes into /lib/firmware" solution.  The sample firmware name    given above is 21 characters, leaving just 8 characters for the name    of the sandbox-symlink.  Tight but not impossible.    Thus the only way to do in-kernel firmware loading (as of Linux    2.6.24) is to install emc2 via the .deb, or to symlink the user's    active RIP sandboxes into /lib/firmware.2.  userspace utility (bfload) loads firmware    This has the advantage that userspace has full access to the    filesystem, so accessing firmware files in arbitrary sandbox    directories is easy.    However, it also has several drawbacks:        It's clumsy to have two pieces of code driving the boards.        I/O conflicts must be detected and avoided, and this is fraught        with race conditions.  I think this is not a huge problem in        practice, but it smells bad.        EPP I/O must be done "manually" with ins and outs, since the        standard Linux parport driver is unsuitable for use with RTAI.        Properly initializing the PCI boards requires access to both the        PCI Config space and the board's normal BARs (both memory and IO).        Userspace PCI access is via one of several libraries:            upci (the current emc2 PCI access library) supports IO and            Memory BAR access but lacks PCI Config space access            libpci supports Config space access but lacks BAR access            libpciaccess supports Config space and Memory BARs, but not            IO BARs    The cleanest way to handle the PCI access issue would be to have one    PCI library that provided all the access methods needed.  No such    library currently exists to my knowledge, and certainly none is    available on all our supported platforms.    The PCI access issue can be fixed a couple of ways:        Use upci and libpci together (gross).        Merge upci into libpci or libpciaccess (clean) and fork the        result into our tree to support old distros without the new        upstream library (gross).        Shell out to setpci where needed.  This would only be sensible        for very simple situations where no feedback is required (such as        the current situation).  This solution is slightly complicated by        the fact that system(3) explicitly clears the setuid bit before        running the shell.  bfload would have to reimplement system()        without this safety feature, calling fork and exec manually.So the implemented solution is firmware loading from kernel space.RIP users must symlink their sandboxes' firmware directories into/lib/firmware and everything works fine.  This is documented in thehostmot2 man page.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -