sab8253xds.txt
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:90k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. *_Design Specification of SAB8253X ASLX Driver for Linux_*
  2.  
  3.   The effort to design and implement the ASLX SAB8253X Driver for Aurora
  4.   <http://www.auroratech.com/> hardware with the functionality described
  5.   in *_Functional Specification of SAB8253X ASLX Driver for Linux
  6.   <http://www.telfordtools.com/sab8253x/sab8253xfs.html>_* requires
  7.   solutions to seven separate problems:
  8.  
  9.    1. creating a development environment for maintaining and extending
  10.       the driver,
  11.    2. integrating the driver into the kernel sources,
  12.    3. creating a file structure of the driver that aids understanding,
  13.    4. crafting a reasonable and easy to use user interface,
  14.    5. developing simple tools and example programs for the driver, and
  15.    6. designing the driver data structures and
  16.    7. designing the driver program logic.
  17.  
  18.   _Development Environment_
  19.  
  20.       There are several possible approaches to creating a development
  21.       environment.  The development environments for many drivers seem
  22.       to have consisted simply of a single machine, and the developer
  23.       used only /printk()/ in the driver code to debug.  I used such an
  24.       environment to develop a driver for an IOP480 based intelligent
  25.       adapter card.
  26.  
  27. For a driver that provides the functionality described in the Functional
  28. Specification, a more sophisticated development and debugging
  29. environment is useful.  (One could even occasionally wish for an ICE,
  30. but that level of resources was not available to me.)
  31.  
  32. The development environment consisted of two 686 class machines, on
  33. which the Linux operating system was installed.  One machine ran at 800
  34. Mhz, the other at 1Ghz.  It probably would have been worthwhile to have
  35. dual processor machine, and one was added to the development environment
  36. later.  The 800 Mhz machine hosted the remote gdb application.  It ran
  37. Redhat Linux 7.0, but because the machine served only as an NFS and
  38. remote gdb host, the details of the Linux distribution on this machine
  39. are not particularly important.
  40.  
  41. The target machine on which the driver was developed and debugged hosted
  42. Suse Linux 7.1 and was later upgraded to Suse Linux 7.3.  Suse Linux
  43. seemed to provide the most complete Linux distribution with the least
  44. hassle in installation.  (As the Suse distribution comes on 7 standard
  45. CDs or 1 DVD, there is a lot of value in having a DVD drive in the
  46. target machine [and the gdb host if it runs a Suse distribution].)
  47.  
  48. The target and remote gdb machines are connected by a 100 Mbps Ethernet
  49. network and by a serial crossover cable between the Com1 (ttyS0) ports. 
  50.  
  51. When I started developing the driver, I obtained the Linux 2.4.3 sources
  52. from The Linux Kernel Archives <http://www.kernel.org/>.  Later as later
  53. distributions became stable, I switched to the Linux 2.4.6
  54. distribution.  The sources were installed first in
  55. /home/martillo/kernel/linux-2.4.3 and then in
  56. /home/martillo/kernel/linux-2.4.6 on the remote gdb host machine, which
  57. was named frolix.
  58.  
  59. The sources were imported into CVS on frolix, and the core directory
  60. into CVS  was added manually because the cvs import function ignores
  61. it.  I consider it safer to maintain the CVS repository on the remote
  62. gdb host machine instead of the target machine because the target
  63. machine is likely to crash frequently, and its file system may be put
  64. into bad states.
  65.  
  66. I executed the following commands on the remote gdb host machine.
  67.  
  68. *ln ^謘 /home/martillo/kernel/linux-2.4.3/include/asm-i386
  69. /home/martillo/kernel/linux-2.4.3/include/asm*
  70. * *
  71. or
  72. * *
  73. *ln ^謘 /home/martillo/kernel/linux-2.4.6/include/asm-i386
  74. /home/martillo/kernel/linux-2.4.6/include/asm*
  75. * *
  76. *ln ^謘 / /frolix *
  77.  
  78. I edited the /etc/exports file to contain the following.
  79.  
  80. /               ylith(rw)
  81. /               fireball(rw)
  82. /               bohun(rw)
  83. /               indefatigable(rw)
  84.  
  85. Ylith is the original 1 Ghz target machine.  Fireball is a 400 Mhz
  86. compact PCI target machine.  Indefatigable is a dual 1 Ghz target
  87. machine.  Bohun is a Solaris target machine used for another project.
  88.  
  89. On the frolix, I started NFS with the following commands (contained in a
  90. shell script).
  91.  
  92. */etc/rc.d/init.d/nfs start*
  93. *exportfs -va*
  94.  
  95. If it had been a Suse Linux machine, I would have used the yast2 control
  96. center to start NFS service.
  97.  
  98. On ylith, I created an empty directory /frolix and executed the
  99. following command.
  100.  
  101. *mount frolix:/ /frolix*
  102. * *
  103. At this point both the remote gdb host (frolix) and the target
  104. development and debugging machine can refer to the same files by the
  105. same paths.  I could have guaranteed the same paths to the source files
  106. on both machines if I had simply used /home/martillo as my home
  107. directory on frolix and exported /home from frolix to all the other
  108. machines so that there would only be one /home directory for all the
  109. machines in my network.  I was lazy about the network configuration.
  110.  
  111. After making sure that the user martillo had read write access
  112. permissions to all the kernel sources, I built the kernel on the target
  113. machine from within xemacs with the following sequence of commands.
  114.  
  115. From a shell window:
  116. *xemacs ^謊 shell&*
  117.  
  118. Inside xemacs:
  119.  
  120. *cd /frolix/home/martillo/kernel/linux-2.4.3*
  121.  
  122. or
  123.  
  124. *cd /frolix/home/martillo/kernel/linux-2.4.6*
  125.  
  126. Then make sure that linux-2.4.x/include/asm-i386 is symbolically linked to
  127. linux-2.4.x/include/asm.
  128.  
  129. Execute the following emacs command.
  130.  
  131.           M-x compile
  132.  
  133. This command prompts for targets.
  134.  
  135. In the development environment the most useful target string was usually
  136. /clean xconfig dep bzImage modules./ The target /xconfig /brings up a
  137. configuration window.  In the basic development environment, it was
  138. generally worthwhile to add SCSI CD ROM, SCSI legacy support, an
  139. Ethernet driver and DOS file system support
  140.  
  141. The target/ dep/ creates the dependencies (note that if the kernel tree
  142. is ever removed, the .depend and .hdepend files must be regenerated). 
  143. The /bzImage /target builds the kernel.  The /modules/ target generates
  144. all the modules to be dynamically installed in the kernel via the
  145. *insmod* command.
  146.  
  147. After building the kernel, installing the modules in the /lib tree
  148. requires the execution (as root) of
  149.  
  150. make modules_install
  151.  
  152. The command *make install* *INSTALL_PATH=/boot* will install the
  153. compressed kernel image as vmlinuz along with other files in the /boot
  154. partition.  I preferred to use a shell script with commands like the
  155. following.
  156.  
  157. cp /frolix/home/martillo/kernel/linux-2.4.6/arch/i386/boot/bzImage
  158. /boot/vmlinuz_246
  159. cp /frolix/home/martillo/kernel/linux-2.4.6/System.map
  160. /boot/System.map-2.4.6
  161. cp /frolix/home/martillo/kernel/linux-2.4.6/.config /boot/vmlinuz_246.config
  162. cp /frolix/home/martillo/kernel/linux-2.4.6/include/linux/autoconf.h
  163. /boot/vmlinuz_246.autoconf.h
  164. cp /frolix/home/martillo/kernel/linux-2.4.6/include/linux/version.h
  165. /boot/vmlinuz_246.version.h
  166.  
  167. When the kernel comes from a linux-2.4.3 tree, the obvious substitutions
  168. of 3 for 6 are required.
  169.  
  170. Once all the modules and the kernel image are installed, the next step
  171. in giving the system the ability to boot with the new linux-2.4.3 or
  172. linux-2.4.6 kernel image is the modification of the lilo.conf file.
  173.  
  174. I added the following directives to the lilo.conf file.
  175.  
  176.   image  = /boot/vmlinuz_243
  177.   label  = linux_2.4.3
  178.   root   = /dev/hde7
  179.   optional
  180.  
  181.   image  = /boot/vmlinuz_246
  182.   label  = linux_2.4.6
  183.   root   = /dev/hde7
  184.   optional
  185.  
  186. In this case /dev/hde7 corresponds to the /boot partition, and the
  187. options linux_2.4.3 and linux_2.4.6 will be added to the boot menu once
  188. the *lilo* command has been executed.  In other system setups the disk
  189. partition that corresponds to /boot might have a different name like
  190. /dev/hda7.
  191.  
  192. Once the new kernel successfully boots, the next step to creating a
  193. driver development and debugging environment is patching the kernel for
  194. remote gdb debugging.
  195.  
  196. The necessary patch can be obtained from kgdb: Source level debugging of
  197. linux kernel <http://kgdb.sourceforge.net/downloads.html>.
  198.  
  199. Now the kernel can be built again with the extra step of configuring for
  200. remote gdb support in the kernel configuration menu. 
  201.  
  202. The following directives should be added to lilo.conf.
  203.  
  204.   image  = /boot/vmlinuz_243
  205.   label  = debug243
  206.   append = "gdb gdbttyS=0 gdbbaud=115200"
  207.   root   = /dev/hde7
  208.   optional
  209.  
  210.   image  = /boot/vmlinuz_246
  211.   label  = debug246
  212.   append = "gdb gdbttyS=0 gdbbaud=115200"
  213.   root   = /dev/hde7
  214.   optional
  215.  
  216.       Then lilo can be executed.  On reboot the boot menu will include
  217.       options for debug243 and debug246.
  218.  
  219. To test the patch, select one of the debug options.  Then, on the remote
  220. gdb host machine execute the following command.
  221.  
  222. stty 115200 < /dev/ttyS0
  223.  
  224. Start up an *xemacs* process.  Execute the following commands within
  225. *xemacs.*
  226.  
  227.           M-x shell
  228.  
  229. Then within the shell window execute the following command.
  230.  
  231. cd /frolix/home/martillo/kernel/linux-2.4./X/
  232. / /
  233. Then invoke the remote debugger.
  234.  
  235.           M-x gdb
  236.  
  237. Reply to the file prompt with *vmlinux.*
  238. * *
  239. In the gdb window, execute the following command.
  240.  
  241. target remote /dev/ttyS0
  242.  
  243. The gdb window should break in gdbstub.c which will be displayed in the
  244. gdb source window.
  245.  
  246. At this point, all the basic gdb remote debugging capabilities are ready
  247. to use.
  248.  
  249. To access the hardware breakpoint capability of the i386 processor, the
  250. following commands can be loaded directly or from a file with the
  251. *script* command.
  252.  
  253. #Hardware breakpoints in gdb
  254. #
  255. #Using ia-32 hardware breakpoints.
  256. #
  257. #4 hardware breakpoints are available in ia-32 processors. These breakpoints
  258. #do not need code modification. They are set using debug registers.
  259. #
  260. #Each hardware breakpoint can be of one of the
  261. #three types: execution, write, access.
  262. #1. An Execution breakpoint is triggered when code at the breakpoint
  263. address is
  264. #executed.
  265. #2. A write breakpoint ( aka watchpoints ) is triggered when memory location
  266. #at the breakpoint address is written.
  267. #3. An access breakpoint is triggered when memory location at the breakpoint
  268. #address is either read or written.
  269. #
  270. #As hardware breakpoints are available in limited number, use software
  271. #breakpoints ( br command in gdb ) instead of execution hardware
  272. breakpoints.
  273. #
  274. #Length of an access or a write breakpoint defines length of the datatype to
  275. #be watched. Length is 1 for char, 2 short , 3 int.
  276. #
  277. #For placing execution, write and access breakpoints, use commands
  278. #hwebrk, hwwbrk, hwabrk
  279. #To remove a breakpoint use hwrmbrk command.
  280. #
  281. #These commands take following types of arguments. For arguments associated
  282. #with each command, use help command.
  283. #1. breakpointno: 0 to 3
  284. #2. length: 1 to 3
  285. #3. address: Memory location in hex ( without 0x ) e.g c015e9bc
  286. #
  287. #Use the command exinfo to find which hardware breakpoint occured.
  288.  
  289.  
  290. #hwebrk breakpointno address
  291. define hwebrk
  292.         maintenance packet Y$arg0,0,0,$arg1
  293. end
  294. document hwebrk
  295.         hwebrk breakpointno address
  296.         Places a hardware execution breakpoint
  297. end
  298.  
  299. #hwwbrk breakpointno length address
  300. define hwwbrk
  301.         maintenance packet Y$arg0,1,$arg1,$arg2
  302. end
  303. document hwwbrk
  304.         hwwbrk breakpointno length address
  305.         Places a hardware write breakpoint
  306. end
  307.  
  308. #hwabrk breakpointno length address
  309. define hwabrk
  310.         maintenance packet Y$arg0,1,$arg1,$arg2
  311. end
  312. document hwabrk
  313.         hwabrk breakpointno length address
  314.         Places a hardware access breakpoint
  315. end
  316.  
  317. #hwrmbrk breakpointno
  318. define hwrmbrk
  319.         maintenance packet y$arg0
  320. end
  321. document hwrmbrk
  322.         hwrmbrk breakpointno
  323.         Removes a hardware breakpoint
  324. end
  325.  
  326. #exinfo
  327. define exinfo
  328.         maintenance packet qE
  329. end
  330. document exinfo
  331.         exinfo
  332.         Gives information about a breakpoint.
  333. end
  334.  
  335. Once the above macros are define, the developer can set hardware
  336. breakpoints.
  337.  
  338. The next step to creating a useful development and debugging environment
  339. is to provide a shell script to for remote debugging of dynamically
  340. loaded modules.  The following shell script (called *loadmodule.sh*)
  341. creates a gdb script called *load/ModuleName/* in
  342. /frolix/home/martillo/kernel/linux-2.4.6 when it is invoked (as root)
  343. with the following command.
  344. loadmodule.sh modulename
  345.  
  346. In order to decrease the probability of confusion, I usually make a link
  347. in kernel root directory,  /frolix/home/martillo/kernel/linux-2.4.6, to
  348. the location of the module to be debugged in the kernel tree.  The above
  349. command is invoked on the target machine (ylith) in the root directory. 
  350. On the remote debug machine, in the gdb command window, whose working
  351. directory should be the kernel root directory,
  352. /frolix/home/martillo/kernel/linux-2.4.6, the command, *script
  353. load/ModuleName/*, is invoked.  Once the script is executed the symbols
  354. for the module are available for remote symbolic debugging.
  355.  
  356. #!/bin/sh
  357. # This script loads a module on a target machine and generates a gdb script.
  358. # source generated gdb script to load the module file at appropriate
  359. addresses
  360. # in gdb.
  361. #
  362. # Usage:
  363. # Loading the module on target machine and generating gdb script)
  364. #       [foo]$ loadmodule.sh <modulename>
  365. #
  366. # Loading the module file into gdb
  367. #       (gdb) source <gdbscriptpath>
  368. #
  369. # Modify following variables according to your setup.
  370. #       TESTMACHINE - Name of the target machine
  371. #       GDBSCRIPTS - The directory where a gdb script will be generated
  372. #
  373. # Author: Amit S. Kale (akale@veritas.com).
  374. #
  375. # If you run into problems, please check files pointed to by following
  376. # variables.
  377. #       ERRFILE - /tmp/<modulename>.errs contains stderr output of insmod
  378. #       MAPFILE - /tmp/<modulename>.map contains stdout output of insmod
  379. #       GDBSCRIPT - $GDBSCRIPTS/load<modulename> gdb script.
  380.  
  381. TESTMACHINE=ylith
  382. GDBSCRIPTS=/frolix/home/martillo/kernel/linux-2.4.6
  383.  
  384. if [ $# -lt 1 ] ; then {
  385.         echo Usage: $0 modulefile
  386.         exit
  387. } ; fi
  388.  
  389. MODULEFILE=$1
  390. MODULEFILEBASENAME=`basename $1`
  391.  
  392. if [ $MODULEFILE = $MODULEFILEBASENAME ] ; then {
  393.         MODULEFILE=`pwd`/$MODULEFILE
  394. } fi
  395.  
  396. ERRFILE=/tmp/$MODULEFILEBASENAME.errs
  397. MAPFILE=/tmp/$MODULEFILEBASENAME.map
  398. GDBSCRIPT=$GDBSCRIPTS/load$MODULEFILEBASENAME
  399.  
  400. function findaddr() {
  401.         local ADDR=0x$(echo "$SEGMENTS" | 
  402.                 grep "$1" | sed 's/^[^ ]*[ ]*[^ ]*[ ]*//' | 
  403.                 sed 's/[ ]*[^ ]*$//')
  404.         echo $ADDR
  405. }
  406.  
  407. function checkerrs() {
  408.         if [ "`cat $ERRFILE`" != "" ] ; then {
  409.                 cat $ERRFILE
  410.         } fi
  411. }
  412.  
  413. #load the module
  414. #echo Copying $MODULEFILE to $TESTMACHINE
  415. #*rcp $MODULEFILE root@${TESTMACHINE}:
  416.  
  417. echo Loading module $MODULEFILE
  418. #rsh -l root $TESTMACHINE  /sbin/insmod -m ./`basename $MODULEFILE` 
  419. #       > $MAPFILE 2> $ERRFILE &
  420. /sbin/insmod -m ./`basename $MODULEFILE` $2 . .  > $MAPFILE 2> $ERRFILE &
  421. sleep 5
  422. checkerrs
  423.  
  424. NUMLINES=`grep -n '^$' $MAPFILE | sed -e 's/:.*//g'`
  425. SEGMENTS=`head -n $NUMLINES $MAPFILE | tail -n $(eval expr $NUMLINES - 1)`
  426. TEXTADDR=$(findaddr "\.text[^.]")
  427. LOADSTRING="add-symbol-file $MODULEFILE $TEXTADDR"
  428. SEGADDRS=`echo "$SEGMENTS" | awk '//{
  429.         if ($1 != ".text" && $1 != ".this" &&
  430.             $1 != ".kstrtab" && $1 != ".kmodtab") {
  431.                 print " -s " $1 " 0x" $3 " "
  432.         }
  433. }'`
  434. LOADSTRING="$LOADSTRING $SEGADDRS"
  435. echo Generating script $GDBSCRIPT
  436. echo $LOADSTRING > $GDBSCRIPT
  437.  
  438. With the addition of the above shell script, the driver development and
  439. debugging environment is almost complete.  Other useful tools for
  440. developing and debugging this type of serial driver would include a
  441. Wanalyzer (I used an Interview 7700 and an HP 4952A in developing this
  442. driver), a breakout box that displays interface signal states and  (for
  443. developing the serial Ethernet-like network driver) several WAN LAN VLAN
  444. routers as described in *Packet Switching Software and Platforms
  445. <http://members.aol.com/Telford001/vrouter2g.html>*, *Routing in a
  446. Bridged Network <http://members.aol.com/Telford001/routetti2.html>, **A
  447. WAN SUBSYSTEM for a High Performance Packet Switch
  448. <http://members.aol.com/Keleustes/syncdob.html>* and *A New High
  449. Performance Architecture for Routers, Bridges and LAN Switches (Software
  450. Defined Internetworking)
  451. <http://members.aol.com/Ishtar7713/private/sdi4.html>.*
  452.  
  453.   _Integration into the Kernel Sources_
  454.    
  455. The driver has its own directory, {kernel root
  456. directory}/drivers/net/wan/8253x, in the 2.4.* kernel source tree.
  457.  
  458. To facilitate the automatic build of the 8253x driver, the following
  459. standard kernel files were modified.
  460.  
  461. 1.                  {kernel root directory}/drivers/net/wan/Config.in to
  462. which the line
  463.  
  464. tristate '  Aurora Technology, Inc. synchronous asynchronous PCI cards
  465. V2' CONFIG_ATI_XX20
  466.  
  467. was added,
  468. 2.                  {kernel root directory}/drivers/net/wan/Makefile to
  469. which the following lines were added,
  470.  
  471. subdir-$(CONFIG_ATI_XX20) += 8253x
  472.  
  473. ifeq ($(CONFIG_ATI_XX20),y)
  474.   obj-y += 8253x/ASLX.o
  475. endif
  476.  
  477. When the driver is built as a dynamically loaded module, the following
  478. macro commands in the file 8253xini.c puts the module entry points in
  479. the special module entry point segment.
  480.  
  481. module_init(auraXX20_probe);
  482. module_exit(auraXX20_cleanup);
  483.  
  484. The sources are provided to the users in a patch file, tentatively named
  485. 8253x.patch <http://www.telfordtools.com/sab8253x/8253x.patch>.
  486.  
  487. To install it the user sets his directory to the top level of the kernel
  488. sources and executes the following command.
  489.  
  490. patch ^謕1 < /{directory-patch}//8253x.patch
  491.    
  492.   _File Structure of the ASLX Driver Source Code_
  493.  
  494. The following files are present in the driver directory.
  495.  
  496. 8253x.h
  497. 8253xdbg.c
  498. 8253xmac.c
  499. 8253xsyn.c
  500. PciRegs.h
  501. crc32.h
  502. sp502.h
  503. 8253xcfg.c
  504. 8253xini.c
  505. 8253xnet.c
  506. 8253xtty.c
  507. Reg9050.h
  508. crc32dcl.h
  509. ring.h
  510. 8253xctl.h
  511. 8253xioc.h
  512. 8253xplx.c
  513. 8253xint.c
  514. crc32.c
  515. endian.h
  516. Makefile
  517. Amcc5920.c
  518. 8253xmcs.h
  519. 8253xmcs.c
  520. 8253xchr.c
  521. 8253xutl.c
  522.  
  523.  
  524.  
  525. The source code is divided functionally among the files of the ASLX driver.
  526.  
  527. 8253xcfg.c is the source for a user application that configures 8253x
  528. control registers to provide clocking.  8253xmac.c is the source for a
  529. user application that sets a pseudo-MAC address for the network driver.
  530.  
  531. 8253xini.c contains the initialization/probe logic.
  532.  
  533. 8253xint.c contains the common interrupt logic.
  534.  
  535. 8253xtty.c contains the asynchronous TTY logic.
  536.  
  537. 8253xsyn.c contains the synchronous TTY logic.
  538.  
  539. 8253xnet.c contains the network driver logic.
  540.  
  541. 8253xchr.c contains the character driver logic.
  542.  
  543. 8253xdbg.c contains some debugging functions.
  544.  
  545. 8253xutl.c contains most of the functions that are common among the
  546. different driver functional subunits.
  547.  
  548. 8253xplx.c contains some functions specific to the PLX9050 (a PCI bridge
  549. chip) and specifically to reading and reprogramming the associated
  550. serial EEPROM.
  551.  
  552. amcc5920.c contains some functions specific to the AMCC5920 (a PCI
  553. bridge chip) and specifically to reading and reprogramming the
  554. associated serial EEPROM.
  555.  
  556. 8253xmcs.c contains functions specific to programming the multichannel
  557. server (mostly G-LINK related logic, programming the sp502 driver chip
  558. and reading or programming the serial EEPROM associated with the
  559. interface cards contained within the MCS unit).
  560.  
  561. crc32.c contains logic to append a CRC32 to a pseudo MAC frame that is
  562. generated by the network driver.
  563.  
  564. 8253x.h contains symbols, structures and macros that relate mostly to
  565. the 8253x chips and ports.
  566.  
  567. 8253xctl.h contains symbols, structures and macros that relate mostly to
  568. the adapter cards.
  569.  
  570. 8253xmcs.h contains symbols and structures that relate mostly to the
  571. multichannel server.  A lot of this file relates to G-LINK.
  572.  
  573. sp502.h contains symbols and structures that relate to the programming
  574. of the hardware interface line drivers of the 3500 adapter cards of the
  575. multichannel server.
  576.  
  577. 8253xioc.h contains symbols and structures that relate to private ioctls.
  578.  
  579. PciRegs.h contains symbols and structures that relate to PCI
  580. configuration space.
  581.  
  582. Reg9050.h contains symbols and structures that relate to the PLX9050 PCI
  583. interface chip and its serial eprom
  584.  
  585. crc32.h, crc32dcl.h and .endian.h contain symbols, structures and macros
  586. that relate to generating a correct CRC32.
  587.  
  588. ring.h contains symbols and structures that relate to the network driver
  589. frame transmission ring and frame reception.
  590.  
  591. The Makefile is a standard Linux kernel Makefile whose structure is
  592. dictated by the current Linux build formalism.
  593.  
  594.   _Using the ASLX Driver _
  595.    
  596.   The ASLX driver is designed to be a ^觩lug-and-play^