<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-36435979</id><updated>2024-09-09T18:35:10.313+08:00</updated><category term="Linux 驅動程式篇"/><category term="Linux 參考資料篇"/><category term="Linux 應用程式篇"/><category term="Linux 綜合開發篇"/><category term="Linux 除錯工具篇"/><category term="Linux 網路程式篇"/><category term="Linux 課程導覽"/><category term="Linux 系統建置篇"/><title type='text'>Banto Linux</title><subtitle type='html'>Banto ARM Linux 教材, since 2004</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default?start-index=26&amp;max-results=25'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>46</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-36435979.post-4105273492962921154</id><published>2008-05-02T23:36:00.000+08:00</published><updated>2008-05-12T14:51:59.516+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 除錯工具篇"/><title type='text'></title><content type='html'>      &lt;h1 id=&quot;mpa50&quot;&gt;To rebuild strace for ARM Platform&lt;/h1&gt;&lt;br id=&quot;exua0&quot;&gt;&lt;font id=&quot;vz3:0&quot; color=&quot;#0000ff&quot;&gt;CC=arm-unknown-linux-gnu-gcc ./configure --target=arm-linux --host=arm-linux&lt;br id=&quot;exua1&quot;&gt;&lt;/font&gt;&lt;br id=&quot;exua2&quot;&gt;&lt;font id=&quot;f-0y0&quot; size=&quot;3&quot;&gt;,build就是你正在使用的机器,host就是你编译好的程序可以运行的平台,target就是你编译的程序可以处理的 平台.这个build和host比较好理解,但是target就不好办了,到底什么意思呢?一般来说,我们平时所说的交差编译用不到他target的,比 如./configure --build=i386-linux,--host=arm-linux就可以了,在386的平台上编译可以运行在arm板的程序.但是,一般我们都是 编译程序,而不是编译工具,如果我们编译工具,比如gcc,这个target就有用了.如果我们需要在一个我们的机器上为arm开发板编译&lt;br id=&quot;a7.00&quot;&gt;&lt;br id=&quot;a7.01&quot;&gt;參考自: &lt;a title=&quot;http://oss.lzu.edu.cn/blog/blog.php?/do_showone/tid_116.html&quot; href=&quot;http://oss.lzu.edu.cn/blog/blog.php?/do_showone/tid_116.html&quot; id=&quot;jvt:&quot;&gt;http://oss.lzu.edu.cn/blog/blog.php?/do_showone/tid_116.html&lt;/a&gt; &lt;br id=&quot;h3u60&quot;&gt;&lt;br id=&quot;a7.02&quot;&gt;&lt;/font&gt;&lt;br id=&quot;vz3:1&quot;&gt;       </content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/4105273492962921154/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/4105273492962921154' title='3 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/4105273492962921154'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/4105273492962921154'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2008/05/to-rebuild-strace-for-arm-platform.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-5386859829667387701</id><published>2008-04-26T12:53:00.000+08:00</published><updated>2008-05-12T14:51:43.057+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 驅動程式篇"/><title type='text'></title><content type='html'>&lt;H1 id=ay8t0&gt;Dummy Block Driver for Linux&lt;/H1&gt; &lt;P id=ay8t1&gt; &lt;/P&gt; &lt;P id=znuj0&gt;/*&lt;BR id=znuj1&gt; * Sample disk driver, from the beginning.&lt;BR id=znuj2&gt; */&lt;/P&gt; &lt;P id=znuj3&gt;#include &amp;lt;linux/config.h&amp;gt;&lt;BR id=znuj4&gt;#include &amp;lt;linux/module.h&amp;gt;&lt;BR id=znuj5&gt;#include &amp;lt;linux/moduleparam.h&amp;gt;&lt;BR id=znuj6&gt;#include &amp;lt;linux/init.h&amp;gt;&lt;/P&gt; &lt;P id=znuj7&gt;#include &amp;lt;linux/sched.h&amp;gt;&lt;BR id=znuj8&gt;#include &amp;lt;linux/kernel.h&amp;gt; /* printk() */&lt;BR id=znuj9&gt;#include &amp;lt;linux/slab.h&amp;gt;  /* kmalloc() */&lt;BR id=znuj10&gt;#include &amp;lt;linux/fs.h&amp;gt;  /* everything... */&lt;BR id=znuj11&gt;#include &amp;lt;linux/errno.h&amp;gt; /* error codes */&lt;BR id=znuj12&gt;#include &amp;lt;linux/timer.h&amp;gt;&lt;BR id=znuj13&gt;#include &amp;lt;linux/types.h&amp;gt; /* size_t */&lt;BR id=znuj14&gt;#include &amp;lt;linux/fcntl.h&amp;gt; /* O_ACCMODE */&lt;BR id=znuj15&gt;#include &amp;lt;linux/hdreg.h&amp;gt; /* HDIO_GETGEO */&lt;BR id=znuj16&gt;#include &amp;lt;linux/kdev_t.h&amp;gt;&lt;BR id=znuj17&gt;#include &amp;lt;linux/vmalloc.h&amp;gt;&lt;BR id=znuj18&gt;#include &amp;lt;linux/genhd.h&amp;gt;&lt;BR id=znuj19&gt;#include &amp;lt;linux/blkdev.h&amp;gt;&lt;BR id=znuj20&gt;#include &amp;lt;linux/buffer_head.h&amp;gt; /* invalidate_bdev */&lt;BR id=znuj21&gt;#include &amp;lt;linux/bio.h&amp;gt;&lt;/P&gt; &lt;P id=znuj22&gt;&lt;B id=eb670&gt;&lt;FONT id=eb671 color=#0000ff&gt;MODULE_LICENSE&lt;/FONT&gt;&lt;/B&gt;(&quot;Dual BSD/GPL&quot;);&lt;/P&gt; &lt;P id=znuj23&gt;static int sbull_major = 0;&lt;BR id=znuj24&gt;&lt;B id=eb672&gt;&lt;FONT id=eb673 color=#0000ff&gt;module_param&lt;/FONT&gt;&lt;/B&gt;(sbull_major, int, 0);&lt;BR id=znuj25&gt;static int hardsect_size = 512;&lt;BR id=znuj26&gt;&lt;B id=eb674&gt;&lt;FONT id=eb675 color=#0000ff&gt;module_param&lt;/FONT&gt;&lt;/B&gt;(hardsect_size, int, 0);&lt;BR id=znuj27&gt;static int nsectors = 1024; /* How big the drive is */&lt;BR id=znuj28&gt;&lt;B id=eb676&gt;&lt;FONT id=eb677 color=#0000ff&gt;module_param&lt;/FONT&gt;&lt;/B&gt;(nsectors, int, 0);&lt;BR id=znuj29&gt;static int ndevices = 4;&lt;BR id=znuj30&gt;&lt;B id=eb678&gt;&lt;FONT id=eb679 color=#0000ff&gt;module_param&lt;/FONT&gt;&lt;/B&gt;(ndevices, int, 0);&lt;/P&gt; &lt;P id=znuj31&gt;/*&lt;BR id=znuj32&gt; * The different &quot;request modes&quot; we can use.&lt;BR id=znuj33&gt; */&lt;BR id=znuj34&gt;enum {&lt;BR id=znuj35&gt; RM_SIMPLE  = 0, /* The extra-simple request function */&lt;BR id=znuj36&gt; RM_FULL    = 1, /* The full-blown version */&lt;BR id=znuj37&gt; RM_NOQUEUE = 2, /* Use make_request */&lt;BR id=znuj38&gt;};&lt;BR id=znuj39&gt;static int request_mode = RM_SIMPLE;&lt;BR id=znuj40&gt;&lt;B id=hrk70&gt;&lt;FONT id=hrk71 color=#0000ff&gt;module_param&lt;/FONT&gt;&lt;/B&gt;(request_mode, int, 0);&lt;/P&gt; &lt;P id=znuj41&gt;/*&lt;BR id=znuj42&gt; * Minor number and partition management.&lt;BR id=znuj43&gt; */&lt;BR id=znuj44&gt;#define SBULL_MINORS 16&lt;BR id=znuj45&gt;#define MINOR_SHIFT 4&lt;BR id=znuj46&gt;#define DEVNUM(kdevnum) (MINOR(kdev_t_to_nr(kdevnum)) &amp;gt;&amp;gt; MINOR_SHIFT&lt;/P&gt; &lt;P id=znuj47&gt;/*&lt;BR id=znuj48&gt; * We can tweak our hardware sector size, but the kernel talks to us&lt;BR id=znuj49&gt; * in terms of small sectors, always.&lt;BR id=znuj50&gt; */&lt;BR id=znuj51&gt;#define KERNEL_SECTOR_SIZE 512&lt;/P&gt; &lt;P id=znuj52&gt;/*&lt;BR id=znuj53&gt; * After this much idle time, the driver will simulate a media change.&lt;BR id=znuj54&gt; */&lt;BR id=znuj55&gt;#define INVALIDATE_DELAY 30*HZ&lt;/P&gt; &lt;P id=znuj56&gt;/*&lt;BR id=znuj57&gt; * The internal representation of our device.&lt;BR id=znuj58&gt; */&lt;BR id=znuj59&gt;struct sbull_dev {&lt;BR id=znuj60&gt;        int size;                       /* Device size in sectors */&lt;BR id=znuj61&gt;        u8 *data;                       /* The data array */&lt;BR id=znuj62&gt;        short users;                    /* How many users */&lt;BR id=znuj63&gt;        short media_change;             /* Flag a media change? */&lt;BR id=znuj64&gt;        spinlock_t lock;                /* For mutual exclusion */&lt;BR id=znuj65&gt;        struct request_queue *queue;    /* The device request queue */&lt;BR id=znuj66&gt;        struct gendisk *gd;             /* The gendisk structure */&lt;BR id=znuj67&gt;        struct timer_list timer;        /* For simulated media changes */&lt;BR id=znuj68&gt;};&lt;/P&gt; &lt;P id=znuj69&gt;static struct sbull_dev *Devices = NULL;&lt;/P&gt; &lt;P id=znuj70&gt;/*&lt;BR id=znuj71&gt; * Handle an I/O request.&lt;BR id=znuj72&gt; */&lt;BR id=znuj73&gt;static void sbull_transfer(struct sbull_dev *dev, unsigned long sector,&lt;BR id=znuj74&gt;  unsigned long nsect, char *buffer, int write)&lt;BR id=znuj75&gt;{&lt;BR id=znuj76&gt; unsigned long offset = sector*KERNEL_SECTOR_SIZE;&lt;BR id=znuj77&gt; unsigned long nbytes = nsect*KERNEL_SECTOR_SIZE;&lt;/P&gt; &lt;P id=znuj78&gt; if ((offset + nbytes) &amp;gt; dev-&amp;gt;size) {&lt;BR id=znuj79&gt;  printk (KERN_NOTICE &quot;Beyond-end write (%ld %ld)n&quot;, offset, nbytes);&lt;BR id=znuj80&gt;  return;&lt;BR id=znuj81&gt; }&lt;BR id=znuj82&gt; if (write)&lt;BR id=znuj83&gt;  &lt;B id=n:lr0&gt;&lt;FONT id=o9b70 color=#0000ff&gt;memcpy&lt;/FONT&gt;&lt;/B&gt;(dev-&amp;gt;data + offset, buffer, nbytes);&lt;BR id=znuj84&gt; else&lt;BR id=znuj85&gt;  &lt;B id=o9b71&gt;&lt;FONT id=o9b72 color=#0000ff&gt;memcpy&lt;/FONT&gt;&lt;/B&gt;(buffer, dev-&amp;gt;data + offset, nbytes);&lt;BR id=znuj86&gt;}&lt;/P&gt; &lt;P id=znuj87&gt;/*&lt;BR id=znuj88&gt; * The simple form of the request function.&lt;BR id=znuj89&gt; */&lt;BR id=znuj90&gt;static void &lt;B id=bo7_0&gt;&lt;FONT id=bo7_1 color=#ff0000&gt;sbull_request&lt;/FONT&gt;&lt;/B&gt;(request_queue_t *q)&lt;BR id=znuj91&gt;{&lt;BR id=znuj92&gt; struct request *req;&lt;/P&gt; &lt;P id=znuj93&gt; while ((req = &lt;B id=bo7_2&gt;&lt;FONT id=bo7_3 color=#0000ff&gt;elv_next_request&lt;/FONT&gt;&lt;/B&gt;(q)) != NULL) {&lt;BR id=znuj94&gt;  struct sbull_dev *dev = req-&amp;gt;rq_disk-&amp;gt;private_data;&lt;BR id=znuj95&gt;  if (! &lt;B id=bo7_4&gt;&lt;FONT id=bo7_5 color=#0000ff&gt;blk_fs_request&lt;/FONT&gt;&lt;/B&gt;(req)) {&lt;BR id=znuj96&gt;   printk (KERN_NOTICE &quot;Skip non-fs requestn&quot;);&lt;BR id=znuj97&gt;   &lt;B id=bo7_6&gt;&lt;FONT id=bo7_7 color=#0000ff&gt;end_request&lt;/FONT&gt;&lt;/B&gt;(req, 0);&lt;BR id=znuj98&gt;   continue;&lt;BR id=znuj99&gt;  }&lt;BR id=znuj100&gt;    //     printk (KERN_NOTICE &quot;Req dev %d dir %ld sec %ld, nr %d f %lxn&quot;,&lt;BR id=znuj101&gt;    //       dev - Devices, rq_data_dir(req),&lt;BR id=znuj102&gt;    //       req-&amp;gt;sector, req-&amp;gt;current_nr_sectors,&lt;BR id=znuj103&gt;    //       req-&amp;gt;flags);&lt;BR id=znuj104&gt;  sbull_transfer(dev, req-&amp;gt;sector, req-&amp;gt;current_nr_sectors,&lt;BR id=znuj105&gt;    req-&amp;gt;buffer, rq_data_dir(req));&lt;BR id=znuj106&gt;  &lt;B id=bo7_8&gt;&lt;FONT id=bo7_9 color=#0000ff&gt;end_request&lt;/FONT&gt;&lt;/B&gt;(req, 1);&lt;BR id=znuj107&gt; }&lt;BR id=znuj108&gt;}&lt;/P&gt; &lt;P id=znuj109&gt;&lt;BR id=znuj110&gt;/*&lt;BR id=znuj111&gt; * Transfer a single BIO.&lt;BR id=znuj112&gt; */&lt;BR id=znuj113&gt;static int sbull_xfer_bio(struct sbull_dev *dev, struct bio *bio)&lt;BR id=znuj114&gt;{&lt;BR id=znuj115&gt; int i;&lt;BR id=znuj116&gt; struct bio_vec *bvec;&lt;BR id=znuj117&gt; sector_t sector = bio-&amp;gt;bi_sector;&lt;/P&gt; &lt;P id=znuj118&gt; /* Do each segment independently. */&lt;BR id=znuj119&gt; bio_for_each_segment(bvec, bio, i) {&lt;BR id=znuj120&gt;  char *buffer = __bio_kmap_atomic(bio, i, KM_USER0);&lt;BR id=znuj121&gt;  sbull_transfer(dev, sector, bio_cur_sectors(bio),&lt;BR id=znuj122&gt;    buffer, bio_data_dir(bio) == WRITE);&lt;BR id=znuj123&gt;  sector += bio_cur_sectors(bio);&lt;BR id=znuj124&gt;  __bio_kunmap_atomic(bio, KM_USER0);&lt;BR id=znuj125&gt; }&lt;BR id=znuj126&gt; return 0; /* Always &quot;succeed&quot; */&lt;BR id=znuj127&gt;}&lt;/P&gt; &lt;P id=znuj128&gt;/*&lt;BR id=znuj129&gt; * Transfer a full request.&lt;BR id=znuj130&gt; */&lt;BR id=znuj131&gt;static int sbull_xfer_request(struct sbull_dev *dev, struct request *req)&lt;BR id=znuj132&gt;{&lt;BR id=znuj133&gt; struct bio *bio;&lt;BR id=znuj134&gt; int nsect = 0;&lt;BR id=znuj135&gt;    &lt;BR id=znuj136&gt; rq_for_each_bio(bio, req) {&lt;BR id=znuj137&gt;  sbull_xfer_bio(dev, bio);&lt;BR id=znuj138&gt;  nsect += bio-&amp;gt;bi_size/KERNEL_SECTOR_SIZE;&lt;BR id=znuj139&gt; }&lt;BR id=znuj140&gt; return nsect;&lt;BR id=znuj141&gt;}&lt;/P&gt; &lt;P id=znuj142&gt; &lt;/P&gt; &lt;P id=znuj143&gt;/*&lt;BR id=znuj144&gt; * Smarter request function that &quot;handles clustering&quot;.&lt;BR id=znuj145&gt; */&lt;BR id=znuj146&gt;static void sbull_full_request(request_queue_t *q)&lt;BR id=znuj147&gt;{&lt;BR id=znuj148&gt; struct request *req;&lt;BR id=znuj149&gt; int sectors_xferred;&lt;BR id=znuj150&gt; struct sbull_dev *dev = q-&amp;gt;queuedata;&lt;/P&gt; &lt;P id=znuj151&gt; while ((req = elv_next_request(q)) != NULL) {&lt;BR id=znuj152&gt;  if (! &lt;B id=p3j.0&gt;&lt;FONT id=p3j.1 color=#0000ff&gt;blk_fs_request&lt;/FONT&gt;&lt;/B&gt;(req)) {&lt;BR id=znuj153&gt;   printk (KERN_NOTICE &quot;Skip non-fs requestn&quot;);&lt;BR id=znuj154&gt;   &lt;B id=bo7_10&gt;&lt;FONT id=bo7_11 color=#0000ff&gt;end_request&lt;/FONT&gt;&lt;/B&gt;(req, 0);&lt;BR id=znuj155&gt;   continue;&lt;BR id=znuj156&gt;  }&lt;BR id=znuj157&gt;  sectors_xferred = sbull_xfer_request(dev, req);&lt;BR id=znuj158&gt;  if (! end_that_request_first(req, 1, sectors_xferred)) {&lt;BR id=znuj159&gt;   &lt;B id=p3j.2&gt;&lt;FONT id=p3j.3 color=#0000ff&gt;blkdev_dequeue_request&lt;/FONT&gt;&lt;/B&gt;(req);&lt;BR id=znuj160&gt;   &lt;B id=p3j.4&gt;&lt;FONT id=p3j.5 color=#0000ff&gt;end_that_request_last&lt;/FONT&gt;&lt;/B&gt;(req);&lt;BR id=znuj161&gt;  }&lt;BR id=znuj162&gt; }&lt;BR id=znuj163&gt;}&lt;/P&gt; &lt;P id=znuj164&gt; &lt;/P&gt; &lt;P id=znuj165&gt;/*&lt;BR id=znuj166&gt; * The direct make request version.&lt;BR id=znuj167&gt; */&lt;BR id=znuj168&gt;static int sbull_make_request(request_queue_t *q, struct bio *bio)&lt;BR id=znuj169&gt;{&lt;BR id=znuj170&gt; struct sbull_dev *dev = q-&amp;gt;queuedata;&lt;BR id=znuj171&gt; int status;&lt;/P&gt; &lt;P id=znuj172&gt; status = sbull_xfer_bio(dev, bio);&lt;BR id=znuj173&gt; &lt;B id=p3j.6&gt;&lt;FONT id=p3j.7 color=#0000ff&gt;bio_endio&lt;/FONT&gt;&lt;/B&gt;(bio, bio-&amp;gt;bi_size, status);&lt;BR id=znuj174&gt; return 0;&lt;BR id=znuj175&gt;}&lt;/P&gt; &lt;P id=znuj176&gt;&lt;BR id=znuj177&gt;/*&lt;BR id=znuj178&gt; * Open and close.&lt;BR id=znuj179&gt; */&lt;/P&gt; &lt;P id=znuj180&gt;static int sbull_open(struct inode *inode, struct file *filp)&lt;BR id=znuj181&gt;{&lt;BR id=znuj182&gt; struct sbull_dev *dev = inode-&amp;gt;i_bdev-&amp;gt;bd_disk-&amp;gt;private_data;&lt;/P&gt; &lt;P id=znuj183&gt; &lt;B id=d:ef0&gt;&lt;FONT id=d:ef1 color=#0000ff&gt;del_timer_sync&lt;/FONT&gt;&lt;/B&gt;(&amp;amp;dev-&amp;gt;timer);&lt;BR id=znuj184&gt; filp-&amp;gt;private_data = dev;&lt;BR id=znuj185&gt; spin_lock(&amp;amp;dev-&amp;gt;lock);&lt;BR id=znuj186&gt; if (! dev-&amp;gt;users) &lt;BR id=znuj187&gt;  &lt;B id=d:ef2&gt;&lt;FONT id=d:ef3 color=#0000ff&gt;check_disk_change&lt;/FONT&gt;&lt;/B&gt;(inode-&amp;gt;i_bdev);&lt;BR id=znuj188&gt; dev-&amp;gt;users++;&lt;BR id=znuj189&gt; spin_unlock(&amp;amp;dev-&amp;gt;lock);&lt;BR id=znuj190&gt; return 0;&lt;BR id=znuj191&gt;}&lt;/P&gt; &lt;P id=znuj192&gt;static int sbull_release(struct inode *inode, struct file *filp)&lt;BR id=znuj193&gt;{&lt;BR id=znuj194&gt; struct sbull_dev *dev = inode-&amp;gt;i_bdev-&amp;gt;bd_disk-&amp;gt;private_data;&lt;/P&gt; &lt;P id=znuj195&gt; spin_lock(&amp;amp;dev-&amp;gt;lock);&lt;BR id=znuj196&gt; dev-&amp;gt;users--;&lt;/P&gt; &lt;P id=znuj197&gt; if (!dev-&amp;gt;users) {&lt;BR id=znuj198&gt;  dev-&amp;gt;timer.expires = jiffies + INVALIDATE_DELAY;&lt;BR id=znuj199&gt;  &lt;B id=d:ef4&gt;&lt;FONT id=d:ef5 color=#0000ff&gt;add_timer&lt;/FONT&gt;&lt;/B&gt;(&amp;amp;dev-&amp;gt;timer);&lt;BR id=znuj200&gt; }&lt;BR id=znuj201&gt; spin_unlock(&amp;amp;dev-&amp;gt;lock);&lt;/P&gt; &lt;P id=znuj202&gt; return 0;&lt;BR id=znuj203&gt;}&lt;/P&gt; &lt;P id=znuj204&gt;/*&lt;BR id=znuj205&gt; * Look for a (simulated) media change.&lt;BR id=znuj206&gt; */&lt;BR id=znuj207&gt;int &lt;B id=njdw0&gt;&lt;FONT id=njdw1 color=#ff0000&gt;sbull_media_changed&lt;/FONT&gt;&lt;/B&gt;(struct gendisk *gd)&lt;BR id=znuj208&gt;{&lt;BR id=znuj209&gt; struct sbull_dev *dev = gd-&amp;gt;private_data;&lt;BR id=znuj210&gt; &lt;BR id=znuj211&gt; return dev-&amp;gt;media_change;&lt;BR id=znuj212&gt;}&lt;/P&gt; &lt;P id=znuj213&gt;/*&lt;BR id=znuj214&gt; * Revalidate.  WE DO NOT TAKE THE LOCK HERE, for fear of deadlocking&lt;BR id=znuj215&gt; * with open.  That needs to be reevaluated.&lt;BR id=znuj216&gt; */&lt;BR id=znuj217&gt;int &lt;B id=lhy50&gt;&lt;FONT id=lhy51 color=#ff0000&gt;sbull_revalidate&lt;/FONT&gt;&lt;/B&gt;(struct gendisk *gd)&lt;BR id=znuj218&gt;{&lt;BR id=znuj219&gt; struct sbull_dev *dev = gd-&amp;gt;private_data;&lt;BR id=znuj220&gt; &lt;BR id=znuj221&gt; if (dev-&amp;gt;media_change) {&lt;BR id=znuj222&gt;  dev-&amp;gt;media_change = 0;&lt;BR id=znuj223&gt;  memset (dev-&amp;gt;data, 0, dev-&amp;gt;size);&lt;BR id=znuj224&gt; }&lt;BR id=znuj225&gt; return 0;&lt;BR id=znuj226&gt;}&lt;/P&gt; &lt;P id=znuj227&gt;/*&lt;BR id=znuj228&gt; * The &quot;invalidate&quot; function runs out of the device timer; it sets&lt;BR id=znuj229&gt; * a flag to simulate the removal of the media.&lt;BR id=znuj230&gt; */&lt;BR id=znuj231&gt;void &lt;B id=njdw2&gt;&lt;FONT id=njdw3 color=#ff0000&gt;sbull_invalidate&lt;/FONT&gt;&lt;/B&gt;(unsigned long ldev)&lt;BR id=znuj232&gt;{&lt;BR id=znuj233&gt; struct sbull_dev *dev = (struct sbull_dev *) ldev;&lt;/P&gt; &lt;P id=znuj234&gt; spin_lock(&amp;amp;dev-&amp;gt;lock);&lt;BR id=znuj235&gt; if (dev-&amp;gt;users || !dev-&amp;gt;data) &lt;BR id=znuj236&gt;  printk (KERN_WARNING &quot;sbull: timer sanity check failedn&quot;);&lt;BR id=znuj237&gt; else&lt;BR id=znuj238&gt;  &lt;B id=nf490&gt;&lt;FONT id=nf491 color=#ff0000&gt;dev-&amp;gt;media_change = 1;&lt;/FONT&gt;&lt;/B&gt;&lt;BR id=znuj239&gt; spin_unlock(&amp;amp;dev-&amp;gt;lock);&lt;BR id=znuj240&gt;}&lt;/P&gt; &lt;P id=znuj241&gt;/*&lt;BR id=znuj242&gt; * The ioctl() implementation&lt;BR id=znuj243&gt; */&lt;/P&gt; &lt;P id=znuj244&gt;int sbull_ioctl (struct inode *inode, struct file *filp,&lt;BR id=znuj245&gt;                 unsigned int cmd, unsigned long arg)&lt;BR id=znuj246&gt;{&lt;BR id=znuj247&gt; long size;&lt;BR id=znuj248&gt; struct hd_geometry geo;&lt;BR id=znuj249&gt; struct sbull_dev *dev = filp-&amp;gt;private_data;&lt;/P&gt; &lt;P id=znuj250&gt; switch(cmd) {&lt;BR id=znuj251&gt;     case HDIO_GETGEO:&lt;BR id=znuj252&gt;         /*&lt;BR id=znuj253&gt;   * Get geometry: since we are a virtual device, we have to make&lt;BR id=znuj254&gt;   * up something plausible.  So we claim 16 sectors, four heads,&lt;BR id=znuj255&gt;   * and calculate the corresponding number of cylinders.  We set the&lt;BR id=znuj256&gt;   * start of data at sector four.&lt;BR id=znuj257&gt;   */&lt;BR id=znuj258&gt;  size = dev-&amp;gt;size*(hardsect_size/KERNEL_SECTOR_SIZE);&lt;BR id=znuj259&gt;  geo.cylinders = (size &amp;amp; ~0x3f) &amp;gt;&amp;gt; 6;&lt;BR id=znuj260&gt;  geo.heads = 4;&lt;BR id=znuj261&gt;  geo.sectors = 16;&lt;BR id=znuj262&gt;  geo.start = 4;&lt;BR id=znuj263&gt;  if (copy_to_user((void __user *) arg, &amp;amp;geo, sizeof(geo)))&lt;BR id=znuj264&gt;   return -EFAULT;&lt;BR id=znuj265&gt;  return 0;&lt;BR id=znuj266&gt; }&lt;/P&gt; &lt;P id=znuj267&gt; return -ENOTTY; /* unknown command */&lt;BR id=znuj268&gt;}&lt;/P&gt; &lt;P id=znuj269&gt; &lt;/P&gt; &lt;P id=znuj270&gt;/*&lt;BR id=znuj271&gt; * The device operations structure.&lt;BR id=znuj272&gt; */&lt;BR id=znuj273&gt;static struct &lt;B id=m_at0&gt;&lt;FONT id=m_at1 color=#0000ff&gt;block_device_operations&lt;/FONT&gt;&lt;/B&gt; sbull_ops = {&lt;BR id=znuj274&gt; .owner           = THIS_MODULE,&lt;BR id=znuj275&gt; .open           = sbull_open,&lt;BR id=znuj276&gt; .release   = sbull_release,&lt;BR id=znuj277&gt; .media_changed   = &lt;B id=rhni0&gt;&lt;FONT id=rhni1 color=#ff0000&gt;sbull_media_changed&lt;/FONT&gt;&lt;/B&gt;,&lt;BR id=znuj278&gt; .revalidate_disk = &lt;B id=rhni2&gt;&lt;FONT id=rhni3 color=#ff0000&gt;sbull_revalidate&lt;/FONT&gt;&lt;/B&gt;,&lt;BR id=znuj279&gt; .ioctl          = sbull_ioctl&lt;BR id=znuj280&gt;};&lt;/P&gt; &lt;P id=znuj281&gt;&lt;BR id=znuj282&gt;/*&lt;BR id=znuj283&gt; * Set up our internal device.&lt;BR id=znuj284&gt; */&lt;BR id=znuj285&gt;static void setup_device(struct sbull_dev *dev, int which)&lt;BR id=znuj286&gt;{&lt;BR id=znuj287&gt; /*&lt;BR id=znuj288&gt;  * Get some memory.&lt;BR id=znuj289&gt;  */&lt;BR id=znuj290&gt; memset (dev, 0, sizeof (struct sbull_dev));&lt;BR id=znuj291&gt; dev-&amp;gt;size = nsectors*hardsect_size;&lt;BR id=znuj292&gt; dev-&amp;gt;data = &lt;B id=zzia0&gt;&lt;FONT id=zzia1 color=#0000ff&gt;vmalloc&lt;/FONT&gt;&lt;/B&gt;(dev-&amp;gt;size);&lt;BR id=znuj293&gt; if (dev-&amp;gt;data == NULL) {&lt;BR id=znuj294&gt;  printk (KERN_NOTICE &quot;vmalloc failure.n&quot;);&lt;BR id=znuj295&gt;  return;&lt;BR id=znuj296&gt; }&lt;BR id=znuj297&gt; &lt;B id=l_5q0&gt;&lt;FONT id=l_5q1 color=#0000ff&gt;spin_lock_init&lt;/FONT&gt;&lt;/B&gt;(&amp;amp;dev-&amp;gt;lock);&lt;BR id=znuj298&gt; &lt;BR id=znuj299&gt; /*&lt;BR id=znuj300&gt;  * The timer which &quot;invalidates&quot; the device.&lt;BR id=znuj301&gt;  */&lt;BR id=znuj302&gt; &lt;B id=l_5q2&gt;&lt;FONT id=l_5q3 color=#0000ff&gt;init_timer&lt;/FONT&gt;&lt;/B&gt;(&amp;amp;dev-&amp;gt;timer);&lt;BR id=znuj303&gt; dev-&amp;gt;timer.data = (unsigned long) dev;&lt;BR id=znuj304&gt; dev-&amp;gt;timer.function = &lt;B id=hcef0&gt;&lt;FONT id=hcef1 color=#ff0000&gt;sbull_invalidate&lt;/FONT&gt;&lt;/B&gt;;&lt;BR id=znuj305&gt; &lt;BR id=znuj306&gt; /*&lt;BR id=znuj307&gt;  * The I/O queue, depending on whether we are using our own&lt;BR id=znuj308&gt;  * make_request function or not.&lt;BR id=znuj309&gt;  */&lt;BR id=znuj310&gt; switch (request_mode) {&lt;BR id=znuj311&gt;     case RM_NOQUEUE:&lt;BR id=znuj312&gt;  dev-&amp;gt;queue = &lt;B id=zzia2&gt;&lt;FONT id=zzia3 color=#0000ff&gt;blk_alloc_queue&lt;/FONT&gt;&lt;/B&gt;(GFP_KERNEL);&lt;BR id=znuj313&gt;  if (dev-&amp;gt;queue == NULL)&lt;BR id=znuj314&gt;   goto out_vfree;&lt;BR id=znuj315&gt;  &lt;B id=br6e0&gt;&lt;FONT id=evor0 color=#0000ff&gt;blk_queue_make_request&lt;/FONT&gt;&lt;/B&gt;(dev-&amp;gt;queue, sbull_make_request);&lt;BR id=znuj316&gt;  break;&lt;/P&gt; &lt;P id=znuj317&gt;     case RM_FULL:&lt;BR id=znuj318&gt;  dev-&amp;gt;queue = &lt;B id=evor1&gt;&lt;FONT id=evor2 color=#0000ff&gt;blk_init_queue&lt;/FONT&gt;&lt;/B&gt;(&lt;B id=evor3&gt;&lt;FONT id=evor4 color=#ff0000&gt;sbull_full_request&lt;/FONT&gt;&lt;/B&gt;, &amp;amp;dev-&amp;gt;lock);&lt;BR id=znuj319&gt;  if (dev-&amp;gt;queue == NULL)&lt;BR id=znuj320&gt;   goto out_vfree;&lt;BR id=znuj321&gt;  break;&lt;/P&gt; &lt;P id=znuj322&gt;     default:&lt;BR id=znuj323&gt;  printk(KERN_NOTICE &quot;Bad request mode %d, using simplen&quot;, request_mode);&lt;BR id=znuj324&gt;         /* fall into.. */&lt;BR id=znuj325&gt; &lt;BR id=znuj326&gt;     case RM_SIMPLE:&lt;BR id=znuj327&gt;  dev-&amp;gt;queue = &lt;B id=l_5q4&gt;&lt;FONT id=l_5q5 color=#0000ff&gt;blk_init_queue&lt;/FONT&gt;&lt;/B&gt;(sbull_request, &amp;amp;dev-&amp;gt;lock);&lt;BR id=znuj328&gt;  if (dev-&amp;gt;queue == NULL)&lt;BR id=znuj329&gt;   goto out_vfree;&lt;BR id=znuj330&gt;  break;&lt;BR id=znuj331&gt; }&lt;BR id=znuj332&gt; &lt;B id=emfv0&gt;&lt;FONT id=qku10 color=#0000ff&gt;blk_queue_hardsect_size&lt;/FONT&gt;&lt;/B&gt;(dev-&amp;gt;queue, hardsect_size);&lt;BR id=znuj333&gt; dev-&amp;gt;queue-&amp;gt;queuedata = dev;&lt;BR id=znuj334&gt; /*&lt;BR id=znuj335&gt;  * And the gendisk structure.&lt;BR id=znuj336&gt;  */&lt;BR id=znuj337&gt; dev-&amp;gt;gd = &lt;B id=qku11&gt;&lt;FONT id=qku12 color=#0000ff&gt;alloc_disk&lt;/FONT&gt;&lt;/B&gt;(SBULL_MINORS);&lt;BR id=znuj338&gt; if (! dev-&amp;gt;gd) {&lt;BR id=znuj339&gt;  printk (KERN_NOTICE &quot;alloc_disk failuren&quot;);&lt;BR id=znuj340&gt;  goto out_vfree;&lt;BR id=znuj341&gt; }&lt;BR id=znuj342&gt; dev-&amp;gt;gd-&amp;gt;major = sbull_major;&lt;BR id=znuj343&gt; dev-&amp;gt;gd-&amp;gt;first_minor = which*SBULL_MINORS;&lt;BR id=znuj344&gt; dev-&amp;gt;gd-&amp;gt;fops = &amp;amp;sbull_ops;&lt;BR id=znuj345&gt; dev-&amp;gt;gd-&amp;gt;queue = dev-&amp;gt;queue;&lt;BR id=znuj346&gt; dev-&amp;gt;gd-&amp;gt;private_data = dev;&lt;BR id=znuj347&gt; snprintf (dev-&amp;gt;gd-&amp;gt;disk_name, 32, &quot;sbull%c&quot;, which + &#39;a&#39;);&lt;BR id=znuj348&gt; set_capacity(dev-&amp;gt;gd, nsectors*(hardsect_size/KERNEL_SECTOR_SIZE));&lt;BR id=znuj349&gt; &lt;B id=qku13&gt;&lt;FONT id=qku14 color=#0000ff&gt;add_disk&lt;/FONT&gt;&lt;/B&gt;(dev-&amp;gt;gd);&lt;BR id=znuj350&gt; return;&lt;/P&gt; &lt;P id=znuj351&gt;  out_vfree:&lt;BR id=znuj352&gt; if (dev-&amp;gt;data)&lt;BR id=znuj353&gt;  &lt;B id=qku15&gt;&lt;FONT id=qku16 color=#0000ff&gt;vfree&lt;/FONT&gt;&lt;/B&gt;(dev-&amp;gt;data);&lt;BR id=znuj354&gt;}&lt;/P&gt; &lt;P id=znuj355&gt; &lt;/P&gt; &lt;P id=znuj356&gt;static int __init sbull_init(void)&lt;BR id=znuj357&gt;{&lt;BR id=znuj358&gt; int i;&lt;BR id=znuj359&gt; /*&lt;BR id=znuj360&gt;  * Get registered.&lt;BR id=znuj361&gt;  */&lt;BR id=znuj362&gt; sbull_major = &lt;B id=i6320&gt;&lt;FONT id=i6321 color=#0000ff&gt;register_blkdev&lt;/FONT&gt;&lt;/B&gt;(sbull_major, &quot;sbull&quot;);&lt;BR id=znuj363&gt; if (sbull_major &amp;lt;= 0) {&lt;BR id=znuj364&gt;  printk(KERN_WARNING &quot;sbull: unable to get major numbern&quot;);&lt;BR id=znuj365&gt;  return -EBUSY;&lt;BR id=znuj366&gt; }&lt;BR id=znuj367&gt; /*&lt;BR id=znuj368&gt;  * Allocate the device array, and initialize each one.&lt;BR id=znuj369&gt;  */&lt;BR id=znuj370&gt; Devices = &lt;B id=mz3s0&gt;&lt;FONT id=i6322 color=#0000ff&gt;kmalloc&lt;/FONT&gt;&lt;/B&gt;(ndevices*sizeof (struct sbull_dev), GFP_KERNEL);&lt;BR id=znuj371&gt; if (Devices == NULL)&lt;BR id=znuj372&gt;  goto out_unregister;&lt;BR id=znuj373&gt; for (i = 0; i &amp;lt; ndevices; i++) &lt;BR id=znuj374&gt;  &lt;B id=p:o60&gt;&lt;FONT id=p:o61 color=#ff0000&gt;setup_device&lt;/FONT&gt;&lt;/B&gt;(Devices + i, i);&lt;BR id=znuj375&gt;    &lt;BR id=znuj376&gt; return 0;&lt;/P&gt; &lt;P id=znuj377&gt;  out_unregister:&lt;BR id=znuj378&gt; &lt;B id=gs2t0&gt;&lt;FONT id=gs2t1 color=#0000ff&gt;unregister_blkdev&lt;/FONT&gt;&lt;/B&gt;(sbull_major, &quot;sbd&quot;);&lt;BR id=znuj379&gt; return -ENOMEM;&lt;BR id=znuj380&gt;}&lt;/P&gt; &lt;P id=znuj381&gt;static void sbull_exit(void)&lt;BR id=znuj382&gt;{&lt;BR id=znuj383&gt; int i;&lt;/P&gt; &lt;P id=znuj384&gt; for (i = 0; i &amp;lt; ndevices; i++) {&lt;BR id=znuj385&gt;  struct sbull_dev *dev = Devices + i;&lt;/P&gt; &lt;P id=znuj386&gt;  &lt;B id=h_bw0&gt;&lt;FONT id=h_bw1 color=#0000ff&gt;del_timer_sync&lt;/FONT&gt;&lt;/B&gt;(&amp;amp;dev-&amp;gt;timer);&lt;BR id=znuj387&gt;  if (dev-&amp;gt;gd) {&lt;BR id=znuj388&gt;   del_gendisk(dev-&amp;gt;gd);&lt;BR id=znuj389&gt;   put_disk(dev-&amp;gt;gd);&lt;BR id=znuj390&gt;  }&lt;BR id=znuj391&gt;  if (dev-&amp;gt;queue) {&lt;BR id=znuj392&gt;   if (request_mode == RM_NOQUEUE)&lt;BR id=znuj393&gt;    &lt;FONT id=qii-0 color=#0000ff&gt;&lt;B id=h_bw2&gt;blk_put_queue&lt;/B&gt;&lt;/FONT&gt;(dev-&amp;gt;queue);&lt;BR id=znuj394&gt;   else&lt;BR id=znuj395&gt;    &lt;B id=gs2t2&gt;&lt;FONT id=gs2t3 color=#0000ff&gt;blk_cleanup_queue&lt;/FONT&gt;&lt;/B&gt;(dev-&amp;gt;queue);&lt;BR id=znuj396&gt;  }&lt;BR id=znuj397&gt;  if (dev-&amp;gt;data)&lt;BR id=znuj398&gt;   &lt;FONT id=flzh0 color=#0000ff&gt;&lt;B id=gs2t4&gt;vfree&lt;/B&gt;&lt;/FONT&gt;(dev-&amp;gt;data);&lt;BR id=znuj399&gt; }&lt;BR id=znuj400&gt; &lt;B id=h_bw3&gt;&lt;FONT id=h_bw4 color=#0000ff&gt;unregister_blkdev&lt;/FONT&gt;&lt;/B&gt;(sbull_major, &quot;sbull&quot;);&lt;BR id=znuj401&gt; kfree(Devices);&lt;BR id=znuj402&gt;}&lt;BR id=znuj403&gt; &lt;BR id=znuj404&gt;module_init(sbull_init);&lt;BR id=znuj405&gt;module_exit(sbull_exit);&lt;BR id=znuj406&gt;&lt;/P&gt; &lt;P id=ay8t2&gt; &lt;/P&gt;</content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/5386859829667387701/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/5386859829667387701' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/5386859829667387701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/5386859829667387701'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2008/04/dummy-block-driver-for-linux-sample.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-1244842185634682310</id><published>2008-04-26T08:08:00.001+08:00</published><updated>2008-05-12T14:51:43.058+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 驅動程式篇"/><title type='text'></title><content type='html'>&lt;h1 id=&quot;rb9o0&quot;&gt;Dummy USB driver for Linux&lt;/h1&gt;&lt;br id=&quot;rb9o1&quot;&gt;/*&lt;br id=&quot;rb9o2&quot;&gt; * USB Skeleton driver - 2.0&lt;br id=&quot;rb9o3&quot;&gt; *&lt;br id=&quot;rb9o4&quot;&gt; * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)&lt;br id=&quot;rb9o5&quot;&gt; *&lt;br id=&quot;rb9o6&quot;&gt; *    This program is free software; you can redistribute it and/or&lt;br id=&quot;rb9o7&quot;&gt; *    modify it under the terms of the GNU General Public License as&lt;br id=&quot;rb9o8&quot;&gt; *    published by the Free Software Foundation, version 2.&lt;br id=&quot;rb9o9&quot;&gt; *&lt;br id=&quot;rb9o10&quot;&gt; * This driver is based on the 2.6.3 version of drivers/usb/usb-skeleton.c &lt;br id=&quot;rb9o11&quot;&gt; * but has been rewritten to be easy to read and use, as no locks are now&lt;br id=&quot;rb9o12&quot;&gt; * needed anymore.&lt;br id=&quot;rb9o13&quot;&gt; *&lt;br id=&quot;rb9o14&quot;&gt; */&lt;br id=&quot;rb9o15&quot;&gt;&lt;br id=&quot;rb9o16&quot;&gt;#include &amp;lt;linux/config.h&amp;gt;&lt;br id=&quot;rb9o17&quot;&gt;#include &amp;lt;linux/kernel.h&amp;gt;&lt;br id=&quot;rb9o18&quot;&gt;#include &amp;lt;linux/errno.h&amp;gt;&lt;br id=&quot;rb9o19&quot;&gt;#include &amp;lt;linux/init.h&amp;gt;&lt;br id=&quot;rb9o20&quot;&gt;#include &amp;lt;linux/slab.h&amp;gt;&lt;br id=&quot;rb9o21&quot;&gt;#include &amp;lt;linux/module.h&amp;gt;&lt;br id=&quot;rb9o22&quot;&gt;#include &amp;lt;linux/kref.h&amp;gt;&lt;br id=&quot;rb9o23&quot;&gt;#include &amp;lt;linux/smp_lock.h&amp;gt;&lt;br id=&quot;rb9o24&quot;&gt;#include &amp;lt;linux/usb.h&amp;gt;&lt;br id=&quot;rb9o25&quot;&gt;#include &amp;lt;asm/uaccess.h&amp;gt;&lt;br id=&quot;rb9o26&quot;&gt;&lt;br id=&quot;rb9o27&quot;&gt;&lt;br id=&quot;rb9o28&quot;&gt;/* Define these values to match your devices */&lt;br id=&quot;rb9o29&quot;&gt;#define USB_SKEL_VENDOR_ID    0xfff0&lt;br id=&quot;rb9o30&quot;&gt;#define USB_SKEL_PRODUCT_ID    0xfff0&lt;br id=&quot;rb9o31&quot;&gt;&lt;br id=&quot;rb9o32&quot;&gt;/* table of devices that work with this driver */&lt;br id=&quot;rb9o33&quot;&gt;static struct &lt;font id=&quot;dz.v0&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;dz.v1&quot;&gt;&lt;b&gt;usb_device_id&lt;/b&gt;&lt;/span&gt;&lt;/font&gt; skel_table [] = {&lt;br id=&quot;rb9o34&quot;&gt;    { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },&lt;br id=&quot;rb9o35&quot;&gt;    { }                    /* Terminating entry */&lt;br id=&quot;rb9o36&quot;&gt;};&lt;br id=&quot;rb9o37&quot;&gt;&lt;font id=&quot;dz.v2&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;dz.v3&quot;&gt;&lt;b&gt;MODULE_DEVICE_TABLE&lt;/b&gt;&lt;/span&gt;&lt;/font&gt; (usb, skel_table);&lt;br id=&quot;rb9o38&quot;&gt;&lt;br id=&quot;rb9o39&quot;&gt;&lt;br id=&quot;rb9o40&quot;&gt;/* Get a minor range for your devices from the usb maintainer */&lt;br id=&quot;rb9o41&quot;&gt;#define USB_SKEL_MINOR_BASE    192&lt;br id=&quot;rb9o42&quot;&gt;&lt;br id=&quot;rb9o43&quot;&gt;/* Structure to hold all of our device specific stuff */&lt;br id=&quot;rb9o44&quot;&gt;struct usb_skel {&lt;br id=&quot;rb9o45&quot;&gt;    struct &lt;font id=&quot;x2ji0&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;x2ji1&quot;&gt;&lt;b&gt;usb_device&lt;/b&gt;&lt;/span&gt;&lt;/font&gt; *    udev;            /* the usb device for this device */&lt;br id=&quot;rb9o46&quot;&gt;    struct &lt;font id=&quot;od0m0&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;x2ji2&quot;&gt;&lt;b&gt;usb_interface&lt;/b&gt;&lt;/span&gt; &lt;/font&gt;*    interface;        /* the interface for this device */&lt;br id=&quot;rb9o47&quot;&gt;    unsigned char *        bulk_in_buffer;        /* the buffer to receive data */&lt;br id=&quot;rb9o48&quot;&gt;    size_t            bulk_in_size;        /* the size of the receive buffer */&lt;br id=&quot;rb9o49&quot;&gt;    __u8            bulk_in_endpointAddr;    /* the address of the bulk in endpoint */&lt;br id=&quot;rb9o50&quot;&gt;    __u8            bulk_out_endpointAddr;    /* the address of the bulk out endpoint */&lt;br id=&quot;rb9o51&quot;&gt;    struct kref        kref;&lt;br id=&quot;rb9o52&quot;&gt;};&lt;br id=&quot;rb9o53&quot;&gt;#define to_skel_dev(d) &lt;font id=&quot;oab00&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;oab01&quot;&gt;&lt;b&gt;container_of&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(d, struct usb_skel, kref)&lt;br id=&quot;rb9o54&quot;&gt;&lt;br id=&quot;rb9o55&quot;&gt;static struct &lt;font id=&quot;x2ji3&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;x2ji4&quot;&gt;&lt;b&gt;usb_driver&lt;/b&gt;&lt;/span&gt;&lt;/font&gt; skel_driver;&lt;br id=&quot;rb9o56&quot;&gt;&lt;br id=&quot;rb9o57&quot;&gt;static void skel_delete(struct kref *kref)&lt;br id=&quot;rb9o58&quot;&gt;{    &lt;br id=&quot;rb9o59&quot;&gt;    struct usb_skel *dev = to_skel_dev(kref);&lt;br id=&quot;rb9o60&quot;&gt;&lt;br id=&quot;rb9o61&quot;&gt;    &lt;font id=&quot;a:1t0&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;a:1t1&quot;&gt;&lt;b&gt;usb_put_dev&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(dev-&amp;gt;udev);&lt;br id=&quot;rb9o62&quot;&gt;    kfree (dev-&amp;gt;bulk_in_buffer);&lt;br id=&quot;rb9o63&quot;&gt;    kfree (dev);&lt;br id=&quot;rb9o64&quot;&gt;}&lt;br id=&quot;rb9o65&quot;&gt;&lt;br id=&quot;rb9o66&quot;&gt;static int skel_open(struct inode *inode, struct file *file)&lt;br id=&quot;rb9o67&quot;&gt;{&lt;br id=&quot;rb9o68&quot;&gt;    struct usb_skel *dev;&lt;br id=&quot;rb9o69&quot;&gt;    struct usb_interface *interface;&lt;br id=&quot;rb9o70&quot;&gt;    int subminor;&lt;br id=&quot;rb9o71&quot;&gt;    int retval = 0;&lt;br id=&quot;rb9o72&quot;&gt;&lt;br id=&quot;rb9o73&quot;&gt;    subminor = iminor(inode);&lt;br id=&quot;rb9o74&quot;&gt;&lt;br id=&quot;rb9o75&quot;&gt;    interface = &lt;font id=&quot;tcv:0&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;tcv:1&quot;&gt;&lt;b&gt;usb_find_interface&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(&amp;amp;skel_driver, subminor);&lt;br id=&quot;rb9o76&quot;&gt;    if (!interface) {&lt;br id=&quot;rb9o77&quot;&gt;        err (&quot;%s - error, can&#39;t find device for minor %d&quot;,&lt;br id=&quot;rb9o78&quot;&gt;             __FUNCTION__, subminor);&lt;br id=&quot;rb9o79&quot;&gt;        retval = -ENODEV;&lt;br id=&quot;rb9o80&quot;&gt;        goto exit;&lt;br id=&quot;rb9o81&quot;&gt;    }&lt;br id=&quot;rb9o82&quot;&gt;&lt;br id=&quot;rb9o83&quot;&gt;    dev = &lt;font id=&quot;tcv:2&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;tcv:3&quot;&gt;&lt;b&gt;usb_get_intfdata&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(interface);&lt;br id=&quot;rb9o84&quot;&gt;    if (!dev) {&lt;br id=&quot;rb9o85&quot;&gt;        retval = -ENODEV;&lt;br id=&quot;rb9o86&quot;&gt;        goto exit;&lt;br id=&quot;rb9o87&quot;&gt;    }&lt;br id=&quot;rb9o88&quot;&gt;    &lt;br id=&quot;rb9o89&quot;&gt;    /* increment our usage count for the device */&lt;br id=&quot;rb9o90&quot;&gt;    &lt;font id=&quot;tcv:4&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;tcv:5&quot;&gt;&lt;b&gt;kref_get&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(&amp;amp;dev-&amp;gt;kref);&lt;br id=&quot;rb9o91&quot;&gt;&lt;br id=&quot;rb9o92&quot;&gt;    /* save our object in the file&#39;s private structure */&lt;br id=&quot;rb9o93&quot;&gt;    file-&amp;gt;private_data = dev;&lt;br id=&quot;rb9o94&quot;&gt;&lt;br id=&quot;rb9o95&quot;&gt;exit:&lt;br id=&quot;rb9o96&quot;&gt;    return retval;&lt;br id=&quot;rb9o97&quot;&gt;}&lt;br id=&quot;rb9o98&quot;&gt;&lt;br id=&quot;rb9o99&quot;&gt;static int skel_release(struct inode *inode, struct file *file)&lt;br id=&quot;rb9o100&quot;&gt;{&lt;br id=&quot;rb9o101&quot;&gt;    struct usb_skel *dev;&lt;br id=&quot;rb9o102&quot;&gt;&lt;br id=&quot;rb9o103&quot;&gt;    dev = (struct usb_skel *)file-&amp;gt;private_data;&lt;br id=&quot;rb9o104&quot;&gt;    if (dev == NULL)&lt;br id=&quot;rb9o105&quot;&gt;        return -ENODEV;&lt;br id=&quot;rb9o106&quot;&gt;&lt;br id=&quot;rb9o107&quot;&gt;    /* decrement the count on our device */&lt;br id=&quot;rb9o108&quot;&gt;    &lt;font id=&quot;tcv:6&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;tcv:7&quot;&gt;&lt;b&gt;kref_put&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(&amp;amp;dev-&amp;gt;kref, skel_delete);&lt;br id=&quot;rb9o109&quot;&gt;    return 0;&lt;br id=&quot;rb9o110&quot;&gt;}&lt;br id=&quot;rb9o111&quot;&gt;&lt;br id=&quot;rb9o112&quot;&gt;static ssize_t skel_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)&lt;br id=&quot;rb9o113&quot;&gt;{&lt;br id=&quot;rb9o114&quot;&gt;    struct usb_skel *dev;&lt;br id=&quot;rb9o115&quot;&gt;    int retval = 0;&lt;br id=&quot;rb9o116&quot;&gt;&lt;br id=&quot;rb9o117&quot;&gt;    dev = (struct usb_skel *)file-&amp;gt;private_data;&lt;br id=&quot;rb9o118&quot;&gt;    &lt;br id=&quot;rb9o119&quot;&gt;    /* do a blocking bulk read to get data from the device */&lt;br id=&quot;rb9o120&quot;&gt;    retval = &lt;font id=&quot;tcv:8&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;tcv:9&quot;&gt;&lt;b&gt;usb_bulk_msg&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(dev-&amp;gt;udev,&lt;br id=&quot;rb9o121&quot;&gt;                  usb_rcvbulkpipe(dev-&amp;gt;udev, dev-&amp;gt;bulk_in_endpointAddr),&lt;br id=&quot;rb9o122&quot;&gt;                  dev-&amp;gt;bulk_in_buffer,&lt;br id=&quot;rb9o123&quot;&gt;                  min(dev-&amp;gt;bulk_in_size, count),&lt;br id=&quot;rb9o124&quot;&gt;                  &amp;amp;count, HZ*10);&lt;br id=&quot;rb9o125&quot;&gt;&lt;br id=&quot;rb9o126&quot;&gt;    /* if the read was successful, copy the data to userspace */&lt;br id=&quot;rb9o127&quot;&gt;    if (!retval) {&lt;br id=&quot;rb9o128&quot;&gt;        if (copy_to_user(buffer, dev-&amp;gt;bulk_in_buffer, count))&lt;br id=&quot;rb9o129&quot;&gt;            retval = -EFAULT;&lt;br id=&quot;rb9o130&quot;&gt;        else&lt;br id=&quot;rb9o131&quot;&gt;            retval = count;&lt;br id=&quot;rb9o132&quot;&gt;    }&lt;br id=&quot;rb9o133&quot;&gt;&lt;br id=&quot;rb9o134&quot;&gt;    return retval;&lt;br id=&quot;rb9o135&quot;&gt;}&lt;br id=&quot;rb9o136&quot;&gt;&lt;br id=&quot;rb9o137&quot;&gt;static void skel_write_bulk_callback(struct urb *urb, struct pt_regs *regs)&lt;br id=&quot;rb9o138&quot;&gt;{&lt;br id=&quot;rb9o139&quot;&gt;    /* sync/async unlink faults aren&#39;t errors */&lt;br id=&quot;rb9o140&quot;&gt;    if (urb-&amp;gt;status &amp;amp;&amp;amp; &lt;br id=&quot;rb9o141&quot;&gt;        !(urb-&amp;gt;status == -ENOENT || &lt;br id=&quot;rb9o142&quot;&gt;          urb-&amp;gt;status == -ECONNRESET ||&lt;br id=&quot;rb9o143&quot;&gt;          urb-&amp;gt;status == -ESHUTDOWN)) {&lt;br id=&quot;rb9o144&quot;&gt;        dbg(&quot;%s - nonzero write bulk status received: %d&quot;,&lt;br id=&quot;rb9o145&quot;&gt;            __FUNCTION__, urb-&amp;gt;status);&lt;br id=&quot;rb9o146&quot;&gt;    }&lt;br id=&quot;rb9o147&quot;&gt;&lt;br id=&quot;rb9o148&quot;&gt;    /* free up our allocated buffer */&lt;br id=&quot;rb9o149&quot;&gt;    &lt;font id=&quot;as.k0&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;as.k1&quot;&gt;&lt;b&gt;usb_buffer_free&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(urb-&amp;gt;dev, urb-&amp;gt;transfer_buffer_length, &lt;br id=&quot;rb9o150&quot;&gt;            urb-&amp;gt;transfer_buffer, urb-&amp;gt;transfer_dma);&lt;br id=&quot;rb9o151&quot;&gt;}&lt;br id=&quot;rb9o152&quot;&gt;&lt;br id=&quot;rb9o153&quot;&gt;static ssize_t skel_write(struct file *file, const char __user *user_buffer, size_t count, loff_t *ppos)&lt;br id=&quot;rb9o154&quot;&gt;{&lt;br id=&quot;rb9o155&quot;&gt;    struct usb_skel *dev;&lt;br id=&quot;rb9o156&quot;&gt;    int retval = 0;&lt;br id=&quot;rb9o157&quot;&gt;    struct urb *urb = NULL;&lt;br id=&quot;rb9o158&quot;&gt;    char *buf = NULL;&lt;br id=&quot;rb9o159&quot;&gt;&lt;br id=&quot;rb9o160&quot;&gt;    dev = (struct usb_skel *)file-&amp;gt;private_data;&lt;br id=&quot;rb9o161&quot;&gt;&lt;br id=&quot;rb9o162&quot;&gt;    /* verify that we actually have some data to write */&lt;br id=&quot;rb9o163&quot;&gt;    if (count == 0)&lt;br id=&quot;rb9o164&quot;&gt;        goto exit;&lt;br id=&quot;rb9o165&quot;&gt;&lt;br id=&quot;rb9o166&quot;&gt;    /* create a urb, and a buffer for it, and copy the data to the urb */&lt;br id=&quot;rb9o167&quot;&gt;    urb = &lt;font id=&quot;kgmd0&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;kgmd1&quot;&gt;&lt;b&gt;usb_alloc_urb&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(0, GFP_KERNEL);&lt;br id=&quot;rb9o168&quot;&gt;    if (!urb) {&lt;br id=&quot;rb9o169&quot;&gt;        retval = -ENOMEM;&lt;br id=&quot;rb9o170&quot;&gt;        goto error;&lt;br id=&quot;rb9o171&quot;&gt;    }&lt;br id=&quot;rb9o172&quot;&gt;&lt;br id=&quot;rb9o173&quot;&gt;    buf = &lt;font id=&quot;kgmd2&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;kgmd3&quot;&gt;&lt;b&gt;usb_buffer_alloc&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(dev-&amp;gt;udev, count, GFP_KERNEL, &amp;amp;urb-&amp;gt;transfer_dma);&lt;br id=&quot;rb9o174&quot;&gt;    if (!buf) {&lt;br id=&quot;rb9o175&quot;&gt;        retval = -ENOMEM;&lt;br id=&quot;rb9o176&quot;&gt;        goto error;&lt;br id=&quot;rb9o177&quot;&gt;    }&lt;br id=&quot;rb9o178&quot;&gt;    if (copy_from_user(buf, user_buffer, count)) {&lt;br id=&quot;rb9o179&quot;&gt;        retval = -EFAULT;&lt;br id=&quot;rb9o180&quot;&gt;        goto error;&lt;br id=&quot;rb9o181&quot;&gt;    }&lt;br id=&quot;rb9o182&quot;&gt;&lt;br id=&quot;rb9o183&quot;&gt;    /* initialize the urb properly */&lt;br id=&quot;rb9o184&quot;&gt;    &lt;font id=&quot;kgmd4&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;kgmd5&quot;&gt;&lt;b&gt;usb_fill_bulk_urb&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(urb, dev-&amp;gt;udev,&lt;br id=&quot;rb9o185&quot;&gt;              usb_sndbulkpipe(dev-&amp;gt;udev, dev-&amp;gt;bulk_out_endpointAddr),&lt;br id=&quot;rb9o186&quot;&gt;              buf, count, skel_write_bulk_callback, dev);&lt;br id=&quot;rb9o187&quot;&gt;    urb-&amp;gt;transfer_flags |= URB_NO_TRANSFER_DMA_MAP;&lt;br id=&quot;rb9o188&quot;&gt;&lt;br id=&quot;rb9o189&quot;&gt;    /* send the data out the bulk port */&lt;br id=&quot;rb9o190&quot;&gt;    retval = &lt;font id=&quot;l.-g0&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;ubz80&quot; style=&quot; background-color: rgb(255, 255, 255);&quot;&gt;&lt;b&gt;usb_submit_urb&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(urb, GFP_KERNEL);&lt;br id=&quot;rb9o191&quot;&gt;    if (retval) {&lt;br id=&quot;rb9o192&quot;&gt;        err(&quot;%s - failed submitting write urb, error %d&quot;, __FUNCTION__, retval);&lt;br id=&quot;rb9o193&quot;&gt;        goto error;&lt;br id=&quot;rb9o194&quot;&gt;    }&lt;br id=&quot;rb9o195&quot;&gt;&lt;br id=&quot;rb9o196&quot;&gt;    /* release our reference to this urb, the USB core will eventually free it entirely */&lt;br id=&quot;rb9o197&quot;&gt;    &lt;font id=&quot;ubz81&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;ubz82&quot;&gt;&lt;b&gt;usb_free_urb&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(urb);&lt;br id=&quot;rb9o198&quot;&gt;&lt;br id=&quot;rb9o199&quot;&gt;exit:&lt;br id=&quot;rb9o200&quot;&gt;    return count;&lt;br id=&quot;rb9o201&quot;&gt;&lt;br id=&quot;rb9o202&quot;&gt;error:&lt;br id=&quot;rb9o203&quot;&gt;    &lt;font id=&quot;ubz83&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;ubz84&quot;&gt;&lt;b&gt;usb_buffer_free&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(dev-&amp;gt;udev, count, buf, urb-&amp;gt;transfer_dma);&lt;br id=&quot;rb9o204&quot;&gt;    &lt;font id=&quot;ubz85&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;ubz86&quot;&gt;&lt;b&gt;usb_free_urb&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(urb);&lt;br id=&quot;rb9o205&quot;&gt;    kfree(buf);&lt;br id=&quot;rb9o206&quot;&gt;    return retval;&lt;br id=&quot;rb9o207&quot;&gt;}&lt;br id=&quot;rb9o208&quot;&gt;&lt;br id=&quot;rb9o209&quot;&gt;static struct &lt;font id=&quot;s0.j0&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;s0.j1&quot;&gt;&lt;b&gt;file_operations&lt;/b&gt;&lt;/span&gt;&lt;/font&gt; skel_fops = {&lt;br id=&quot;rb9o210&quot;&gt;    .owner =    THIS_MODULE,&lt;br id=&quot;rb9o211&quot;&gt;    .read =        skel_read,&lt;br id=&quot;rb9o212&quot;&gt;    .write =    skel_write,&lt;br id=&quot;rb9o213&quot;&gt;    .open =        skel_open,&lt;br id=&quot;rb9o214&quot;&gt;    .release =    skel_release,&lt;br id=&quot;rb9o215&quot;&gt;};&lt;br id=&quot;rb9o216&quot;&gt;&lt;br id=&quot;rb9o217&quot;&gt;/* &lt;br id=&quot;rb9o218&quot;&gt; * usb class driver info in order to get a minor number from the usb core,&lt;br id=&quot;rb9o219&quot;&gt; * and to have the device registered with devfs and the driver core&lt;br id=&quot;rb9o220&quot;&gt; */&lt;br id=&quot;rb9o221&quot;&gt;static struct &lt;font id=&quot;dos20&quot; color=&quot;#ff0000&quot;&gt;&lt;b&gt;usb_class_driver&lt;/b&gt;&lt;/font&gt; skel_class = {&lt;br id=&quot;rb9o222&quot;&gt;    .name = &quot;usb/skel%d&quot;,&lt;br id=&quot;rb9o223&quot;&gt;    .fops = &amp;amp;skel_fops,&lt;br id=&quot;rb9o224&quot;&gt;    .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH,&lt;br id=&quot;rb9o225&quot;&gt;    .minor_base = USB_SKEL_MINOR_BASE,&lt;br id=&quot;rb9o226&quot;&gt;};&lt;br id=&quot;rb9o227&quot;&gt;&lt;br id=&quot;rb9o228&quot;&gt;static int &lt;font id=&quot;ah4w0&quot; color=&quot;#ff0000&quot;&gt;&lt;span id=&quot;ah4w1&quot;&gt;&lt;b&gt;skel_probe&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(struct usb_interface *interface, const struct usb_device_id *id)&lt;br id=&quot;rb9o229&quot;&gt;{&lt;br id=&quot;rb9o230&quot;&gt;    struct usb_skel *dev = NULL;&lt;br id=&quot;rb9o231&quot;&gt;    struct usb_host_interface *iface_desc;&lt;br id=&quot;rb9o232&quot;&gt;    struct usb_endpoint_descriptor *endpoint;&lt;br id=&quot;rb9o233&quot;&gt;    size_t buffer_size;&lt;br id=&quot;rb9o234&quot;&gt;    int i;&lt;br id=&quot;rb9o235&quot;&gt;    int retval = -ENOMEM;&lt;br id=&quot;rb9o236&quot;&gt;&lt;br id=&quot;rb9o237&quot;&gt;    /* allocate memory for our device state and initialize it */&lt;br id=&quot;rb9o238&quot;&gt;    dev = kmalloc(sizeof(struct usb_skel), GFP_KERNEL);&lt;br id=&quot;rb9o239&quot;&gt;    if (dev == NULL) {&lt;br id=&quot;rb9o240&quot;&gt;        err(&quot;Out of memory&quot;);&lt;br id=&quot;rb9o241&quot;&gt;        goto error;&lt;br id=&quot;rb9o242&quot;&gt;    }&lt;br id=&quot;rb9o243&quot;&gt;    memset(dev, 0x00, sizeof (*dev));&lt;br id=&quot;rb9o244&quot;&gt;    &lt;font id=&quot;ltpg0&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;ltpg1&quot;&gt;&lt;b&gt;kref_init&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(&amp;amp;dev-&amp;gt;kref);&lt;br id=&quot;rb9o245&quot;&gt;&lt;br id=&quot;rb9o246&quot;&gt;    dev-&amp;gt;udev = &lt;font id=&quot;jxju0&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;jxju1&quot;&gt;&lt;b&gt;usb_get_dev&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(interface_to_usbdev(interface));&lt;br id=&quot;rb9o247&quot;&gt;    dev-&amp;gt;interface = interface;&lt;br id=&quot;rb9o248&quot;&gt;&lt;br id=&quot;rb9o249&quot;&gt;    /* set up the endpoint information */&lt;br id=&quot;rb9o250&quot;&gt;    /* use only the first bulk-in and bulk-out endpoints */&lt;br id=&quot;rb9o251&quot;&gt;    iface_desc = interface-&amp;gt;cur_altsetting;&lt;br id=&quot;rb9o252&quot;&gt;    for (i = 0; i &amp;lt; iface_desc-&amp;gt;desc.bNumEndpoints; ++i) {&lt;br id=&quot;rb9o253&quot;&gt;&lt;font id=&quot;ojdu0&quot; color=&quot;#ff0000&quot;&gt;&lt;span id=&quot;ojdu1&quot;&gt;&lt;b&gt;        endpoint = &amp;amp;iface_desc-&amp;gt;endpoint[i].desc;&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;&lt;br id=&quot;rb9o254&quot;&gt;&lt;br id=&quot;rb9o255&quot;&gt;        if (!dev-&amp;gt;bulk_in_endpointAddr &amp;amp;&amp;amp;&lt;br id=&quot;rb9o256&quot;&gt;            (endpoint-&amp;gt;bEndpointAddress &amp;amp; USB_DIR_IN) &amp;amp;&amp;amp;&lt;br id=&quot;rb9o257&quot;&gt;            ((endpoint-&amp;gt;bmAttributes &amp;amp; USB_ENDPOINT_XFERTYPE_MASK)&lt;br id=&quot;rb9o258&quot;&gt;                    == USB_ENDPOINT_XFER_BULK)) {&lt;br id=&quot;rb9o259&quot;&gt;            /* we found a bulk in endpoint */&lt;br id=&quot;rb9o260&quot;&gt;            buffer_size = endpoint-&amp;gt;wMaxPacketSize;&lt;br id=&quot;rb9o261&quot;&gt;&lt;font id=&quot;ojdu2&quot; color=&quot;#ff0000&quot;&gt;&lt;span id=&quot;ojdu3&quot;&gt;&lt;b&gt;            dev-&amp;gt;bulk_in_size = buffer_size;&lt;/b&gt;&lt;/span&gt;&lt;br style=&quot;font-weight: bold;&quot; id=&quot;rb9o262&quot;&gt;&lt;span id=&quot;ojdu4&quot;&gt;&lt;b&gt;            dev-&amp;gt;bulk_in_endpointAddr = endpoint-&amp;gt;bEndpointAddress;&lt;/b&gt;&lt;/span&gt;&lt;br style=&quot;font-weight: bold;&quot; id=&quot;rb9o263&quot;&gt;&lt;span id=&quot;ojdu5&quot;&gt;&lt;b&gt;            dev-&amp;gt;bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;&lt;br id=&quot;rb9o264&quot;&gt;            if (!dev-&amp;gt;bulk_in_buffer) {&lt;br id=&quot;rb9o265&quot;&gt;                err(&quot;Could not allocate bulk_in_buffer&quot;);&lt;br id=&quot;rb9o266&quot;&gt;                goto error;&lt;br id=&quot;rb9o267&quot;&gt;            }&lt;br id=&quot;rb9o268&quot;&gt;        }&lt;br id=&quot;rb9o269&quot;&gt;&lt;br id=&quot;rb9o270&quot;&gt;        if (!dev-&amp;gt;bulk_out_endpointAddr &amp;amp;&amp;amp;&lt;br id=&quot;rb9o271&quot;&gt;            !(endpoint-&amp;gt;bEndpointAddress &amp;amp; USB_DIR_IN) &amp;amp;&amp;amp;&lt;br id=&quot;rb9o272&quot;&gt;            ((endpoint-&amp;gt;bmAttributes &amp;amp; USB_ENDPOINT_XFERTYPE_MASK)&lt;br id=&quot;rb9o273&quot;&gt;                    == USB_ENDPOINT_XFER_BULK)) {&lt;br id=&quot;rb9o274&quot;&gt;            /* we found a bulk out endpoint */&lt;br id=&quot;rb9o275&quot;&gt;&lt;font id=&quot;nq5j0&quot; color=&quot;#ff0000&quot;&gt;&lt;span id=&quot;nq5j1&quot;&gt;&lt;b&gt;            dev-&amp;gt;bulk_out_endpointAddr = endpoint-&amp;gt;bEndpointAddress;&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;&lt;br id=&quot;rb9o276&quot;&gt;        }&lt;br id=&quot;rb9o277&quot;&gt;    }&lt;br id=&quot;rb9o278&quot;&gt;    if (!(dev-&amp;gt;bulk_in_endpointAddr &amp;amp;&amp;amp; dev-&amp;gt;bulk_out_endpointAddr)) {&lt;br id=&quot;rb9o279&quot;&gt;        err(&quot;Could not find both bulk-in and bulk-out endpoints&quot;);&lt;br id=&quot;rb9o280&quot;&gt;        goto error;&lt;br id=&quot;rb9o281&quot;&gt;    }&lt;br id=&quot;rb9o282&quot;&gt;&lt;br id=&quot;rb9o283&quot;&gt;    /* save our data pointer in this interface device */&lt;br id=&quot;rb9o284&quot;&gt;    &lt;font id=&quot;jxju2&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;jxju3&quot;&gt;&lt;b&gt;usb_set_intfdata&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(interface, dev);&lt;br id=&quot;rb9o285&quot;&gt;&lt;br id=&quot;rb9o286&quot;&gt;    /* we can register the device now, as it is ready */&lt;br id=&quot;rb9o287&quot;&gt;    retval = usb_register_dev(interface, &amp;amp;skel_class);&lt;br id=&quot;rb9o288&quot;&gt;    if (retval) {&lt;br id=&quot;rb9o289&quot;&gt;        /* something prevented us from registering this driver */&lt;br id=&quot;rb9o290&quot;&gt;        err(&quot;Not able to get a minor for this device.&quot;);&lt;br id=&quot;rb9o291&quot;&gt;        &lt;font id=&quot;l8ff0&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;l8ff1&quot;&gt;&lt;b&gt;usb_set_intfdata&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(interface, NULL);&lt;br id=&quot;rb9o292&quot;&gt;        goto error;&lt;br id=&quot;rb9o293&quot;&gt;    }&lt;br id=&quot;rb9o294&quot;&gt;&lt;br id=&quot;rb9o295&quot;&gt;    /* let the user know what node this device is now attached to */&lt;br id=&quot;rb9o296&quot;&gt;    info(&quot;USB Skeleton device now attached to USBSkel-%d&quot;, interface-&amp;gt;minor);&lt;br id=&quot;rb9o297&quot;&gt;    return 0;&lt;br id=&quot;rb9o298&quot;&gt;&lt;br id=&quot;rb9o299&quot;&gt;error:&lt;br id=&quot;rb9o300&quot;&gt;    if (dev)&lt;br id=&quot;rb9o301&quot;&gt;        &lt;font id=&quot;l8ff2&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;l8ff3&quot;&gt;&lt;b&gt;kref_put&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(&amp;amp;dev-&amp;gt;kref, skel_delete);&lt;br id=&quot;rb9o302&quot;&gt;    return retval;&lt;br id=&quot;rb9o303&quot;&gt;}&lt;br id=&quot;rb9o304&quot;&gt;&lt;br id=&quot;rb9o305&quot;&gt;static void &lt;font id=&quot;o_g90&quot; color=&quot;#ff0000&quot;&gt;&lt;span id=&quot;o_g91&quot;&gt;&lt;b&gt;skel_disconnect&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(struct usb_interface *interface)&lt;br id=&quot;rb9o306&quot;&gt;{&lt;br id=&quot;rb9o307&quot;&gt;    struct usb_skel *dev;&lt;br id=&quot;rb9o308&quot;&gt;    int minor = interface-&amp;gt;minor;&lt;br id=&quot;rb9o309&quot;&gt;&lt;br id=&quot;rb9o310&quot;&gt;    /* prevent skel_open() from racing skel_disconnect() */&lt;br id=&quot;rb9o311&quot;&gt;    &lt;font id=&quot;z6kr0&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;z6kr1&quot;&gt;&lt;b&gt;lock_kernel&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;();&lt;br id=&quot;rb9o312&quot;&gt;&lt;br id=&quot;rb9o313&quot;&gt;    dev = &lt;font id=&quot;z6kr2&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;z6kr3&quot;&gt;&lt;b&gt;usb_get_intfdata&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(interface);&lt;br id=&quot;rb9o314&quot;&gt;    &lt;font id=&quot;z6kr4&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;z6kr5&quot;&gt;&lt;b&gt;usb_set_intfdata&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(interface, NULL);&lt;br id=&quot;rb9o315&quot;&gt;&lt;br id=&quot;rb9o316&quot;&gt;    /* give back our minor */&lt;br id=&quot;rb9o317&quot;&gt;    &lt;font id=&quot;z6kr6&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;z6kr7&quot;&gt;&lt;b&gt;usb_deregister_dev&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(interface, &amp;amp;skel_class);&lt;br id=&quot;rb9o318&quot;&gt;&lt;br id=&quot;rb9o319&quot;&gt;    &lt;font id=&quot;l8ff4&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;o:k90&quot;&gt;&lt;b&gt;unlock_kernel&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;();&lt;br id=&quot;rb9o320&quot;&gt;&lt;br id=&quot;rb9o321&quot;&gt;    /* decrement our usage count */&lt;br id=&quot;rb9o322&quot;&gt;    &lt;font id=&quot;z6kr8&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;qad50&quot;&gt;&lt;b&gt;kref_put&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(&amp;amp;dev-&amp;gt;kref, skel_delete);&lt;br id=&quot;rb9o323&quot;&gt;&lt;br id=&quot;rb9o324&quot;&gt;    info(&quot;USB Skeleton #%d now disconnected&quot;, minor);&lt;br id=&quot;rb9o325&quot;&gt;}&lt;br id=&quot;rb9o326&quot;&gt;&lt;br id=&quot;rb9o327&quot;&gt;static struct &lt;font id=&quot;fvnv0&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;fvnv1&quot;&gt;&lt;b&gt;usb_driver&lt;/b&gt;&lt;/span&gt;&lt;/font&gt; skel_driver = {&lt;br id=&quot;rb9o328&quot;&gt;    .owner = THIS_MODULE,&lt;br id=&quot;rb9o329&quot;&gt;    .name = &quot;skeleton&quot;,&lt;br id=&quot;rb9o330&quot;&gt;    .id_table = skel_table,&lt;br id=&quot;rb9o331&quot;&gt;    .probe = skel_probe,&lt;br id=&quot;rb9o332&quot;&gt;    .disconnect = skel_disconnect,&lt;br id=&quot;rb9o333&quot;&gt;};&lt;br id=&quot;rb9o334&quot;&gt;&lt;br id=&quot;rb9o335&quot;&gt;static int __init usb_skel_init(void)&lt;br id=&quot;rb9o336&quot;&gt;{&lt;br id=&quot;rb9o337&quot;&gt;    int result;&lt;br id=&quot;rb9o338&quot;&gt;&lt;br id=&quot;rb9o339&quot;&gt;    /* register this driver with the USB subsystem */&lt;br id=&quot;rb9o340&quot;&gt;    result = &lt;font id=&quot;fvnv2&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;fvnv3&quot;&gt;&lt;b&gt;usb_register&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(&amp;amp;skel_driver);&lt;br id=&quot;rb9o341&quot;&gt;    if (result)&lt;br id=&quot;rb9o342&quot;&gt;        err(&quot;usb_register failed. Error number %d&quot;, result);&lt;br id=&quot;rb9o343&quot;&gt;&lt;br id=&quot;rb9o344&quot;&gt;    return result;&lt;br id=&quot;rb9o345&quot;&gt;}&lt;br id=&quot;rb9o346&quot;&gt;&lt;br id=&quot;rb9o347&quot;&gt;static void __exit usb_skel_exit(void)&lt;br id=&quot;rb9o348&quot;&gt;{&lt;br id=&quot;rb9o349&quot;&gt;    /* deregister this driver with the USB subsystem */&lt;br id=&quot;rb9o350&quot;&gt;    &lt;font id=&quot;fvnv4&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;fvnv5&quot;&gt;&lt;b&gt;usb_deregister&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(&amp;amp;skel_driver);&lt;br id=&quot;rb9o351&quot;&gt;}&lt;br id=&quot;rb9o352&quot;&gt;&lt;br id=&quot;rb9o353&quot;&gt;module_init (usb_skel_init);&lt;br id=&quot;rb9o354&quot;&gt;module_exit (usb_skel_exit);&lt;br id=&quot;rb9o355&quot;&gt;&lt;br id=&quot;rb9o356&quot;&gt;MODULE_LICENSE(&quot;GPL&quot;);&lt;br id=&quot;rb9o357&quot;&gt; </content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/1244842185634682310/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/1244842185634682310' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/1244842185634682310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/1244842185634682310'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2008/04/dummy-usb-driver-for-linux-usb-skeleton.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-6617343530474473058</id><published>2008-04-26T08:08:00.000+08:00</published><updated>2008-05-12T14:51:43.058+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 驅動程式篇"/><title type='text'></title><content type='html'>      &lt;h1 id=&quot;j03b0&quot;&gt;Dummy PCI driver for Linux&lt;/h1&gt;&lt;br id=&quot;i87c1&quot;&gt;#include &amp;lt;linux/config.h&amp;gt;&lt;br id=&quot;i87c2&quot;&gt;#include &amp;lt;linux/kernel.h&amp;gt;&lt;br id=&quot;i87c3&quot;&gt;#include &amp;lt;linux/module.h&amp;gt;&lt;br id=&quot;i87c4&quot;&gt;#include &amp;lt;linux/pci.h&amp;gt;&lt;br id=&quot;i87c5&quot;&gt;#include &amp;lt;linux/init.h&amp;gt;&lt;br id=&quot;i87c6&quot;&gt;&lt;br id=&quot;i87c7&quot;&gt;&lt;br id=&quot;i87c8&quot;&gt;static struct &lt;font id=&quot;i27-0&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;i27-1&quot;&gt;&lt;b id=&quot;xf5p0&quot;&gt;pci_device_id &lt;/b&gt;&lt;/span&gt;&lt;/font&gt;ids[] = {&lt;br id=&quot;i87c9&quot;&gt;    { &lt;font id=&quot;idny0&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;idny1&quot;&gt;&lt;b id=&quot;xf5p1&quot;&gt;PCI_DEVICE&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3), },&lt;br id=&quot;i87c10&quot;&gt;    { 0, }&lt;br id=&quot;i87c11&quot;&gt;};&lt;br id=&quot;i87c12&quot;&gt;&lt;font id=&quot;i27-2&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;i27-3&quot;&gt;&lt;b id=&quot;xf5p2&quot;&gt;MODULE_DEVICE_TABLE&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(pci, ids);&lt;br id=&quot;i87c13&quot;&gt;&lt;br id=&quot;i87c14&quot;&gt;static unsigned char skel_get_revision(struct pci_dev *dev)&lt;br id=&quot;i87c15&quot;&gt;{&lt;br id=&quot;i87c16&quot;&gt;    u8 revision;&lt;br id=&quot;i87c17&quot;&gt;&lt;br id=&quot;i87c18&quot;&gt;    &lt;font id=&quot;i27-4&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;i27-5&quot;&gt;&lt;b id=&quot;xf5p3&quot;&gt;pci_read_config_byte&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(dev, PCI_REVISION_ID, &amp;amp;revision);&lt;br id=&quot;i87c19&quot;&gt;    return revision;&lt;br id=&quot;i87c20&quot;&gt;}&lt;br id=&quot;i87c21&quot;&gt;&lt;br id=&quot;i87c22&quot;&gt;static int &lt;font id=&quot;da4r0&quot; color=&quot;#ff0000&quot;&gt;&lt;span id=&quot;epn_0&quot;&gt;&lt;b id=&quot;xf5p4&quot;&gt;probe&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(struct pci_dev *dev, const struct pci_device_id *id)&lt;br id=&quot;i87c23&quot;&gt;{&lt;br id=&quot;i87c24&quot;&gt;    /* Do probing type stuff here.  &lt;br id=&quot;i87c25&quot;&gt;     * Like calling request_region();&lt;br id=&quot;i87c26&quot;&gt;     */&lt;br id=&quot;i87c27&quot;&gt;    &lt;font id=&quot;p1o90&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;p1o91&quot;&gt;&lt;b id=&quot;xf5p5&quot;&gt;pci_enable_device&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(dev);&lt;br id=&quot;i87c28&quot;&gt;    &lt;br id=&quot;i87c29&quot;&gt;    if (skel_get_revision(dev) == 0x42)&lt;br id=&quot;i87c30&quot;&gt;        return -ENODEV;&lt;br id=&quot;i87c31&quot;&gt;&lt;br id=&quot;i87c32&quot;&gt;&lt;br id=&quot;i87c33&quot;&gt;    return &lt;font id=&quot;idny2&quot; color=&quot;#ff0000&quot;&gt;&lt;span id=&quot;idny3&quot;&gt;&lt;b id=&quot;xf5p6&quot;&gt;0&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;;&lt;br id=&quot;i87c34&quot;&gt;}&lt;br id=&quot;i87c35&quot;&gt;&lt;br id=&quot;i87c36&quot;&gt;static void &lt;font id=&quot;da4r1&quot; color=&quot;#ff0000&quot;&gt;&lt;b id=&quot;xf5p7&quot;&gt;remove&lt;/b&gt;&lt;/font&gt;(struct pci_dev *dev)&lt;br id=&quot;i87c37&quot;&gt;{&lt;br id=&quot;i87c38&quot;&gt;    /* clean up any allocated resources and stuff here.&lt;br id=&quot;i87c39&quot;&gt;     * like call release_region();&lt;br id=&quot;i87c40&quot;&gt;     */&lt;br id=&quot;i87c41&quot;&gt;}&lt;br id=&quot;i87c42&quot;&gt;&lt;br id=&quot;i87c43&quot;&gt;static struct &lt;font id=&quot;sv3a0&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;sv3a1&quot;&gt;&lt;b&gt;pci_driver&lt;/b&gt;&lt;/span&gt;&lt;/font&gt; pci_driver = {&lt;br id=&quot;i87c44&quot;&gt;    .name = &quot;pci_skel&quot;,&lt;br id=&quot;i87c45&quot;&gt;    .id_table = ids,&lt;br id=&quot;i87c46&quot;&gt;    .probe = probe,&lt;br id=&quot;i87c47&quot;&gt;    .remove = remove,&lt;br id=&quot;i87c48&quot;&gt;};&lt;br id=&quot;i87c49&quot;&gt;&lt;br id=&quot;i87c50&quot;&gt;static int __init pci_skel_init(void)&lt;br id=&quot;i87c51&quot;&gt;{&lt;br id=&quot;i87c52&quot;&gt;    return &lt;font id=&quot;j03b1&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;j03b2&quot;&gt;&lt;b id=&quot;xf5p8&quot;&gt;pci_register_driver&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(&amp;amp;pci_driver);&lt;br id=&quot;i87c53&quot;&gt;}&lt;br id=&quot;i87c54&quot;&gt;&lt;br id=&quot;i87c55&quot;&gt;static void __exit pci_skel_exit(void)&lt;br id=&quot;i87c56&quot;&gt;{&lt;br id=&quot;i87c57&quot;&gt;    &lt;font id=&quot;j03b3&quot; color=&quot;#0000ff&quot;&gt;&lt;span id=&quot;j03b4&quot;&gt;&lt;b id=&quot;xf5p9&quot;&gt;pci_unregister_driver&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;(&amp;amp;pci_driver);&lt;br id=&quot;i87c58&quot;&gt;}&lt;br id=&quot;i87c59&quot;&gt;&lt;br id=&quot;i87c60&quot;&gt;MODULE_LICENSE(&quot;GPL&quot;);&lt;br id=&quot;i87c61&quot;&gt;&lt;br id=&quot;i87c62&quot;&gt;module_init(pci_skel_init);&lt;br id=&quot;i87c63&quot;&gt;module_exit(pci_skel_exit);&lt;br id=&quot;i87c64&quot;&gt; </content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/6617343530474473058/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/6617343530474473058' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/6617343530474473058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/6617343530474473058'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2008/04/dummy-pci-driver-for-linux-include.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-9138550167839649946</id><published>2008-04-19T00:36:00.000+08:00</published><updated>2008-05-12T14:42:57.532+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 參考資料篇"/><title type='text'></title><content type='html'>      &lt;h1 id=&quot;s2hw&quot;&gt;&lt;b id=&quot;uki8&quot;&gt;&lt;span id=&quot;ArticleTitle1_ArticleTitle1_lblTitle&quot;&gt;Linux 2.6 驱动设计快速入门&lt;/span&gt;&lt;/b&gt;&lt;/h1&gt;引用自: &lt;a title=&quot;http://dev.csdn.net/article/67/67489.shtm&quot; href=&quot;http://dev.csdn.net/article/67/67489.shtm&quot; id=&quot;e68s&quot;&gt;http://dev.csdn.net/article/67/67489.shtm&lt;/a&gt; &lt;br id=&quot;ns9q&quot;&gt;&lt;span id=&quot;ArticleContent1_ArticleContent1_lblContent&quot;&gt;&lt;p id=&quot;nqy1&quot; class=&quot;abstract&quot; align=&quot;left&quot;&gt;&lt;br id=&quot;akte&quot;&gt;&lt;/p&gt;&lt;p id=&quot;nqy1&quot; class=&quot;abstract&quot; align=&quot;left&quot;&gt;Linux 2.6 和 2.4 的比较我不想废话，总体来说 2.6 功能更强，但是资源消耗更多。 &lt;/p&gt;&lt;p id=&quot;bfvt&quot; class=&quot;text&quot;&gt;由于 2.6 内核在驱动框架，底层调用上和 2.4 内核有很多差别，所以本文主要是为程序员提供 2.4 到 2.6 迁移的指导。 &lt;/p&gt;&lt;p id=&quot;wbl:&quot; class=&quot;text&quot;&gt;2.6 和 2.4 主要的不同在于 &lt;/p&gt;&lt;p id=&quot;dufq&quot; class=&quot;text&quot;&gt;•  内核的 API 变化，增加了不少新功能（例如 mem pool ） &lt;/p&gt;&lt;p id=&quot;ak99&quot; class=&quot;text&quot;&gt;•  提供 sysfs 用于描述设备树 &lt;/p&gt;&lt;p id=&quot;hcnx&quot; class=&quot;text&quot;&gt;•  驱动模块从 .o 变为 .ko &lt;/p&gt;&lt;h2 id=&quot;edlt&quot;&gt;移植 hello word &lt;/h2&gt;&lt;p id=&quot;s:m8&quot; class=&quot;text&quot;&gt;下面是一个最简单的 2.4 驱动： &lt;/p&gt;&lt;p id=&quot;wrpd&quot; class=&quot;boxsource&quot;&gt;#define MODULE &lt;br id=&quot;g4zq&quot;&gt;#include &amp;lt;linux/module.h&amp;gt; &lt;br id=&quot;bnc:&quot;&gt;#include &amp;lt;linux/kernel.h&amp;gt; &lt;br id=&quot;k-8y&quot;&gt;int init_module(void) &lt;br id=&quot;zuyy&quot;&gt;{ &lt;br id=&quot;z4zv&quot;&gt;printk(KERN_INFO &quot;Hello, worldn&quot;); &lt;br id=&quot;t-sn&quot;&gt;return 0; &lt;br id=&quot;rohg&quot;&gt;} &lt;br id=&quot;w8zj&quot;&gt;void cleanup_module(void) &lt;br id=&quot;b4lr&quot;&gt;{&lt;br id=&quot;fbxu&quot;&gt;printk(KERN_INFO &quot;Goodbye cruel worldn&quot;); &lt;br id=&quot;wkes&quot;&gt;} &lt;/p&gt;&lt;p id=&quot;gfhf&quot; class=&quot;text&quot;&gt;2.6的hello world版本！ &lt;/p&gt;&lt;p id=&quot;i5tg&quot; class=&quot;boxsource&quot;&gt;#include &amp;lt; linux/module.h&amp;gt; &lt;br id=&quot;ajje&quot;&gt;#include &amp;lt; linux/config.h&amp;gt; &lt;br id=&quot;fx8w&quot;&gt;#include &amp;lt; linux/init.h&amp;gt; &lt;br id=&quot;eo9y&quot;&gt;MODULE_LICENSE(&quot;GPL&quot;);// 新，否则有 waring, 去掉了 #define MODULE, 自动定义 &lt;br id=&quot;yma7&quot;&gt;static int hello_init(void) &lt;br id=&quot;d-3r&quot;&gt;{ &lt;br id=&quot;crm9&quot;&gt;printk(KERN_ALERT &quot;Hello, worldn&quot;); &lt;br id=&quot;wqns&quot;&gt;return 0; &lt;br id=&quot;nr0a&quot;&gt;} &lt;br id=&quot;dhpk&quot;&gt;static void hello_exit(void) &lt;br id=&quot;cl42&quot;&gt;{ &lt;br id=&quot;zde:&quot;&gt;printk(KERN_ALERT &quot;Goodbye, cruel worldn&quot;); &lt;br id=&quot;t.yg&quot;&gt;} &lt;br id=&quot;gfdv&quot;&gt;module_init(hello_init);// 必须！！ &lt;br id=&quot;vrwi&quot;&gt;module_exit(hello_exit); // 必须！！ &lt;/p&gt;&lt;p id=&quot;z0nh&quot;&gt;&lt;span id=&quot;c-qb&quot; class=&quot;text&quot;&gt;注意，在 2.4 中 module_init 不是必须的，只要驱动的初始化函数以及析沟函数命名使用了缺省的 init_module 和 cleanup_module&lt;/span&gt; &lt;/p&gt;&lt;h2 id=&quot;hb5:&quot;&gt;编译生成： &lt;/h2&gt;&lt;p id=&quot;owao&quot; class=&quot;text&quot;&gt;&lt;b id=&quot;mzzc&quot;&gt;2.4 &lt;/b&gt;&lt;/p&gt;&lt;p id=&quot;shrc&quot; class=&quot;text&quot;&gt;gcc -D__KERNEL__ -DMODULE -I/usr/src/linux- 2.4.27 /include -O2 -c testmod.c &lt;/p&gt;&lt;p id=&quot;lo3b&quot; class=&quot;text&quot;&gt;&lt;b id=&quot;dlsa&quot;&gt;2.6 &lt;/b&gt;&lt;/p&gt;&lt;p id=&quot;utxa&quot; class=&quot;text&quot;&gt;makefile 中要有 obj-m:= hello.o &lt;/p&gt;&lt;p id=&quot;l3vu&quot; class=&quot;text&quot;&gt;然后： &lt;/p&gt;&lt;p id=&quot;r44c&quot; class=&quot;text&quot;&gt;make -C /usr/src/linux- 2.6.11 SUBDIRS=$PWD modules （当然简单的 make 也可以） &lt;/p&gt;&lt;p id=&quot;pb6e&quot; class=&quot;text&quot;&gt;哈哈够简单！！ &lt;/p&gt;&lt;h2 id=&quot;zjfv&quot;&gt;其他不同： &lt;/h2&gt;&lt;h3 id=&quot;kunw&quot;&gt;计数器： &lt;/h3&gt;&lt;p id=&quot;ekmv&quot; class=&quot;text&quot;&gt;以前 2.4 内核使用 MOD_INC_USE_COUNT 增加计数例如： &lt;/p&gt;&lt;p id=&quot;j5w9&quot; class=&quot;text&quot;&gt;void &lt;/p&gt;&lt;p id=&quot;ue8k&quot; class=&quot;text&quot;&gt;inc_mod(void) &lt;/p&gt;&lt;p id=&quot;wq50&quot; class=&quot;text&quot;&gt;{ &lt;/p&gt;&lt;p id=&quot;smr5&quot; class=&quot;text&quot;&gt;MOD_INC_USE_COUNT; &lt;/p&gt;&lt;p id=&quot;okx.&quot; class=&quot;text&quot;&gt;} /* end inc_mod */ &lt;/p&gt;&lt;p id=&quot;sy75&quot;&gt;  &lt;/p&gt;&lt;p id=&quot;o.2w&quot; class=&quot;text&quot;&gt;/************************************************************************ &lt;/p&gt;&lt;p id=&quot;e30t&quot; class=&quot;text&quot;&gt;* Calculator DEC &lt;/p&gt;&lt;p id=&quot;a4t_&quot; class=&quot;text&quot;&gt;************************************************************************/ &lt;/p&gt;&lt;p id=&quot;y6d:&quot; class=&quot;text&quot;&gt;void &lt;/p&gt;&lt;p id=&quot;rs3.&quot; class=&quot;text&quot;&gt;dec_mod(void) &lt;/p&gt;&lt;p id=&quot;i0mw&quot; class=&quot;text&quot;&gt;{ &lt;/p&gt;&lt;p id=&quot;iw6e&quot; class=&quot;text&quot;&gt;MOD_DEC_USE_COUNT; &lt;/p&gt;&lt;p id=&quot;f45b&quot; class=&quot;text&quot;&gt;} /* end dec_mod */ &lt;/p&gt;&lt;p id=&quot;r6.v&quot; class=&quot;text&quot;&gt;现在这个也过时了 !! &lt;/p&gt;&lt;p id=&quot;w:4e&quot; class=&quot;text&quot;&gt;2.6 ，用户函数要加载模块，使用： &lt;/p&gt;&lt;p id=&quot;p4w0&quot; class=&quot;text&quot;&gt;&lt;span id=&quot;se4l&quot; class=&quot;text&quot;&gt;int try_module_get(&amp;amp;module); &lt;/span&gt;&lt;/p&gt;&lt;p id=&quot;diir&quot; class=&quot;text&quot;&gt;函数卸载模块使用 &lt;/p&gt;&lt;p id=&quot;x:hg&quot; class=&quot;text&quot;&gt;module_put() &lt;/p&gt;&lt;p id=&quot;qqz3&quot; class=&quot;text&quot;&gt;而驱动中不必显示定义 inc 和 dec &lt;/p&gt;&lt;h3 id=&quot;t_5y&quot;&gt;没有 kdev_t 了 &lt;/h3&gt;&lt;p id=&quot;q:05&quot; class=&quot;text&quot;&gt;现在都流行用 dev_t 了 , 而且是 32 位的 &lt;/p&gt;&lt;h3 id=&quot;qrp8&quot;&gt;结构体初始化 &lt;/h3&gt;&lt;p id=&quot;fiff&quot; class=&quot;text&quot;&gt;老版本使用： &lt;/p&gt;&lt;p id=&quot;viun&quot; class=&quot;text&quot;&gt;static struct some_structure = { &lt;/p&gt;&lt;p id=&quot;wk::&quot; class=&quot;text&quot;&gt;field1: value, &lt;/p&gt;&lt;p id=&quot;m7if&quot; class=&quot;text&quot;&gt;field2: value &lt;/p&gt;&lt;p id=&quot;zufg&quot; class=&quot;text&quot;&gt;}; &lt;/p&gt;&lt;p id=&quot;q7.b&quot; class=&quot;text&quot;&gt;现在流行用： &lt;/p&gt;&lt;p id=&quot;uouk&quot; class=&quot;text&quot;&gt;static struct some_structure = { &lt;/p&gt;&lt;p id=&quot;bafn&quot; class=&quot;text&quot;&gt;.field1 = value, &lt;/p&gt;&lt;p id=&quot;ie-g&quot; class=&quot;text&quot;&gt;.field2 = value, &lt;/p&gt;&lt;p id=&quot;esji&quot; class=&quot;text&quot;&gt;... &lt;/p&gt;&lt;p id=&quot;h_1d&quot; class=&quot;text&quot;&gt;}; &lt;/p&gt;&lt;h3 id=&quot;im_7&quot;&gt;malloc.h &lt;/h3&gt;&lt;p id=&quot;e::g&quot; class=&quot;text&quot;&gt;要用核态内存？用 &amp;lt;linux/slab.h&amp;gt; 好了，&lt;/p&gt;&lt;h3 id=&quot;c5di&quot;&gt;内存池&lt;/h3&gt;&lt;p id=&quot;qz8v&quot; class=&quot;text&quot;&gt;内 存管理变化不大，添加了memory pool*(#include&amp;lt;linux/mempool.h&amp;gt; )。（现在什么都是pool，内存 线程 ....）这是为块设备提供的，使用mempool最大的优点是分配内存不会错，也不会等待（怎么这个也和RTEMS学）。对于embed的设备还是有些 用处的。标准调用方式：&lt;/p&gt;&lt;p id=&quot;j7ih&quot; class=&quot;text&quot;&gt;mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn, mempool_free_t *free_fn, void *pool_data); &lt;/p&gt;&lt;p id=&quot;zpfy&quot; class=&quot;text&quot;&gt;使用mempool的函数 ：&lt;/p&gt;&lt;p id=&quot;r-gm&quot; class=&quot;text&quot;&gt;mempool_alloc_t / mempool_free_t &lt;/p&gt;&lt;p id=&quot;d6e7&quot; class=&quot;text&quot;&gt;mempool_alloc_slab / mempool_free_slab &lt;/p&gt;&lt;p id=&quot;bi31&quot; class=&quot;text&quot;&gt;mempool_alloc / mempool_free &lt;/p&gt;&lt;p id=&quot;c0az&quot; class=&quot;text&quot;&gt;mempool_resize &lt;/p&gt;&lt;p id=&quot;g:cn&quot; class=&quot;text&quot;&gt; &lt;/p&gt;&lt;h3 id=&quot;l205&quot;&gt;结构体赋值 &lt;/h3&gt;&lt;p id=&quot;ptj_&quot; class=&quot;text&quot;&gt;以前，驱动中结构体赋值使用： &lt;/p&gt;&lt;p id=&quot;bkoa&quot; class=&quot;text&quot;&gt;static struct some_structure = { &lt;/p&gt;&lt;p id=&quot;j1eu&quot; class=&quot;text&quot;&gt;field1: value, &lt;/p&gt;&lt;p id=&quot;etku&quot; class=&quot;text&quot;&gt;field2: value &lt;/p&gt;&lt;p id=&quot;mut3&quot; class=&quot;text&quot;&gt;}; &lt;/p&gt;&lt;p id=&quot;d:4i&quot;&gt;  &lt;/p&gt;&lt;p id=&quot;kz4g&quot; class=&quot;text&quot;&gt;现在要用： &lt;/p&gt;&lt;p id=&quot;fa3v&quot; class=&quot;text&quot;&gt;static struct some_structure = { &lt;/p&gt;&lt;p id=&quot;slfp&quot; class=&quot;text&quot;&gt;.field1 = value, &lt;/p&gt;&lt;p id=&quot;jyg0&quot; class=&quot;text&quot;&gt;.field2 = value, &lt;/p&gt;&lt;p id=&quot;t4u1&quot; class=&quot;text&quot;&gt;... &lt;/p&gt;&lt;p id=&quot;kvk5&quot; class=&quot;text&quot;&gt;}; &lt;/p&gt;&lt;p id=&quot;i0d9&quot; class=&quot;text&quot;&gt;例如 : &lt;/p&gt;&lt;p id=&quot;jbhw&quot; class=&quot;text&quot;&gt;&lt;span id=&quot;wo3t&quot; class=&quot;text&quot;&gt;static struct file_operations yourdev_file_ops &lt;/span&gt;&lt;span id=&quot;l8.i&quot; class=&quot;text&quot;&gt;= {&lt;/span&gt;&lt;/p&gt;&lt;p id=&quot;be_x&quot; class=&quot;text&quot;&gt;&lt;span id=&quot;c7v1&quot; class=&quot;text&quot;&gt;.open = yourdev_open, &lt;/span&gt;&lt;/p&gt;&lt;p id=&quot;d7o_&quot; class=&quot;text&quot;&gt;&lt;span id=&quot;e9jr&quot; class=&quot;text&quot;&gt;.read = yourdev_read_file, &lt;/span&gt;&lt;/p&gt;&lt;p id=&quot;eal_&quot; class=&quot;text&quot;&gt;&lt;span id=&quot;c4rn&quot; class=&quot;text&quot;&gt;.write = yourdev_write_file, &lt;/span&gt;&lt;/p&gt;&lt;p id=&quot;c.j2&quot; class=&quot;text&quot;&gt;&lt;span id=&quot;d5vk&quot; class=&quot;text&quot;&gt;}; &lt;/span&gt;&lt;/p&gt;&lt;p id=&quot;hg7f&quot;&gt;  &lt;/p&gt;&lt;h3 id=&quot;d240&quot;&gt;min() ， max() &lt;/h3&gt;&lt;p id=&quot;clxj&quot; class=&quot;text&quot;&gt;不少程序员定义自己的 min 和 max 宏，大家也知道宏不安全， Linux 定义了 min 和 max 函数（注意不是模板函数，需要自己制定比较类型！） &lt;/p&gt;&lt;h3 id=&quot;xmo3&quot;&gt;原型变化 &lt;/h3&gt;&lt;p id=&quot;f1ut&quot; class=&quot;text&quot;&gt;call_usermodehelper() &lt;/p&gt;&lt;p id=&quot;kmiv&quot; class=&quot;text&quot;&gt;request_module() &lt;/p&gt;&lt;p id=&quot;m2lf&quot; class=&quot;text&quot;&gt;函数原型变化了，用到的赶快查 !!! &lt;/p&gt;&lt;h3 id=&quot;ir8s&quot;&gt;Devfs &lt;/h3&gt;&lt;p id=&quot;ygga&quot; class=&quot;text&quot;&gt;唉，还没怎么用，就过时了的技术，这就是 linux 。不是我们落伍，是世界变化快 &lt;/p&gt;&lt;p id=&quot;r57j&quot;&gt;  &lt;/p&gt;&lt;h2 id=&quot;mp-u&quot;&gt;字符设备 &lt;/h2&gt;&lt;p id=&quot;l0mf&quot; class=&quot;text&quot;&gt;2.6 中主从设备编号不再局限于原来的 8bit &lt;/p&gt;&lt;p id=&quot;imja&quot; class=&quot;text&quot;&gt;register_chrdev() 可以升级为： &lt;/p&gt;&lt;p id=&quot;e:ra&quot; class=&quot;text&quot;&gt;&lt;span id=&quot;b9li&quot; class=&quot;text&quot;&gt;int register_chrdev_region(dev_t from, // 设备号 unsigned count, // 注册号 char *name); // 名称 &lt;/span&gt;&lt;/p&gt;&lt;p id=&quot;c9-o&quot; class=&quot;text&quot;&gt;该函数的动态版本（不知道主设备号时使用） &lt;/p&gt;&lt;p id=&quot;p8bv&quot; class=&quot;text&quot; align=&quot;left&quot;&gt;int alloc_chrdev_region(dev_t *dev, unsigned baseminor, &lt;/p&gt;&lt;p id=&quot;adk6&quot; class=&quot;text&quot;&gt;unsigned count, char *name); &lt;/p&gt;&lt;p id=&quot;jeiu&quot;&gt;  &lt;/p&gt;&lt;h2 id=&quot;gw9e&quot;&gt;新的 file_operations &lt;/h2&gt;&lt;p id=&quot;vxy4&quot; class=&quot;text&quot;&gt;register_chrdev_region 没有使用 register_chrdev_region 参数，因为设备现在使用 struct cdev 来定义他在 &amp;lt;linux/cdev.h&amp;gt; 中定义。 &lt;/p&gt;&lt;p id=&quot;sopw&quot; class=&quot;text&quot;&gt;struct cdev { &lt;/p&gt;&lt;p id=&quot;hifh&quot; class=&quot;text&quot;&gt;struct kobject kobj; &lt;/p&gt;&lt;p id=&quot;ng9t&quot; class=&quot;text&quot;&gt;struct module *owner; &lt;/p&gt;&lt;p id=&quot;qia9&quot; class=&quot;text&quot;&gt;struct file_operations *ops; &lt;/p&gt;&lt;p id=&quot;w9uo&quot; class=&quot;text&quot;&gt;struct list_head list; &lt;/p&gt;&lt;p id=&quot;cvi1&quot; class=&quot;text&quot;&gt;dev_t dev; &lt;/p&gt;&lt;p id=&quot;z36c&quot; class=&quot;text&quot;&gt;unsigned int count; &lt;/p&gt;&lt;p id=&quot;wc9q&quot; class=&quot;text&quot;&gt;}; &lt;/p&gt;&lt;p id=&quot;jbcf&quot; class=&quot;text&quot;&gt;&lt;span id=&quot;t:g1&quot; class=&quot;text&quot;&gt;使用时首先需要分配空间： struct cdev *cdev_alloc(void); &lt;/span&gt;&lt;/p&gt;&lt;p id=&quot;smd6&quot; class=&quot;text&quot;&gt;然后对其初始化： &lt;/p&gt;&lt;p id=&quot;ulm.&quot; class=&quot;text&quot;&gt;&lt;span id=&quot;lv.3&quot; class=&quot;text&quot;&gt;void cdev_init(struct cdev *cdev, struct file_operations *fops); &lt;/span&gt;&lt;/p&gt;&lt;p id=&quot;lpm8&quot; class=&quot;text&quot;&gt;cdev 使用 kobject_set_name 设置名称：例如： &lt;/p&gt;&lt;p id=&quot;okvo&quot; class=&quot;text&quot;&gt;&lt;span id=&quot;mzot&quot; class=&quot;text&quot;&gt;struct cdev *my_cdev = cdev_alloc(); kobject_set_name(&amp;amp;cdev-&amp;gt;kobj, &quot;my_cdev%d&quot;, devnum); &lt;/span&gt;&lt;/p&gt;&lt;p id=&quot;l6ns&quot; class=&quot;text&quot;&gt;此后就可以使用 int cdev_add(struct cdev *cdev, dev_t dev, unsigned count); 将 cdev 加入到系统中。 &lt;/p&gt;&lt;p id=&quot;weam&quot; class=&quot;text&quot;&gt;删除 cdev 使用 &lt;/p&gt;&lt;p id=&quot;jseh&quot; class=&quot;text&quot;&gt;void cdev_del(struct cdev *cdev); &lt;/p&gt;&lt;p id=&quot;o4ou&quot; class=&quot;text&quot;&gt;&lt;span id=&quot;z_3-&quot; class=&quot;text&quot;&gt;对 于没有使用 cdev_add 添加的 cdev 使用 kobject_put(&amp;amp;cdev-&amp;gt;kobj); 删除 也就是使用： struct kobject *cdev_get(struct cdev *cdev); void cdev_put(struct cdev *cdev);   &lt;/span&gt;&lt;/p&gt;&lt;h3 id=&quot;zfuf&quot;&gt;太极链； &lt;/h3&gt;&lt;p id=&quot;rr.i&quot; class=&quot;text&quot;&gt;struct inode -&amp;gt; i_cdev -&amp;gt; cdev &lt;/p&gt;&lt;p id=&quot;elrj&quot; class=&quot;text&quot;&gt;这样就从 inode 链接到 cdev &lt;/p&gt;&lt;p id=&quot;e6en&quot;&gt;  &lt;/p&gt;&lt;h3 id=&quot;qp9e&quot;&gt;驱动体系： &lt;/h3&gt;&lt;p id=&quot;xtjv&quot; class=&quot;text&quot;&gt;/dev 到 /sys &lt;/p&gt;&lt;p id=&quot;q4_0&quot; class=&quot;text&quot;&gt;/dev 也过时了，设备文件都跑到 /sys 里了！ &lt;/p&gt;&lt;p id=&quot;qndu&quot; class=&quot;text&quot;&gt;# cd /sys &lt;/p&gt;&lt;p id=&quot;xexh&quot; class=&quot;text&quot;&gt;# ls &lt;/p&gt;&lt;p id=&quot;ebec&quot; class=&quot;text&quot;&gt;block bus class devices firmware&lt;/p&gt;&lt;/span&gt;      &lt;br id=&quot;xv19&quot;&gt;</content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/9138550167839649946/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/9138550167839649946' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/9138550167839649946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/9138550167839649946'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2008/04/linux-2.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-2087780112409748947</id><published>2008-04-18T21:28:00.000+08:00</published><updated>2008-05-12T14:51:43.058+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 驅動程式篇"/><title type='text'></title><content type='html'>&lt;h1 id=&quot;p3y3&quot;&gt;Build Kernel Module as KO files&lt;/h1&gt;&lt;br id=&quot;n6-r&quot;&gt;&lt;h3 id=&quot;quzj&quot;&gt;Show build progress in verbose&lt;/h3&gt;make V=1 &lt;br id=&quot;t0n:&quot;&gt;&lt;br id=&quot;u7e9&quot;&gt;&lt;h3 id=&quot;lfe2&quot;&gt;&lt;span id=&quot;had3&quot;&gt;lib path for glibc&lt;/span&gt;&lt;/h3&gt;/opt/microtime/pro/devkit/arm/pxa270/gcc-4.0.2-glibc-2.3.3/arm-unknown-linux-gnu/arm-unknown-linux-gnu/lib&lt;br id=&quot;hm2v&quot;&gt;&lt;h3 id=&quot;yapq&quot;&gt;&lt;span id=&quot;s81n&quot;&gt;bin path of gcc&lt;br id=&quot;gjim&quot;&gt;&lt;/span&gt;&lt;/h3&gt;/opt/microtime/pro/devkit/arm/pxa270/gcc-4.0.2-glibc-2.3.3/arm-unknown-linux-gnu/bin&lt;br id=&quot;tf-i&quot;&gt;&lt;h3 id=&quot;l802&quot;&gt;header file path of Linux Kernel&lt;br id=&quot;qrex&quot;&gt;&lt;/h3&gt;/usr/src/creator/pxa270/linux/include&lt;br id=&quot;t60o&quot;&gt;&lt;h3 id=&quot;j.8s&quot;&gt;&lt;span id=&quot;r6v.&quot;&gt;obj-y&lt;/span&gt;&lt;/h3&gt;cmd_drivers/char/creator-pxa270-lcd.o := arm-unknown-linux-gnu-gcc -Wp,-MD,drivers/char/.creator-pxa270-lcd.o.d  -nostdinc -isystem /opt/microtime/pro/devkit/arm/pxa270/gcc-4.0.2-glibc-2.3.3/arm-unknown-linux-gnu/bin/../lib/gcc/arm-unknown-linux-gnu/4.0.2/include -D__KERNEL__ -Iinclude  -include include/linux/autoconf.h -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -fno-inline -Os     -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -fno-omit-frame-pointer -mapcs -mno-sched-prolog -mabi=apcs-gnu -mno-thumb-interwork -D__LINUX_ARM_ARCH__=5 -march=armv5te -mtune=xscale -Wa,-mcpu=xscale  -msoft-float -Uarm -Wdeclaration-after-statement -Wno-pointer-sign&lt;span id=&quot;czfn&quot;&gt; -DKBUILD_BASENAME=creator_pxa270_lcd&lt;/span&gt; -DKBUILD_MODNAME=creator_pxa270_lcd -c -o drivers/char/creator-pxa270-lcd.o drivers/char/creator-pxa270-lcd.c&lt;br id=&quot;mq-0&quot;&gt;&lt;br id=&quot;omz:&quot;&gt;&lt;h3 id=&quot;ojem&quot;&gt;&lt;span id=&quot;zf9u&quot;&gt;&lt;b&gt;obj-m&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;&lt;span id=&quot;rj3t&quot;&gt;&lt;b&gt;step1:&lt;/b&gt;&lt;/span&gt;&lt;br id=&quot;y-ls&quot;&gt;cmd_drivers/char/creator-pxa270-lcd.o := arm-unknown-linux-gnu-gcc -Wp,-MD,drivers/char/.creator-pxa270-lcd.o.d  -nostdinc -isystem /opt/microtime/pro/devkit/arm/pxa270/gcc-4.0.2-glibc-2.3.3/arm-unknown-linux-gnu/bin/../lib/gcc/arm-unknown-linux-gnu/4.0.2/include -D__KERNEL__ -Iinclude  -include include/linux/autoconf.h -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -fno-inline -Os     -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -fno-omit-frame-pointer -mapcs -mno-sched-prolog -mabi=apcs-gnu -mno-thumb-interwork -D__LINUX_ARM_ARCH__=5 -march=armv5te -mtune=xscale -Wa,-mcpu=xscale  -msoft-float -Uarm -Wdeclaration-after-statement -Wno-pointer-sign   &lt;font id=&quot;ov8d&quot; color=&quot;#ff0000&quot;&gt;&lt;span id=&quot;yg-d&quot;&gt;&lt;b&gt;-DMODULE&lt;/b&gt;&lt;/span&gt;&lt;/font&gt; -DKBUILD_BASENAME=creator_pxa270_lcd &lt;span id=&quot;gb5t&quot;&gt;-DKBUILD_MODNAME=creator_pxa270_lcd&lt;/span&gt; -c -o &lt;span id=&quot;ihaq&quot;&gt;drivers/char/creator-pxa270-lcd.o&lt;/span&gt; drivers/char/&lt;span id=&quot;w1th&quot;&gt;&lt;b&gt;creator-pxa270-lcd.c&lt;/b&gt;&lt;/span&gt;&lt;br id=&quot;b57:&quot;&gt;&lt;br id=&quot;p4n7&quot;&gt;&lt;span id=&quot;cjn7&quot;&gt;&lt;b&gt;step2:&lt;/b&gt;&lt;/span&gt;&lt;br id=&quot;hr4d&quot;&gt;scripts/mod/&lt;font id=&quot;omzb&quot; color=&quot;#ff0000&quot;&gt;&lt;span id=&quot;s2o8&quot;&gt;&lt;b&gt;modpost&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;   -o /usr/src/creator/pxa270/pro/devkit/lsp/create-pxa270/linux-2.6.15.3/Module.symvers &lt;span id=&quot;tthn&quot;&gt;&lt;b&gt;vmlinux&lt;/b&gt;&lt;/span&gt; drivers/char/&lt;span id=&quot;zs1r&quot;&gt;&lt;b&gt;creator-pxa270-lcd.o&lt;/b&gt;&lt;/span&gt;&lt;br id=&quot;f9fn&quot;&gt;&lt;br id=&quot;tc8t&quot;&gt;&lt;span id=&quot;x0wd&quot;&gt;&lt;b&gt;step3:&lt;/b&gt;&lt;/span&gt;&lt;br id=&quot;qr_m&quot;&gt;arm-unknown-linux-gnu-gcc -Wp,-MD,drivers/char/.creator-pxa270-lcd.mod.o.d  -nostdinc -isystem /opt/microtime/pro/devkit/arm/pxa270/gcc-4.0.2-glibc-2.3.3/arm-unknown-linux-gnu/bin/../lib/gcc/arm-unknown-linux-gnu/4.0.2/include -D__KERNEL__ -Iinclude  -include include/linux/autoconf.h -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -fno-inline -Os     -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -fno-omit-frame-pointer -mapcs -mno-sched-prolog -mabi=apcs-gnu -mno-thumb-interwork -D__LINUX_ARM_ARCH__=5 -march=armv5te -mtune=xscale -Wa,-mcpu=xscale  -msoft-float -Uarm -Wdeclaration-after-statement -Wno-pointer-sign    -DKBUILD_BASENAME=creator_pxa270_lcd -DKBUILD_MODNAME=creator_pxa270_lcd -DMODULE -c -o drivers/char/creator-pxa270-lcd.mod.o drivers/char/&lt;span id=&quot;ipi1&quot;&gt;&lt;b&gt;creator-pxa270-lcd.mod.c&lt;/b&gt;&lt;/span&gt;&lt;br id=&quot;u:0m&quot;&gt;&lt;br id=&quot;ftk9&quot;&gt;&lt;span id=&quot;o19d&quot;&gt;&lt;b&gt;step4:&lt;/b&gt;&lt;/span&gt;&lt;br id=&quot;y30g&quot;&gt;arm-unknown-linux-gnu-ld -EL  -r -o drivers/char/&lt;span id=&quot;en9e&quot;&gt;&lt;b&gt;creator-pxa270-lcd.ko &lt;/b&gt;&lt;/span&gt;&lt;span id=&quot;dhd0&quot;&gt;drivers/char/creator-pxa270-lcd.o drivers/char/creator-pxa270-lcd.mod.o&lt;/span&gt;&lt;br id=&quot;r56n&quot;&gt;&lt;br id=&quot;cpia&quot;&gt;&lt;br id=&quot;d10_&quot;&gt;&lt;br id=&quot;mwkw&quot;&gt;      </content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/2087780112409748947/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/2087780112409748947' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/2087780112409748947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/2087780112409748947'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2008/04/build-kernel-module-as-ko-files-show.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-91563742909096429</id><published>2008-04-12T07:20:00.000+08:00</published><updated>2008-05-12T14:42:57.533+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 參考資料篇"/><title type='text'></title><content type='html'>      &lt;h1 id=&quot;yo_i&quot;&gt;&lt;font id=&quot;g1qz&quot; color=&quot;#000066&quot;&gt;&lt;b id=&quot;iykz&quot;&gt;arm linux 启动流程之 解压内核 &lt;/b&gt;&lt;/font&gt;&lt;/h1&gt;          &lt;p id=&quot;sgbu&quot;&gt;&lt;font id=&quot;h_8w&quot; face=&quot;Tahoma&quot; size=&quot;4&quot;&gt;引用自: &lt;a title=&quot;http://blog.csdn.net/dansen_xu/archive/2007/08/13/1740738.aspx&quot; href=&quot;http://blog.csdn.net/dansen_xu/archive/2007/08/13/1740738.aspx&quot; id=&quot;jqcx&quot;&gt;&lt;/a&gt;&lt;a title=&quot;http://blog.csdn.net/dansen_xu/archive/2007/08/13/1740738.aspx&quot; href=&quot;http://blog.csdn.net/dansen_xu/archive/2007/08/13/1740738.aspx&quot; id=&quot;m0ra&quot;&gt;http://blog.csdn.net/dansen_xu/archive/2007/08/13/1740738.aspx&lt;/a&gt; &lt;br id=&quot;vifi&quot;&gt;&lt;/font&gt;&lt;/p&gt;&lt;p id=&quot;sgbu&quot;&gt;&lt;font id=&quot;h_8w&quot; face=&quot;Tahoma&quot; size=&quot;4&quot;&gt;Author-------Dansen-----xzd2734@163.com&lt;/font&gt;&lt;/p&gt; &lt;p id=&quot;fu:2&quot;&gt;&lt;font id=&quot;l_g-&quot; face=&quot;Tahoma&quot; size=&quot;4&quot;&gt;从后往前看下编译生成zImage的过程，我们可以找到程序的入口还是那个很重要&lt;br id=&quot;urko&quot;&gt;链接文件，找到它,生成zImage所在的目录是kernelarcharmbootcompressed&lt;br id=&quot;k:4l&quot;&gt;Make过程为....ld -p -X -T vmlinux.lds head.o misc.o head-s3c2410.o piggy.o&lt;br id=&quot;dws0&quot;&gt;libgcc.o -o vmlinux&lt;br id=&quot;zcw4&quot;&gt;然后是用二进制工具objcopy把vmlinux制作成可执行的二进制映像文件zImage&lt;br id=&quot;cu6-&quot;&gt;这样在我们就去kernelarcharmbootcompressed目录下去找到vmlinux.lds文件&lt;br id=&quot;ij::&quot;&gt;如果没有编译就不会有这个文件，因为它也是在编译过程生成的，由同一目录下的&lt;br id=&quot;o-vk&quot;&gt;vmlinux.lds.in生成，打开这个文件&lt;br id=&quot;owd5&quot;&gt;ENTRY(_start)&lt;br id=&quot;b0v5&quot;&gt;SECTIONS&lt;br id=&quot;guge&quot;&gt;{&lt;br id=&quot;u8ua&quot;&gt;  . = LOAD_ADDR;&lt;br id=&quot;mnc4&quot;&gt;  _load_addr = .;&lt;/font&gt;&lt;/p&gt; &lt;p id=&quot;u3u9&quot;&gt;&lt;font id=&quot;gc6z&quot; face=&quot;Tahoma&quot; size=&quot;4&quot;&gt;  . = TEXT_START;&lt;br id=&quot;frfl&quot;&gt;  _text = .;&lt;/font&gt;&lt;/p&gt; &lt;p id=&quot;zopj&quot;&gt;&lt;font id=&quot;wo6e&quot; face=&quot;Tahoma&quot; size=&quot;4&quot;&gt;  .text : {&lt;br id=&quot;hkit&quot;&gt;    _start = .;&lt;br id=&quot;upia&quot;&gt;    *(.start)&lt;br id=&quot;sz-v&quot;&gt;    *(.text)&lt;br id=&quot;pf0g&quot;&gt;........&lt;br id=&quot;qtph&quot;&gt;入口是_start,而且入口就直接定义在这个文件中了&lt;br id=&quot;o15w&quot;&gt;入口直接接着.start段,所以程序开始是从.start段开始执行的&lt;br id=&quot;yq5e&quot;&gt;如果看看vmlinux.lds的生成过程就应该能找到LOAD_ADDR和TEXT_START的值&lt;br id=&quot;tlol&quot;&gt;实际上这两个值是由其他两个变量赋给的 ZRELADDR 和 ZTEXTADDR&lt;br id=&quot;fuea&quot;&gt;在kernelarcharmbootMakefile中我们可以找到这两个变量的值&lt;br id=&quot;oazz&quot;&gt;ifeq ($(CONFIG_ARCH_S3C2410),y)&lt;br id=&quot;x01o&quot;&gt;ZTEXTADDR  = 0x30008000&lt;br id=&quot;n6fd&quot;&gt;ZRELADDR  = 0x30008000&lt;br id=&quot;a3lg&quot;&gt;endif&lt;br id=&quot;as1z&quot;&gt;所以&lt;br id=&quot;sox9&quot;&gt;LOAD_ADDR = 0x30008000&lt;br id=&quot;jtsu&quot;&gt;TEXT_START = 0x30008000&lt;br id=&quot;x5cb&quot;&gt;看一下vmlinux.lds吧&lt;br id=&quot;f8-e&quot;&gt;ENTRY(_start)&lt;br id=&quot;njap&quot;&gt;SECTIONS&lt;br id=&quot;krmh&quot;&gt;{&lt;br id=&quot;a150&quot;&gt;  . = 0x30008000;&lt;br id=&quot;a5m0&quot;&gt;  _load_addr = .;&lt;/font&gt;&lt;/p&gt; &lt;p id=&quot;ixip&quot;&gt;&lt;font id=&quot;l_0t&quot; face=&quot;Tahoma&quot; size=&quot;4&quot;&gt;  . = 0;&lt;br id=&quot;sfcc&quot;&gt;  _text = .;&lt;br id=&quot;sv1l&quot;&gt;显然LOAD_ADDR被赋值了0x30008000&lt;br id=&quot;acth&quot;&gt;看一下TEXT_START怎么成0了，我想这应该是一个偏移吧，偏移是0&lt;br id=&quot;zmye&quot;&gt;所以它还是0x30008000&lt;br id=&quot;er5e&quot;&gt;接着下来就从head.s来开始看代码吧&lt;br id=&quot;b1s0&quot;&gt;  .section &quot;.start&quot;, #alloc, #execinstr&lt;br id=&quot;exva&quot;&gt;/*&lt;br id=&quot;eu1z&quot;&gt; * sort out different calling conventions&lt;br id=&quot;ak.0&quot;&gt; */&lt;br id=&quot;ozv4&quot;&gt;  .align&lt;br id=&quot;rs5l&quot;&gt;start:&lt;br id=&quot;gt89&quot;&gt;  .type start,#function&lt;br id=&quot;ckr3&quot;&gt;  .rept 8&lt;br id=&quot;ffpu&quot;&gt;  mov r0, r0&lt;br id=&quot;i6u9&quot;&gt;  .endr&lt;/font&gt;&lt;/p&gt; &lt;p id=&quot;ob9v&quot;&gt;&lt;font id=&quot;nlul&quot; face=&quot;Tahoma&quot; size=&quot;4&quot;&gt;  b 1f&lt;br id=&quot;y87b&quot;&gt;  .word 0x016f2818  @ Magic numbers to help the loader&lt;br id=&quot;ee:j&quot;&gt;  .word start   @ absolute load/run zImage address&lt;br id=&quot;n.4w&quot;&gt;  .word _edata   @ zImage end address&lt;br id=&quot;yg4m&quot;&gt;1:  mov r7, r1   @ save architecture ID&lt;br id=&quot;acvp&quot;&gt;这里一定就是程序的入口了，一般汇编程序的含义就看看英文注释就是了&lt;br id=&quot;s9oa&quot;&gt;有一个要注意的地方，不是一个汇编文件就是属于一个段的，不是说先执行完了&lt;br id=&quot;e2q_&quot;&gt;head.s再去执行head-s3c2410.s,还是要注意链接的段,显然head.s&lt;br id=&quot;ig7i&quot;&gt;不一会就开始了另一个段.text&lt;br id=&quot;lch0&quot;&gt;  .text&lt;br id=&quot;bizl&quot;&gt;  adr r0, LC0&lt;br id=&quot;jxih&quot;&gt;  ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp}&lt;br id=&quot;u4gn&quot;&gt;  subs r0, r0, r1  @ calculate the delta offset&lt;br id=&quot;nvgp&quot;&gt;而我们的head-s3c2410.s呢&lt;br id=&quot;g_0b&quot;&gt; .section &quot;.start&quot;, #alloc, #execinstr&lt;br id=&quot;oxd0&quot;&gt;__S3C2410_start:&lt;br id=&quot;lv93&quot;&gt; bic r2, pc, #0x1f&lt;br id=&quot;v7qy&quot;&gt; add r3, r2, #0x4000  @ 16 kb is quite enough...&lt;br id=&quot;qedl&quot;&gt;还是属于.start段的，所以顺序执行下来时先执行head-s3c2410.s，然后再去执行&lt;br id=&quot;ono_&quot;&gt;.text段。head-s3c2410.s主要是cpu的一些初始化工作。接着下来我们会需要把内核&lt;br id=&quot;v.c-&quot;&gt;接压缩，先说说为什么吧。还是注意到上面生成zImage的文件中有一个piggy.o，往上&lt;br id=&quot;czuz&quot;&gt;追寻可以看到是piggy.o由那个真正的内核vmlinux生成的，这个vmlinux才是启动后一直在&lt;br id=&quot;bec4&quot;&gt;运行的内核，原本很大，压缩以后可以方便地放在flash中，当然其实不压缩跳到它的&lt;br id=&quot;xczb&quot;&gt;入口也就可以运行了。解压的内核是准备从LOAD_ADDR = 0x30008000开始的4M空间，会覆盖&lt;br id=&quot;nb47&quot;&gt;我们的当前运行的代码，那样就先把内核解压到我们这个zImage+分配堆栈0x10000的最后&lt;br id=&quot;yli2&quot;&gt;  cmp r4, r2  //r4 是LOAD_ADDR=0x30008000&lt;br id=&quot;k-x8&quot;&gt;  bhs wont_overwrite //r2 是当前代码的最底部    这里当然不会跳转&lt;br id=&quot;lfku&quot;&gt;  add r0, r4, #4096*1024 @ 4MB largest kernel size&lt;br id=&quot;omka&quot;&gt;  cmp r0, r5  //r5 也是0x30008000 &lt;br id=&quot;knhq&quot;&gt;  bls wont_overwrite //不会跳转&lt;/font&gt;&lt;/p&gt; &lt;p id=&quot;e4te&quot;&gt;&lt;font id=&quot;rhkb&quot; face=&quot;Tahoma&quot; size=&quot;4&quot;&gt;  mov r5, r2  //r2是(user_stack+4096)在zImage的最后+0x10000&lt;br id=&quot;gq3l&quot;&gt;  mov r0, r5  &lt;br id=&quot;jes1&quot;&gt;  mov r3, r7  //machine type&lt;br id=&quot;um1c&quot;&gt;  bl decompress_kernel &lt;br id=&quot;y9y-&quot;&gt;有了r5,r0,r7作为参数，就可以调用misc.c中的decompress_kernel函数进行解压缩了&lt;br id=&quot;o-wy&quot;&gt;这个函数调用的gunzip函数时gcc的库函数，所以在源码中找不到的&lt;br id=&quot;xw-o&quot;&gt;解压在r5开始的地方，函数返回的是r0解压得到的长度。这时候我们需要对代码经行调整&lt;br id=&quot;gedb&quot;&gt;  add r1, r5, r0  @ end of decompressed kernel&lt;br id=&quot;boc2&quot;&gt;  adr r2, reloc_start&lt;br id=&quot;ktey&quot;&gt;  ldr r3, LC1   //LC1: .word reloc_end - reloc_start&lt;br id=&quot;e3.6&quot;&gt;  add r3, r2, r3&lt;br id=&quot;isag&quot;&gt;1:  ldmia r2!, {r8 - r13}  @ copy relocation code&lt;br id=&quot;sanv&quot;&gt;  stmia r1!, {r8 - r13}&lt;br id=&quot;kwh4&quot;&gt;  ldmia r2!, {r8 - r13}&lt;br id=&quot;ll3v&quot;&gt;  stmia r1!, {r8 - r13}&lt;br id=&quot;g-aq&quot;&gt;  cmp r2, r3  //这里就把从reloc_start到reloc_end这段我们需要的代码放到了&lt;br id=&quot;v.v6&quot;&gt;  blo 1b  //解压内核的最后，而在下面我们会将zImage都覆盖掉&lt;br id=&quot;ug.d&quot;&gt;  bl cache_clean_flush&lt;br id=&quot;yhel&quot;&gt;  add pc, r5, r0 //调到调整后的reloc_start，在decompressed kernel后&lt;br id=&quot;hisv&quot;&gt;reloc_start: add r8, r5, r0 //r5解压内核开始的地方 r0解压内核的长度&lt;br id=&quot;cppw&quot;&gt;  debug_reloc_start&lt;br id=&quot;k2kh&quot;&gt;  mov r1, r4  //r4=0x30008000&lt;br id=&quot;wkr8&quot;&gt;1:&lt;br id=&quot;rwu1&quot;&gt;  .rept 4&lt;br id=&quot;y.-g&quot;&gt;  ldmia r5!, {r0, r2, r3, r9 - r13} @ relocate kernel&lt;br id=&quot;w.1y&quot;&gt;  stmia r1!, {r0, r2, r3, r9 - r13}&lt;br id=&quot;bnx0&quot;&gt;  .endr&lt;/font&gt;&lt;/p&gt; &lt;p id=&quot;kvu0&quot;&gt;&lt;font id=&quot;tsrz&quot; face=&quot;Tahoma&quot; size=&quot;4&quot;&gt;  cmp r5, r8&lt;/font&gt;&lt;/p&gt;&lt;p id=&quot;bzex&quot;&gt;&lt;font id=&quot;tsrz&quot; face=&quot;Tahoma&quot; size=&quot;4&quot;&gt;  blo 1b  //这样就又把解压的真正内核移到了0x30008000处&lt;/font&gt;&lt;/p&gt;&lt;p id=&quot;re-n&quot;&gt;&lt;font id=&quot;tsrz&quot; face=&quot;Tahoma&quot; size=&quot;4&quot;&gt;call_kernel: bl cache_clean_flush&lt;/font&gt;&lt;/p&gt;&lt;p id=&quot;pw5t&quot;&gt;&lt;font id=&quot;tsrz&quot; face=&quot;Tahoma&quot; size=&quot;4&quot;&gt;  bl cache_off&lt;/font&gt;&lt;/p&gt;&lt;p id=&quot;qxwa&quot;&gt;&lt;font id=&quot;tsrz&quot; face=&quot;Tahoma&quot; size=&quot;4&quot;&gt;  mov r0, #0&lt;/font&gt;&lt;/p&gt;&lt;p id=&quot;ffzh&quot;&gt;&lt;font id=&quot;tsrz&quot; face=&quot;Tahoma&quot; size=&quot;4&quot;&gt;  mov r1, r7   @ restore architecture number&lt;/font&gt;&lt;/p&gt;&lt;p id=&quot;l-5w&quot;&gt;&lt;font id=&quot;tsrz&quot; face=&quot;Tahoma&quot; size=&quot;4&quot;&gt;  mov pc, r4   @ call kernel&lt;/font&gt;&lt;/p&gt;&lt;p id=&quot;rdqr&quot;&gt;&lt;font id=&quot;tsrz&quot; face=&quot;Tahoma&quot; size=&quot;4&quot;&gt;上面就是跳到0x30008000这里去执行真正的内核了吧&lt;/font&gt;&lt;/p&gt;&lt;div id=&quot;google_header&quot; class=&quot;google_header&quot;&gt;&lt;p id=&quot;vy6y&quot;&gt; &lt;/p&gt;&lt;/div&gt;&lt;br id=&quot;a-wq&quot;&gt;      </content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/91563742909096429/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/91563742909096429' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/91563742909096429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/91563742909096429'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2008/04/arm-linux-httpblog.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-5687575575756297560</id><published>2008-03-29T03:17:00.000+08:00</published><updated>2008-05-12T14:42:57.534+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 參考資料篇"/><title type='text'></title><content type='html'>&lt;h1 id=&quot;vve.&quot;&gt;            Linux 下透過 GPRS 上網&lt;/h1&gt;&lt;br id=&quot;kzvk&quot;&gt;引用自:&lt;a title=&quot;http://blog.linym.net/archives/171&quot; href=&quot;http://blog.linym.net/archives/171&quot; id=&quot;gomf&quot;&gt; http://blog.linym.net/archives/171&lt;/a&gt; &lt;br id=&quot;ufgz&quot;&gt;&lt;br id=&quot;ym-a&quot;&gt;&lt;p id=&quot;b2hh&quot;&gt;&lt;b id=&quot;a9oj&quot;&gt;基本需求：&lt;/b&gt;&lt;/p&gt; &lt;ul id=&quot;n11j&quot;&gt;&lt;li id=&quot;f_sk&quot;&gt;可連上 GPRS 的硬體設備&lt;/li&gt;&lt;li id=&quot;fst5&quot;&gt;編譯 Kernel 使其支援 PPP&lt;/li&gt;&lt;li id=&quot;zt-f&quot;&gt;擁有 pppd、chat 兩個程式&lt;/li&gt;&lt;li id=&quot;t08t&quot;&gt;PPP 連線的 script 檔案&lt;/li&gt;&lt;/ul&gt; &lt;p id=&quot;tp7i&quot;&gt;&lt;b id=&quot;ac_-&quot;&gt;1. 可連上 GPRS 的硬體設備&lt;/b&gt;&lt;br id=&quot;iz10&quot;&gt; 可以是專用的 GPRS Modem 或是手機，不過當然要先配置好相關設定及驅動，我是使用 Wavecom Q2403A 這個 GSM/GPRS 模組透過 com port 來實驗。&lt;/p&gt; &lt;p id=&quot;vdfp&quot;&gt;&lt;b id=&quot;acpi&quot;&gt;2. 編譯 Kernel 使其支援 PPP&lt;/b&gt;&lt;br id=&quot;t_9-&quot;&gt; # make menuconfig&lt;br id=&quot;l23e&quot;&gt; 選擇 Device Drivers —&amp;gt; Network device support —&amp;gt; PPP (point-to-point protocol) support，底下的子項目如果不確定就全選即可。&lt;br id=&quot;xrr4&quot;&gt; 核心更新後請檢查 /dev/ppp 是否存在，若無可用 mknod /dev/ppp c 108 0 建立。&lt;/p&gt; &lt;p id=&quot;nm-n&quot;&gt;&lt;b id=&quot;b4yx&quot;&gt;3. 擁有 pppd、chat 兩個程式&lt;/b&gt;&lt;br id=&quot;gexp&quot;&gt; 如果是一般 PC 版本應該都已經有內建了；&lt;strike id=&quot;ljx0&quot; datetime=&quot;2007-09-16T01:38:33+00:00&quot;&gt;Embedded 平台則可以考慮使用 busybox，裡面也有包含這兩個程式；&lt;/strike&gt;再不然就自行下載 &lt;a id=&quot;qclm&quot; href=&quot;http://ppp.samba.org/ppp/download.html&quot; target=&quot;_blank&quot;&gt;source code&lt;/a&gt; 來編譯。&lt;/p&gt; &lt;p id=&quot;gm_n&quot;&gt;&lt;b id=&quot;zjqu&quot;&gt;4. PPP 連線的 script 檔案&lt;/b&gt;&lt;br id=&quot;du2h&quot;&gt; 建立 script 來做 PPP 連線，通常可以在 /usr/share/doc/ppp/examples/scripts 底下找到 ppp-on、ppp-off、ppp-on-dialer 三個範例檔案，不過用範例檔的設定不一定能成功，請參考&lt;a id=&quot;fr3i&quot; href=&quot;http://blog.linym.net/wp-content/uploads/2007/08/gprs.zip&quot;&gt;我的檔案&lt;/a&gt;，已測試中華電信可以成功。&lt;/p&gt; &lt;p id=&quot;d_-.&quot;&gt;相關的設定及原理可以參考：&lt;/p&gt; &lt;ul id=&quot;veas&quot;&gt;&lt;li id=&quot;aofb&quot;&gt;&lt;a id=&quot;yfu3&quot; href=&quot;http://tldp.org/HOWTO/PPP-HOWTO/&quot;&gt;Linux PPP HOWTO&lt;/a&gt; (另有&lt;a id=&quot;m-:.&quot; href=&quot;http://linux.cis.nctu.edu.tw/chinese/how-to/PPP-HOWTO.html&quot;&gt;中譯版&lt;/a&gt;)&lt;/li&gt;&lt;li id=&quot;g_56&quot;&gt;&lt;a id=&quot;bk:j&quot; href=&quot;http://wiki.openmoko.org/wiki/Manually_using_GPRS&quot;&gt;Manually using GPRS&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br id=&quot;bfuf&quot;&gt;      &lt;br id=&quot;orx3&quot;&gt;</content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/5687575575756297560/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/5687575575756297560' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/5687575575756297560'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/5687575575756297560'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2008/03/linux-gprs-httpblog.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-7422580890913799926</id><published>2008-03-29T03:16:00.000+08:00</published><updated>2008-05-12T14:42:57.534+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 參考資料篇"/><title type='text'></title><content type='html'>                        &lt;div class=&quot;post&quot; id=&quot;post-109&quot;&gt; 			&lt;h1 id=&quot;i5y-&quot;&gt;&lt;a id=&quot;ex4i&quot; href=&quot;http://jayya.com/2006/01/16/109&quot; rel=&quot;bookmark&quot; title=&quot;Permanent Link: 移植KVM到arm-linux(1)&quot;&gt;移植KVM到arm-linux&lt;/a&gt;&lt;/h1&gt;&lt;br id=&quot;fy-v&quot;&gt;引用自: &lt;a title=&quot;http://tech.jayya.com/2007/11/28/porting-kvm-to-armlinux.html&quot; href=&quot;http://tech.jayya.com/2007/11/28/porting-kvm-to-armlinux.html&quot; id=&quot;lioa&quot;&gt;http://tech.jayya.com/2007/11/28/porting-kvm-to-armlinux.html&lt;/a&gt; &lt;br id=&quot;rlfm&quot;&gt;&lt;br id=&quot;tn3:&quot;&gt;  			&lt;div id=&quot;y.:y&quot; class=&quot;entry&quot;&gt; 				&lt;p id=&quot;c6tw&quot;&gt;上午kvm能正常在板子上运行了，并且还解决了preverify的问题（感谢一下陶老师的帮助和提醒），今天一并完整的写出来整个过程吧 &lt;/p&gt;&lt;ol id=&quot;hd-t&quot;&gt;&lt;li id=&quot;thqo&quot;&gt;&lt;b id=&quot;e.7q&quot;&gt;建立交叉编译环境：&lt;/b&gt;&lt;/li&gt;&lt;p id=&quot;d0-d&quot;&gt; &lt;/p&gt;&lt;ul id=&quot;p.5a&quot;&gt;&lt;li id=&quot;a6uo&quot;&gt;下载xscale-arm-linux-toolchain.tgz,tar zxfv xscale-arm-linux-toolchain.tgz,将解压后的文件在/usr/local/arm-linux下，将他击入当前的路径下， 比如修改你的.bash_profile,PATH=$PATH:/usr/local/arm-linux/bin,退出，在登陆使之生效，输入arm -linux-gcc -v可以查看gcc的版本;&lt;/li&gt;&lt;li id=&quot;c11t&quot;&gt;&lt;font id=&quot;x1sr&quot; color=&quot;red&quot;&gt;很抱歉，写得时候漏写了一个重要的设置步骤，多谢雨里来的提醒,现补充如下：&lt;/font&gt;我们还需要安装交叉编译环境的标准C函数库，进入系统的/usr/目录并解压库函数软件包&lt;br id=&quot;yrzl&quot;&gt; [user@host]# cd /usr&lt;br id=&quot;pr4:&quot;&gt; [user@host]# tar zvxf /root/gnupro-bin-glibc2.2.4.tgz&lt;br id=&quot;zz3c&quot;&gt; 上述命令会在系统目录/usr/cygnus/xscale-020726/H-i686-pc-linux-gnulibc2.4/目录下建立一系列的子目录和文件，它们是交叉编译时需要的标准C函数库和各种工具。&lt;/li&gt;&lt;/ul&gt;&lt;li id=&quot;y7mk&quot;&gt;&lt;b id=&quot;vood&quot;&gt;下载sun的cldc的src&lt;/b&gt;&lt;/li&gt;&lt;p id=&quot;zl77&quot;&gt;解压，里面包含有相关的源码。我这里使用了j2me_cldc-1_0_4-src-winunix.zip，j2me_cldc-1_1-fcs -src-winunix.zip这两个都可以在sun的网站下载，不过推荐大家抓紧时间下载，因为今天去下载midp2.0就已经不能下载了（sun 阿，令人失望！）。&lt;/p&gt;&lt;li id=&quot;d4_t&quot;&gt;&lt;b id=&quot;zrz6&quot;&gt;安装jdk并设置后相关路径&lt;/b&gt;&lt;/li&gt;&lt;p id=&quot;xb93&quot;&gt;这里不推荐使用jdk1.5，因为他对中文的支持有问题，使用1.4或者更低的都可以（希望可以在sun的官方找到）&lt;br id=&quot;k5wx&quot;&gt; 我使用的是1.4.2_01。修改.bash_profile或者/etc/profile添加PATH或者CLASSPATH。这里说一些为什么要用到 jdk，主要是要编译api里面的java文件，当然我们只一致kvm就不需要这个了，详细地大家可以看看解开的文件cldc文件夹里面的make文件&lt;/p&gt;&lt;li id=&quot;n2g3&quot;&gt;&lt;b id=&quot;jcdf&quot;&gt;修改make文件&lt;/b&gt;&lt;/li&gt;&lt;p id=&quot;j-25&quot;&gt;进入j2me_cldc/kvm/VmUnix/build/，vi修改Makefile，主要修改将原来使用的x86的编译器GCC改为我们的 arm-linux-gcc，这样才能得到我们的所需，我主要是修改下面的句子：ifeq ($(GCC), true) CC =arm-linux-gcc，另外我又在文件的开始指定export PLATFORM=linux，当然你也可以在make的时候加参数PLATFORM=linux。&lt;/p&gt;&lt;li id=&quot;h86u&quot;&gt;&lt;b id=&quot;xqlz&quot;&gt;编译&lt;/b&gt;&lt;/li&gt;&lt;p id=&quot;tt7w&quot;&gt;先编译preverify，进入tools/preverfiyer/build/linux下，make，这里没有必要对这个makefile进 行修改，况且你的编译平台是x86，应该不能进行修改，否则编译出来的preverify是不运行的，那么kvm的编译也将会不能通过。&lt;br id=&quot;eemd&quot;&gt; 编译kvm，进入kvm/VmUnix/build,make,就可以得到kvm,注意这个是在kvm的build目录下生成的,file kvm会的到以下信息:kvm: ELF 32-bit LSB executable, ARM, version 1 (ARM), for GNU/Linux 2.4.18, dynamically linked (uses shared libs), not stripped&lt;/p&gt;&lt;li id=&quot;oeic&quot;&gt;&lt;b id=&quot;e3_f&quot;&gt;在板子上运行并进行相应的测试&lt;/b&gt;&lt;/li&gt;&lt;p id=&quot;y:kl&quot;&gt;将得到的kvm,烧到板子上,x86下kvm运行所需文件： libm.so.6 =&amp;gt; /lib/tls/libm.so.6 (0xb75c0000)&lt;br id=&quot;l2ts&quot;&gt;         libnsl.so.1 =&amp;gt; /lib/libnsl.so.1 (0xb75ab000)&lt;br id=&quot;tfcj&quot;&gt;         libc.so.6 =&amp;gt; /lib/tls/libc.so.6 (0xb7473000)&lt;br id=&quot;ah2s&quot;&gt;         /lib/ld-linux.so.2 =&amp;gt; /lib/ld-linux.so.2 (0xb75eb000)&lt;br id=&quot;ncyf&quot;&gt; 大家可以参考以下,以便能使板子环境符合要求.更改属性为a+x,运行kvm,没有任何参数的情况下将会出现以下信息:ALERT: Must provide class name&lt;br id=&quot;sfak&quot;&gt; Usage: kvm &amp;lt; -options&amp;gt; &lt;br id=&quot;n2ji&quot;&gt; Options:&lt;br id=&quot;c2eg&quot;&gt;   -version&lt;br id=&quot;tw18&quot;&gt;   -classpath &lt;br id=&quot;d21o&quot;&gt;   -heapsize  (e.g. 65536 or 128k or 1M)&lt;/p&gt;&lt;li id=&quot;d.:y&quot;&gt;&lt;b id=&quot;m3es&quot;&gt;运行helloworld并正确使用preverify&lt;/b&gt;&lt;/li&gt;&lt;p id=&quot;m58v&quot;&gt;这一步准确来说不是移植要做的事情,因为这是j2me开发者要注意的事情.我们先来看看kvm的执行.class 文件的机制:&lt;br id=&quot;j2az&quot;&gt; &lt;a id=&quot;dpr5&quot; class=&quot;imagelink&quot; href=&quot;http://www.jayya.com/wp-content/uploads/2006/01/portingVerifiera.gif&quot; title=&quot;portingVerifiera.gif&quot; rel=&quot;lightbox&quot;&gt;&lt;img id=&quot;image112&quot; src=&quot;http://www.jayya.com/wp-content/uploads/2006/01/portingVerifiera.gif&quot; alt=&quot;portingVerifiera.gif&quot; target=&quot;_blank&quot;&gt;&lt;/a&gt;&lt;br id=&quot;kb8:&quot;&gt; 如图示:我们javac编译完的生成的.class文件必须经过preverify预验证后才能被kvm正确的执行,否则会出现 java/class/Verifyerror,为什么要采用预验证机制,是因为sun考虑到嵌入式设备资源有限,所以将jvm的庞大字节码验证机制进行 严重的”缩水”,也就用了一个轻量级机制&lt;br id=&quot;o:g2&quot;&gt; 来保证安全.说了这么多,讲讲具体怎么使用(这个流程开发j2me程序的人应该都知道点,虽然大家都不常用这个来开发).&lt;br id=&quot;x4_2&quot;&gt; 1编译javac -classpath  kvm/classes  hello.java   这里kvm/classes指你编译生成的classes文件夹&lt;br id=&quot;dzci&quot;&gt; 2预验证preverify -classpath kvm/classes -d . mydir&lt;br id=&quot;yr:q&quot;&gt; preverify有几个参数: -classpath  同上  -d 输出验证后的class文件,默认的是当前目录下的output文件夹下,还有检测是否使用了 finalizers ,float,native methods等&lt;br id=&quot;wvz:&quot;&gt; 将检验后的classs文件放到板子上,就可以执行了!&lt;br id=&quot;llho&quot;&gt; &lt;/p&gt;&lt;/ol&gt;  								&lt;br id=&quot;ke7e&quot;&gt;&lt;h3 id=&quot;exyq&quot;&gt;CLDC 1.0.4 Fix for Red_Hat&lt;br id=&quot;wsr.&quot;&gt;&lt;/h3&gt;&lt;p id=&quot;kqrm&quot;&gt;引用自: &lt;a title=&quot;http://forum.java.sun.com/thread.jspa?threadID=468349&quot; href=&quot;http://forum.java.sun.com/thread.jspa?threadID=468349&quot; id=&quot;r.2h&quot;&gt;http://forum.java.sun.com/thread.jspa?threadID=468349&lt;/a&gt; &lt;/p&gt;&lt;p id=&quot;kqrm&quot;&gt;&lt;br id=&quot;e.vw&quot;&gt;&lt;/p&gt;&lt;p id=&quot;kqrm&quot;&gt; The following works for J2ME CLDC 1.1 (it may be the same for 1.0.4, I didn&#39;t try that).&lt;br id=&quot;a25b&quot;&gt; &lt;br id=&quot;oy41&quot;&gt; If you don&#39;t care to verify that you are having the same problem, skip ahead a bit to what I did to fix the problem I was having. &lt;br id=&quot;qp.z&quot;&gt; &lt;br id=&quot;c7ju&quot;&gt; Rebuild the kvm with debugging on. Goto the j2me_cldc/build/linux directory&lt;br id=&quot;n-su&quot;&gt; edit Makefile around the 4th line add a line that says &quot;export DEBUG=true&quot;&lt;br id=&quot;n.ux&quot;&gt; If you have previously run make then do &quot;make clean&quot; then &quot;make&quot;&lt;br id=&quot;u8:y&quot;&gt; &lt;br id=&quot;u183&quot;&gt; Im assuming your PATH and CLASSPATH are set appropriately so you can simply prevreify a class by typing &quot;preverify HelloWorld&quot; and you see &quot;Segmentation fault&quot;&lt;br id=&quot;r0w6&quot;&gt; &lt;br id=&quot;s_7z&quot;&gt; At this point run &quot;preverify -verbose HelloWorld&quot; and you will see that it is indeed running and loading classes but it craps out after a few classes.&lt;br id=&quot;co.v&quot;&gt; &lt;br id=&quot;e26.&quot;&gt; To run the debugger on this type &quot;gdb --args preverify HelloWorld&quot;&lt;br id=&quot;t6:e&quot;&gt; at the (gdb) prompt type &quot;run&quot;.  You will see&lt;br id=&quot;yk.9&quot;&gt; &quot;Program received signal SIGSEGV, Segmentation fault.&quot;&lt;br id=&quot;gj2b&quot;&gt; Type bt (or backtrace) in the debuger. If you see something like this&lt;br id=&quot;m9-s&quot;&gt; &lt;br id=&quot;y1k2&quot;&gt; #0  0x4207c1ac in memcpy () from /lib/tls/libc.so.6&lt;br id=&quot;m7m7&quot;&gt; #1  0x080520ef in utf2native ()&lt;br id=&quot;ah.j&quot;&gt; #2  0x0805b9ab in Locked_InitializeClass ()&lt;br id=&quot;eu:9&quot;&gt; ...&lt;br id=&quot;wjhz&quot;&gt; &lt;br id=&quot;jtqy&quot;&gt; then you either didn&#39;t get the &quot;export DEBUG=true&quot; part right or your didn&#39;t &quot;make clean&quot; or something else happened. You should see something more like this (more detail):&lt;br id=&quot;nlry&quot;&gt; &lt;br id=&quot;q9st&quot;&gt; #0  0x4207c1ac in memcpy () from /lib/tls/libc.so.6&lt;br id=&quot;z2co&quot;&gt; #1  0x080520ef in utf2native (from=0x8069740 &quot;?_006b&quot;, to=0xbfff6ba0 &quot;&quot;,&lt;br id=&quot;d6zp&quot;&gt;     buflen=-1073779800) at ../../src/convert_md.c:100&lt;br id=&quot;m7mp&quot;&gt; #2  0x0805b9ab in Locked_InitializeClass (cb=0x8069740, detail=0xbfff6ba0)&lt;br id=&quot;nggn&quot;&gt;     at ../../src/classresolver.c:685&lt;br id=&quot;yz-2&quot;&gt; #3  0x0805b57a in InitializeClass (cb=0x8069740, detail=0xbfff6ba0)&lt;br id=&quot;j:ji&quot;&gt;     at ../../src/classresolver.c:506&lt;br id=&quot;t6ei&quot;&gt; #4  0x0805c2af in InitializeAndResolveClass (cb=0x8069740, resolve=FALSE)&lt;br id=&quot;eao6&quot;&gt;     at ../../src/classresolver.c:991&lt;br id=&quot;cwrk&quot;&gt; ...&lt;br id=&quot;jnvr&quot;&gt; &lt;br id=&quot;syet&quot;&gt; what this is telling you is that the glibc memcpy function is where the segfault happened. memcpy is trying to copy memory but it looks like the buffer length (buflen) is bogus. memcpy is called from utf2native which is called by Locked_InitializerClass in classresolver.c&lt;br id=&quot;vy02&quot;&gt; &lt;br id=&quot;anv0&quot;&gt; Quit the debugger (“quit”). Goto j2me_cldc/tools/preverifier/src/&lt;br id=&quot;y5hi&quot;&gt; &lt;br id=&quot;p6gb&quot;&gt; Look at the file classresolver.c, at the Locked_InitializerClass function, around line 572. See the lines&lt;br id=&quot;m9z5&quot;&gt; &lt;br id=&quot;jcv.&quot;&gt;     char buff[BUFSIZ];&lt;br id=&quot;pdzv&quot;&gt;     char *nativeName = &amp;amp;buff[0];&lt;br id=&quot;n43-&quot;&gt; &lt;br id=&quot;nmn1&quot;&gt; remember them. Look down to line 685, see the lines&lt;br id=&quot;aw-a&quot;&gt; &lt;br id=&quot;oyvz&quot;&gt;     utf2native(cbSuperName(cb), nativeName, BUFSIZ);&lt;br id=&quot;gbxh&quot;&gt;     super = FindClassFromClass(ee, nativeName, FALSE, cb);&lt;br id=&quot;t.gm&quot;&gt; &lt;br id=&quot;i:nt&quot;&gt; Nowehere else in classresolver.c is this buff or *nativeName used (so Im assuming we are free to mess with without significantly impacting anything else). What this is doing is creating a buffer on the stack that is BUFSIZ big (8192 bytes). utf2native gets the buffer and size and calls memcpy. Im guessing that because the preverifier seems to be loading classes recursively that there are lots of buffers like this on the stack hanging around and Im running out of stack space which results in a segmentation fault. I don’t know why EVERYONE running linux doesn’t have this problem.&lt;br id=&quot;ipms&quot;&gt; &lt;br id=&quot;t4wa&quot;&gt; How to fix this? We are now going to change the program to put the buffer in dynamic memory not on the stack. &lt;br id=&quot;tt6e&quot;&gt; &lt;br id=&quot;le0q&quot;&gt; In classresolver.c, around line 572, change the buff and nativeName declarations to this (comment out the old ones, put in new ones):&lt;br id=&quot;g_01&quot;&gt; &lt;br id=&quot;xn6r&quot;&gt;&lt;span id=&quot;e5bi&quot;&gt;&lt;b&gt;     //char buff[BUFSIZ];&lt;/b&gt;&lt;/span&gt;&lt;br style=&quot;font-weight: bold;&quot; id=&quot;v6e5&quot;&gt;&lt;span id=&quot;hm:x&quot;&gt;&lt;b&gt;     //char *nativeName = &amp;amp;buff[0];&lt;/b&gt;&lt;/span&gt;&lt;br style=&quot;font-weight: bold;&quot; id=&quot;gnfi&quot;&gt;&lt;span id=&quot;zuoa&quot; style=&quot; color: rgb(0, 0, 255);&quot;&gt;&lt;b&gt;     char *buff;&lt;/b&gt;&lt;/span&gt;&lt;br style=&quot;font-weight: bold; color: rgb(0, 0, 255);&quot; id=&quot;n563&quot;&gt;&lt;span id=&quot;ydur&quot; style=&quot; color: rgb(0, 0, 255);&quot;&gt;&lt;b&gt;     char *nativeName;&lt;/b&gt;&lt;/span&gt;&lt;br id=&quot;vut6&quot;&gt; &lt;br id=&quot;w0qh&quot;&gt; The skip down to around line 685. Add a few lines around the call to utf2native to look like this:&lt;br id=&quot;kel9&quot;&gt; &lt;br style=&quot;font-weight: bold;&quot; id=&quot;d8yq&quot;&gt;&lt;span id=&quot;yuwk&quot; style=&quot; color: rgb(0, 0, 255);&quot;&gt;&lt;b&gt;         buff = (char*)malloc(BUFSIZ);&lt;/b&gt;&lt;/span&gt;&lt;br style=&quot;font-weight: bold; color: rgb(0, 0, 255);&quot; id=&quot;daqo&quot;&gt;&lt;span id=&quot;g5ed&quot; style=&quot; color: rgb(0, 0, 255);&quot;&gt;&lt;b&gt;         if (buff == NULL)&lt;/b&gt;&lt;/span&gt;&lt;br style=&quot;font-weight: bold; color: rgb(0, 0, 255);&quot; id=&quot;mxwm&quot;&gt;&lt;span id=&quot;a6zt&quot; style=&quot; color: rgb(0, 0, 255);&quot;&gt;&lt;b&gt;             fprintf( stderr, &quot;Bogus, malloc failed.&quot; );&lt;/b&gt;&lt;/span&gt;&lt;br style=&quot;font-weight: bold; color: rgb(0, 0, 255);&quot; id=&quot;if3t&quot;&gt;&lt;span id=&quot;mqfd&quot; style=&quot; color: rgb(0, 0, 255);&quot;&gt;&lt;b&gt;         nativeName = buff;&lt;/b&gt;&lt;/span&gt;&lt;br style=&quot;font-weight: bold;&quot; id=&quot;zxgy&quot;&gt;                                                                                 &lt;br style=&quot;font-weight: bold;&quot; id=&quot;ffbn&quot;&gt;&lt;span id=&quot;mile&quot;&gt;&lt;b&gt;         utf2native(cbSuperName(cb), nativeName, BUFSIZ);&lt;/b&gt;&lt;/span&gt;&lt;br style=&quot;font-weight: bold;&quot; id=&quot;q0pu&quot;&gt;&lt;span id=&quot;l-nk&quot;&gt;&lt;b&gt;         super = FindClassFromClass(ee, nativeName, FALSE, cb);&lt;/b&gt;&lt;/span&gt;&lt;br style=&quot;font-weight: bold;&quot; id=&quot;t57n&quot;&gt; &lt;br style=&quot;font-weight: bold;&quot; id=&quot;oqgf&quot;&gt;&lt;span id=&quot;dyrz&quot; style=&quot; color: rgb(0, 0, 255);&quot;&gt;&lt;b&gt;         free(buff);&lt;/b&gt;&lt;/span&gt;&lt;br id=&quot;bna7&quot;&gt;                                                                                 &lt;br id=&quot;ge2q&quot;&gt; We added 4 lines before the utf2native call and the free(buff) after it. What we are doing is allocating dynamic memory for the buffer (not on the stack this time) and freeing it right after we are done with it. &lt;br id=&quot;fgl:&quot;&gt; &lt;br id=&quot;e_qc&quot;&gt; Save your work. Now &quot;make clean&quot; and &quot;make&quot;. When you try to run the preverifier, turn on -verbose. You will get the preverifier to run a little further but it may still die with a segmentation fault, this time in a different place, same problem. I found four c files that declare and use buff[BUFSIZ] (classloader.c, classresolver.c, file.c and jar_support.c). I also found that if you have your CLASSPATH is set to point to the j2me_cldc/api/classes directory or j2me_cldc/api/classes.zip file you will get the same error but different calling functions. My CLASSPATH originally pointed to the classes directory and the classloader.c and classresolver.c were crapping out. I switched to having the CLASSPATH point to the classes.zip file and then the jar_support.c functions were the problem. I fixed all 4 just to be sure. Im not guaranteeing this will solve your problem. But it solved mine. &lt;br id=&quot;jllc&quot;&gt; &lt;br id=&quot;ux42&quot;&gt; Dan&lt;a id=&quot;w0.l&quot; href=&quot;http://jayya.com/tag/%e7%a7%bb%e6%a4%8d&quot; rel=&quot;tag&quot;&gt;&lt;/a&gt;&lt;/p&gt; 				&lt;p id=&quot;b_15&quot; class=&quot;postmetadata alt&quot;&gt; 					&lt;small id=&quot;u9ai&quot;&gt;&lt;br id=&quot;buzy&quot;&gt;  						 					&lt;/small&gt; 				&lt;/p&gt;  			&lt;/div&gt; 		&lt;/div&gt;      </content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/7422580890913799926/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/7422580890913799926' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/7422580890913799926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/7422580890913799926'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2008/03/kvmarm-linux-httptech.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-2344879216918795871</id><published>2008-02-12T14:11:00.000+08:00</published><updated>2008-05-12T14:55:13.223+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 課程導覽"/><title type='text'></title><content type='html'>            &lt;h1 style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;ArmLinux 課程大綱 (PXA-270)&lt;/h1&gt; &lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;br&gt;&lt;/p&gt; &lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;font size=&quot;3&quot;&gt;&lt;a id=&quot;mfb6&quot; title=&quot;新華電腦開課資訊&quot; href=&quot;http://www.microtime.com.tw/training/ARM/9504/9604.htm&quot; target=&quot;_blank&quot;&gt;*新華電腦開課資訊&lt;/a&gt;: http://www.microtime.com.tw/training/ARM/9504/9604.htm&lt;/font&gt;&lt;/p&gt; &lt;br&gt;&lt;br&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background: blue none repeat scroll 0% 50%; color: white;&quot;&gt;Linux 操作與&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background: blue none repeat scroll 0% 50%; color: white;&quot;&gt;系統&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background: blue none repeat scroll 0% 50%; color: white;&quot;&gt;建置篇&lt;span lang=&quot;EN-US&quot;&gt;(9:00&lt;/span&gt;～&lt;span lang=&quot;EN-US&quot;&gt;16:00&lt;/span&gt;；&lt;span lang=&quot;EN-US&quot;&gt;6&lt;/span&gt; 小時&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;font color=&quot;#000099&quot;&gt;1. Linux 簡介&lt;br&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;&lt;font color=&quot;#000000&quot;&gt;        A. Linux 基本操作 &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;(&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;含實機操作&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;&lt;br&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;2. Embedded Linux &lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#000099&quot;&gt;系統架構&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;font color=&quot;#000099&quot;&gt;3. Embedded Linux &lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#000099&quot;&gt;核心組態&lt;/font&gt;&lt;span style=&quot;color: black;&quot; lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;font color=&quot;#000099&quot;&gt;4&lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#000099&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;. Embedded Linux &lt;/span&gt;檔案系統規劃&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;        A. Virtual PC&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;下建置&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt; Embedded Linux&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;(&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;含實機操作&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;br&gt;        &lt;font size=&quot;2&quot;&gt;B. &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;透過 &lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;Domingo debugger&lt;/span&gt;&lt;font size=&quot;2&quot;&gt;開發環境下載&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt; Embedded Linux&lt;span style=&quot;color: black;&quot;&gt; (&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;含實機操作&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;        C. NFS &lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;含實機操作&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;        D. MTD &lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;含實機操作&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt; &lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span style=&quot;color: black;&quot; lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;5&lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#000099&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;. Linux 應用程式環境&lt;br&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;font color=&quot;#000000&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;        A. Java Virtual Machine in Linux &lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;含實機操作&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000000&quot;&gt;        B. pppd &lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;含實機操作&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;br&gt; &lt;/p&gt; &lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background: blue none repeat scroll 0% 50%; color: white; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;Linux 程式開發篇&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;(9:00&lt;/span&gt;&lt;font size=&quot;2&quot;&gt;～&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;16:00&lt;/span&gt;&lt;font size=&quot;2&quot;&gt;；&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;6&lt;/span&gt;&lt;font size=&quot;2&quot;&gt;小時&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt; &lt;br&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;1. Embedded Linux &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;開發環境&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;font color=&quot;#000000&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;        A. Kbuild System for Kernel&lt;br&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;font color=&quot;#000000&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;        B. Auto Make System for Application&lt;br&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt; &lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;/p&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;2. Embedded Linux &lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#000099&quot;&gt;核心原始碼架構&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;3. Embedded Linux &lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#000099&quot;&gt;核心初始化分析&lt;/font&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;font color=&quot;#000000&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;        A. 以 ICE 除錯核心&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;font color=&quot;#000000&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;含實機操作&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;4. Linux &lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#000099&quot;&gt;應用程式設計&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;&lt;span style=&quot;color: black;&quot; lang=&quot;EN-US&quot;&gt;        A. Memory Management &lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span style=&quot;color: black;&quot; lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;含實機操作&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;&lt;span style=&quot;color: black;&quot; lang=&quot;EN-US&quot;&gt;        B. File access &lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span style=&quot;color: black;&quot; lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;含實機操作&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;        B. Process&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span style=&quot;color: black;&quot; lang=&quot;EN-US&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;含實機操作&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;        C. Thread &lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;含實機操作&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;        D. IPC &lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;含實機操作&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;5. &lt;/span&gt;應用程式共享程式庫&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;    A. &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;以&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;MP3 Decoder&lt;/span&gt;&lt;font size=&quot;2&quot;&gt;程式庫為例&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt; (&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;含實機操作&lt;/font&gt;&lt;span style=&quot;color: black;&quot;&gt;)&lt;font color=&quot;#000099&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;6. Linux&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font color=&quot;#000099&quot;&gt; 應用程式除錯工具&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;font color=&quot;#000000&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;        A. 以 GDB &lt;/span&gt;除錯&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;font color=&quot;#000000&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;應用程式&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;font color=&quot;#000000&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;含實機操作&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;        B&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;. &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;記憶體配置除錯&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;(memwatch/YAMD)&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;(&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt; 含實機操作&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;        C&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;. &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;系統呼叫追蹤 &lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;(strace)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt; (&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;含實機操作&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;background: blue none repeat scroll 0% 50%; color: white;&quot;&gt;基本驅動程式開發篇&lt;span lang=&quot;EN-US&quot;&gt;(9:00&lt;/span&gt;～&lt;span lang=&quot;EN-US&quot;&gt;16:00&lt;/span&gt;；&lt;span lang=&quot;EN-US&quot;&gt;6&lt;/span&gt;小時&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;font color=&quot;#000099&quot;&gt;1. Linux &lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#000099&quot;&gt;核心模組架構&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;        A&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt; . &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;建置與設定核心模組&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt; (&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;含實機操作&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt; &lt;br&gt;&lt;/font&gt;&lt;font color=&quot;#000099&quot;&gt;2  Linux &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;驅動程式架構&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;        A&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;. &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;建置與設定驅動程式&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;(&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt; 含實機操作&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;3. Linux 驅動程式&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;除錯工具&lt;/font&gt;&lt;span style=&quot;color: black;&quot; lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;        A. &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;列印訊息法&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;(printk)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt; (&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;含實機操作&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt; &lt;br&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;        B&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;. &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;訊息紀錄&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt; (&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;Klogd/syslogd) (&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt; 含實機操作&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;br&gt;        C&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;. &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;查詢除錯法&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;(proc)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt; (&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt; 含實機操作&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;4. Linux&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font color=&quot;#000099&quot;&gt; 字元類型驅動程式&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;A. &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;以&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;LED &amp;amp; DIP Switch &amp;amp; Key&lt;/span&gt;&lt;font size=&quot;2&quot;&gt; 為例&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;(&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt; 含實機操作&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;        B. &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;Interrupt&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;        C. Task Queue&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;        D. Memory management&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;&lt;br&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;b&gt;&lt;span style=&quot;background: blue none repeat scroll 0% 50%; color: white; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt; &lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;br&gt;&lt;/p&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;background: blue none repeat scroll 0% 50%; color: white; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;進階驅動程式開發篇&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;(9:00&lt;/span&gt;&lt;font size=&quot;2&quot;&gt;～&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt; 16:00&lt;/span&gt;&lt;font size=&quot;2&quot;&gt;；&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;6&lt;/span&gt;&lt;font size=&quot;2&quot;&gt;小時&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;1. LCD &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;驅動程式&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;        A. &lt;/span&gt;&lt;font size=&quot;2&quot;&gt;以&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;LCD&lt;/span&gt;&lt;font size=&quot;2&quot;&gt;控制&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;IC&lt;/span&gt;&lt;font size=&quot;2&quot;&gt;為例&lt;/font&gt;&lt;span style=&quot;color: black;&quot; lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;含實機操作&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;  &lt;br&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;        B. Frame Buffer 架構&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;2. Audio Driver 架構&lt;br&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;3. &lt;/font&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;串列埠控制&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;        A. &lt;/span&gt;&lt;font size=&quot;2&quot;&gt;以&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;Termios UART 控制&lt;/span&gt;&lt;font size=&quot;2&quot;&gt;為例&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt; (&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;含實機操作&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;        B. 控制台&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;架構 (Console Architecture)&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/p&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000066&quot;&gt;&lt;font color=&quot;#330099&quot;&gt;4. USB 驅動程式架構&lt;br&gt; 5. PCI 驅動程式架構&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt; &lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;6. Linux&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font color=&quot;#000099&quot;&gt; 區塊類型驅動程式&lt;/font&gt;&lt;span style=&quot;color: black;&quot; lang=&quot;EN-US&quot;&gt;&lt;br&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;A. &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;以&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;RAM Disk&lt;/span&gt;&lt;font size=&quot;2&quot;&gt;為例&lt;/font&gt;&lt;/span&gt; &lt;span style=&quot;color: black; line-height: 120%;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;&lt;font size=&quot;2&quot;&gt;含實機操作&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;font color=&quot;#000066&quot;&gt;&lt;font color=&quot;#330099&quot;&gt;&lt;br&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt;  &lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt; &lt;br&gt;&lt;/font&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;background: blue none repeat scroll 0% 50%; color: white; line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;網路應用開發篇&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;(9:00&lt;/span&gt;&lt;font size=&quot;2&quot;&gt;～&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt; 16:00&lt;/span&gt;&lt;font size=&quot;2&quot;&gt;；&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;6&lt;/span&gt;&lt;font size=&quot;2&quot;&gt;小時&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;font color=&quot;#000099&quot;&gt;1. Linux &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font color=&quot;#000099&quot;&gt;網路類型驅動程式&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;&lt;font color=&quot;#000099&quot;&gt;2. &lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#000099&quot;&gt;網路應用程式設計&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;        A. &lt;/span&gt;&lt;font size=&quot;2&quot;&gt;以聊天程式為例&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;&lt;font size=&quot;2&quot;&gt;含實機操作&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;br&gt;&lt;font color=&quot;#000099&quot;&gt;3. &lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#000099&quot;&gt;利用&lt;span lang=&quot;EN-US&quot;&gt; Embedded Linux &lt;/span&gt;設置網路服務&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;font color=&quot;#000099&quot;&gt; &lt;br&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;        A&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;. Telnetd&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;建置&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt; (&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt;含實機操作&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt; &lt;br&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;        B&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;. &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;Web Server&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt; 建置&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot; lang=&quot;EN-US&quot;&gt;&lt;font size=&quot;2&quot;&gt;(&lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 120%;&quot;&gt;&lt;font size=&quot;2&quot;&gt; 含實機操作&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;br&gt;&lt;font color=&quot;#000099&quot;&gt;4. CGI &lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#000099&quot;&gt;程式設計&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br&gt;        A. &lt;/span&gt;&lt;font size=&quot;2&quot;&gt;以&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;CGI &lt;/span&gt;&lt;font size=&quot;2&quot;&gt;程式控制&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;LED(&lt;/span&gt;&lt;font size=&quot;2&quot;&gt;含實機操作&lt;/font&gt;&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot;margin: 0cm 0cm 0pt; line-height: 120%; text-align: justify;&quot;&gt; &lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/2344879216918795871/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/2344879216918795871' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/2344879216918795871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/2344879216918795871'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2008/02/armlinux-pxa-270-httpwww.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-2174945952602907450</id><published>2008-01-05T21:40:00.000+08:00</published><updated>2008-02-11T22:38:02.124+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 參考資料篇"/><title type='text'></title><content type='html'>      &lt;h1&gt;有趣的主題&lt;/h1&gt; &lt;h3&gt;Linux Package&lt;/h3&gt;&lt;a href=&quot;http://packman.links2linux.org/&quot;&gt;Packman&lt;/a&gt;: http://packman.links2linux.org/ : 此網站存放 Suse Linux 軟體套件，讓使用者能很輕易地安裝與移除軟體。&lt;br&gt;&lt;a id=&quot;edet&quot; title=&quot;LinuxToy&quot; href=&quot;http://linuxtoy.org/&quot; target=&quot;_blank&quot;&gt;LinuxToy&lt;/a&gt;: http://linuxtoy.org/&lt;br&gt; &lt;p&gt;&lt;a id=&quot;zca1&quot; title=&quot;Ericsk 的 Ubuntu 筆記&quot; href=&quot;http://blog.xuite.net/ericsk0313/ubuntu&quot; target=&quot;_blank&quot;&gt;Ericsk 的 Ubuntu 筆記&lt;/a&gt;: http://blog.xuite.net/ericsk0313/ubuntu&lt;/p&gt; &lt;p&gt;&lt;a id=&quot;ezb_&quot; title=&quot;Ericsk 的個人網站&quot; href=&quot;http://blog.ericsk.org/&quot; target=&quot;_blank&quot;&gt;Ericsk 的個人網站&lt;/a&gt;: http://blog.ericsk.org/&lt;/p&gt; &lt;p&gt;&lt;a id=&quot;a2x_&quot; title=&quot;阿駕零零壹 © 學習筆記&quot; href=&quot;http://twntwn.info/blog/ajer001&quot; target=&quot;_blank&quot;&gt;阿駕零零壹 © 學習筆記&lt;/a&gt;: http://twntwn.info/blog/ajer001&lt;/p&gt;&lt;a id=&quot;b313&quot; title=&quot;Linux 的粉絲衝上浪頭 2.0&quot; href=&quot;http://blog.ilc.edu.tw/blog/blog/673/&quot; target=&quot;_blank&quot;&gt;Linux 的粉絲衝上浪頭 2.0&lt;/a&gt;: http://blog.ilc.edu.tw/blog/blog/673/   &lt;h3&gt;Device Driver&lt;/h3&gt;&lt;a id=&quot;pqde&quot; title=&quot;The GNU/Linux &amp;quot;usbnet&amp;quot; Driver Framework&quot; href=&quot;http://www.linux-usb.org/usbnet/&quot; target=&quot;_blank&quot;&gt;The GNU/Linux &quot;usbnet&quot; Driver Framework&lt;/a&gt;: http://www.linux-usb.org/usbnet/&lt;br&gt; &lt;h3&gt;JVM&lt;/h3&gt;&lt;a id=&quot;h0li&quot; title=&quot;Java Midlets on the Pocket PC - the Complete Tutorial&quot; href=&quot;http://www.pocketpcmag.com/blogs/index.php?blog=3&amp;amp;p=644&amp;amp;more=1&amp;amp;c=1&amp;amp;tb=1&amp;amp;pb=1&quot; target=&quot;_blank&quot;&gt;Java Midlets Tutorial (PocketPC)&lt;/a&gt;: http://www.pocketpcmag.com/blogs/index.php?blog=3&amp;amp;p=644&amp;amp;more=1&amp;amp;c=1&amp;amp;tb=1&amp;amp;pb=1&lt;br&gt;&lt;a id=&quot;v_pz&quot; title=&quot;JVMs, JDKs and JREs&quot; href=&quot;http://java-virtual-machine.net/other.html&quot; target=&quot;_blank&quot;&gt;JVMs, JDKs and JREs&lt;/a&gt;: http://java-virtual-machine.net/other.html&lt;br&gt; &lt;div id=&quot;welcome-body&quot;&gt; &lt;/div&gt; &lt;h3&gt;Network&lt;/h3&gt; &lt;p&gt;&lt;a id=&quot;nm3b&quot; title=&quot;Boa + PHP for uClinux&quot; href=&quot;http://www.menie.org/georges/uClinux/boa-php.html&quot; target=&quot;_blank&quot;&gt;Boa + PHP for uClinux&lt;/a&gt;: http://www.menie.org/georges/uClinux/boa-php.html&lt;/p&gt; &lt;p&gt;&lt;a id=&quot;wkpk&quot; title=&quot;PHP for IIS&quot; href=&quot;http://blog.raienet.com/188?TSSESSION=5d9fb85e5c0162885e12924128ef1838&quot; target=&quot;_blank&quot;&gt;PHP for IIS&lt;/a&gt;: http://blog.raienet.com/188?TSSESSION=5d9fb85e5c0162885e12924128ef1838&lt;/p&gt; &lt;div&gt;&lt;br&gt;&lt;h3&gt;Web Page Editor&lt;/h3&gt;&lt;a title=&quot;AceHTML&quot; target=&quot;_blank&quot; href=&quot;http://software.visicommedia.com/en/products/acehtmlfreeware/&quot; id=&quot;ea0c&quot;&gt;AceHTML&lt;/a&gt;: http://software.visicommedia.com/en/products/acehtmlfreeware/&lt;br&gt;&lt;a title=&quot;HomeSite&quot; target=&quot;_blank&quot; href=&quot;http://www.adobe.com/products/homesite/&quot; id=&quot;t-j5&quot;&gt;HomeSite&lt;/a&gt;: http://www.adobe.com/products/homesite/&lt;br&gt;&lt;a title=&quot;NotePad++&quot; target=&quot;_blank&quot; href=&quot;http://notepad-plus.sourceforge.net/tw/site.htm&quot; id=&quot;ipgg&quot;&gt;NotePad++&lt;/a&gt;: http://notepad-plus.sourceforge.net/tw/site.htm&lt;br&gt;&lt;a title=&quot;EditPlus&quot; target=&quot;_blank&quot; href=&quot;http://www.editplus.com/&quot; id=&quot;oow5&quot;&gt;EditPlus&lt;/a&gt;: http://www.editplus.com/&lt;br&gt;&lt;a title=&quot;Crimson&quot; target=&quot;_blank&quot; href=&quot;http://www.crimsoneditor.com/&quot; id=&quot;xvi4&quot;&gt;Crimson&lt;/a&gt;: http://www.crimsoneditor.com/&lt;br&gt; &lt;h3&gt;Forum&lt;/h3&gt; &lt;p&gt;&lt;a id=&quot;lhc4&quot; title=&quot;大鳥的實驗室&quot; href=&quot;http://www.armlabs.com/phpBB2/viewforum.php?f=7&quot; target=&quot;_blank&quot;&gt;大鳥的實驗室&lt;/a&gt;: http://www.armlabs.com/phpBB2/viewforum.php?f=7&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/2174945952602907450/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/2174945952602907450' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/2174945952602907450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/2174945952602907450'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2008/01/packman-suse-linux-packman-httppackman.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-6969976739394559972</id><published>2007-12-30T22:05:00.000+08:00</published><updated>2008-01-19T15:04:49.955+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 課程導覽"/><title type='text'></title><content type='html'>                                  &lt;h1&gt;ArmLinux 相關網站&lt;/h1&gt;&lt;h3&gt;Linux Kernel 相關網站&lt;/h3&gt;&lt;a title=&quot;The Linux Kernel Archives&quot; target=&quot;_blank&quot; href=&quot;http://www.kernel.org/&quot; id=&quot;giig&quot;&gt;The Linux Kernel Archives&lt;/a&gt;: http://www.kernel.org/&lt;br&gt;&lt;a title=&quot;The ARM Linux Project&quot; target=&quot;_blank&quot; href=&quot;http://www.arm.linux.org.uk/&quot; id=&quot;fj4w&quot;&gt;The ARM Linux Project&lt;/a&gt;: http://www.arm.linux.org.uk/&lt;br&gt;&lt;a title=&quot;The Familiar Project&quot; target=&quot;_blank&quot; href=&quot;http://familiar.handhelds.org/&quot; id=&quot;rsw8&quot;&gt;The Familiar Project&lt;/a&gt;: http://familiar.handhelds.org/&lt;br&gt;&lt;a title=&quot;IPAQ Linux Project:&quot; target=&quot;_blank&quot; href=&quot;http://www.ipaqlinux.com/&quot; id=&quot;o:p1&quot;&gt;IPAQ Linux Project&lt;/a&gt;: http://www.ipaqlinux.com/&lt;br&gt;&lt;br&gt;&lt;h3&gt;arm-linux-gcc 下載網站&lt;/h3&gt;&lt;a title=&quot;ARM Linux&quot; target=&quot;_blank&quot; href=&quot;ftp://ftp.arm.linux.org.uk/pub/armlinux/toolchain/&quot; id=&quot;f27u&quot;&gt;ARM Linux&lt;/a&gt;: ftp://ftp.arm.linux.org.uk/pub/armlinux/toolchain/     (Version 2.95.3, 3.0, 3.2)&lt;br&gt;&lt;a title=&quot;Handhelds.org&quot; target=&quot;_blank&quot; href=&quot;ftp://ftp.handhelds.org/projects/toolchain/&quot; id=&quot;px6l&quot;&gt;Handhelds.org&lt;/a&gt;: ftp://ftp.handhelds.org/projects/toolchain/        (Version 3.3.2, 3.4.1)&lt;br&gt;&lt;a title=&quot;ELDK 4.1&quot; target=&quot;_blank&quot; href=&quot;ftp://ftp.denx.de/pub/eldk/4.1/&quot; id=&quot;j8bw&quot;&gt;ELDK 4.1&lt;/a&gt;: ftp://ftp.denx.de/pub/eldk/4.1/                              (Version 4.0.0)&lt;br&gt;&lt;a title=&quot;GNU ARM&quot; target=&quot;_blank&quot; href=&quot;http://www.gnuarm.org/&quot; id=&quot;ew59&quot;&gt;GNU ARM&lt;/a&gt;: http://www.gnuarm.org/                                       (Version 4.0, 4.1, 4.2)  &lt;br&gt;&lt;br&gt;&lt;h3&gt;發展工具相關網站&lt;/h3&gt; &lt;a title=&quot;GCC ARM Improvement Project&quot; target=&quot;_blank&quot; href=&quot;http://www.inf.u-szeged.hu/gcc-arm/&quot; id=&quot;fa-2&quot;&gt;GCC ARM Improvement Project&lt;/a&gt;: http://www.inf.u-szeged.hu/gcc-arm/&lt;font color=&quot;#0000ff&quot;&gt;&lt;u&gt;&lt;br&gt;&lt;/u&gt;&lt;/font&gt;&lt;a title=&quot;arm-linux-gcc: ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3/gcc-core-2.95.3.tar.gz&quot; target=&quot;_blank&quot; href=&quot;ftp://ftp.gnu.org/gnu/gcc/&quot; id=&quot;bkfu&quot;&gt;GNU GCC Source&lt;/a&gt;: ftp://ftp.gnu.org/gnu/gcc/&lt;br&gt;&lt;br&gt;&lt;h3&gt;系統建置&lt;/h3&gt;&lt;a title=&quot;Linux from Scratch&quot; target=&quot;_blank&quot; href=&quot;http://lamp.linux.gov.cn/Linux/LFS-6.2/index.html&quot; id=&quot;ld_0&quot;&gt;Linux from Scratch&lt;/a&gt;: http://lamp.linux.gov.cn/Linux/LFS-6.2/index.html&lt;br&gt;&lt;a title=&quot;GNU Make Manual&quot; target=&quot;_blank&quot; href=&quot;http://www.gnu.org/software/make/manual/&quot; id=&quot;bm3p&quot;&gt;GNU Make Manual&lt;/a&gt;: http://www.gnu.org/software/make/manual/&lt;br&gt;&lt;a target=&quot;_blank&quot; title=&quot;鳥哥的Linux私房菜&quot; href=&quot;http://linux.vbird.org/&quot; id=&quot;xg0h&quot;&gt;鳥哥的Linux私房菜&lt;/a&gt;: http://linux.vbird.org/&lt;br&gt;&lt;br&gt;&lt;h3&gt;討論區&lt;/h3&gt;&lt;a title=&quot;Banto Linux Forum in Google Group&quot; target=&quot;_blank&quot; href=&quot;http://groups.google.com.tw/group/banto-linux/?msg=new&amp;amp;lnk=gcis&amp;amp;hl=zh-TW&quot; id=&quot;r1hs&quot;&gt;Banto Linux Forum in Google Group&lt;/a&gt;: http://groups.google.com.tw/group/banto-linux/?msg=new&amp;amp;lnk=gcis&amp;amp;hl=zh-TW&lt;br&gt;&lt;br&gt;</content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/6969976739394559972/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/6969976739394559972' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/6969976739394559972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/6969976739394559972'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2007/12/armlinux-linux.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-4908523310819374868</id><published>2007-12-30T21:24:00.000+08:00</published><updated>2008-01-21T16:06:10.616+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 課程導覽"/><title type='text'></title><content type='html'>                  &lt;h1&gt;ArmLinux 相關書籍&lt;/h1&gt;&lt;br&gt;*本課程參考與推薦使用下列書籍:&lt;br&gt;&lt;br&gt; &lt;h2 style=&quot;color: rgb(0, 0, 153);&quot;&gt;應用程式設計&lt;/h2&gt; &lt;h3&gt;&lt;a id=&quot;c58z&quot; title=&quot;Linux 程式設計教學手冊&quot; href=&quot;http://www.books.com.tw/exep/assp.php/mesmerli/exep/prod/booksfile.php?item=0010269756&quot; target=&quot;_blank&quot;&gt;Linux 程式設計教學手冊&lt;/a&gt; (基峰)&lt;/h3&gt;&lt;p&gt;&lt;img style=&quot;margin: 1em 1em 0pt 0pt; width: 200px; height: 200px; float: left;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_283fczb6r4c&quot;&gt;如果您已經有些許程式設計經驗，而且想要加入Linux程式設計的領域，這本最暢銷的入門書籍就是您所需要的。第三版新增的內容有MySQL的存取和管理、設計GNOME和KDE程式、在Linux標準下設計可攜性的應用程式。本書新增的內容還有核心的程式設計、設備驅動程式、CVS、grep、 GUI開發環境。作者利用一個CD資料庫管理應用程式一步步引導您，讓您得以由簡而繁的學習Linux程式設計。您將從最基本的概念（設計Linux C程式）起步。進而學習到基本的系統呼叫、檔案輸出和輸入、處理程序之間的通訊和shell設計。您也將學到一些使用者介面的開發工具和函式庫。本書從編譯和執行第一個程式的基礎起步。文中都會先說明基本的觀念，隨後再以實作程式範例，指引您將知識應用到真實的應用程式上。&lt;br&gt;&lt;/p&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt; &lt;h2 style=&quot;color: rgb(0, 0, 153);&quot;&gt;系統建置&lt;/h2&gt; &lt;h3&gt;&lt;a id=&quot;m6in&quot; title=&quot;Linux 技術手冊&quot; href=&quot;http://www.books.com.tw/exep/assp.php/mesmerli/exep/prod/booksfile.php?item=0010243634&quot; target=&quot;_blank&quot;&gt;Linux 技術手冊&lt;/a&gt; (歐萊禮)&lt;/h3&gt;&lt;img style=&quot;margin: 1em 1em 0pt 0pt; float: left; width: 200px; height: 200px;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_265d63rsgrm&quot;&gt;  &lt;p&gt;不論你是第一次安裝，還是已經使用 Linux 多年，而現在想要知道多一點關於如何添加網路印表機或設定 ADSL 連線，這本《Linux 技術手冊》（Running Linux）正是你不可或缺的手冊。各種設定上經常令人困擾的疑難雜症，在其它書上鮮少被提及者，本書中都有令你滿意的解答，所以在 Linux 使用族群中本書被公認是入門最佳的參考書。&lt;/p&gt; &lt;p&gt;舉凡要理解、安裝與開始使用 Linux 系統所需的一切知識，在這本《Linux 技術手冊》中皆有涵蓋。本書並不刻意強調 OS、shell、GUI，甚至重要應用程式之間的分野；由於本書的作者都是一些經驗老道的 Linux 熱愛者，他們早就設想到讀者可能會遭遇的問題所在，已為你選擇好穩健且通行的解決方案，並且提供詳盡的討論說明及指引，讓你能夠很愜意的使用 Linux。書中的討論說明儘求明確與完整，不但初學者可以得到清楚的方向，有經驗的使用者也可從中吸取許多新知，對其 Linux 功力的精進將有很大助益。&lt;/p&gt; &lt;p&gt;對任何 Linux 的使用者來說，這都是一本札實的入門手冊；此外，本書中還包括許多的參考資源，可以因應由於各種硬體配備、進階應用，以及陸續出現的新科技所帶來的特殊需求。無論是家用電腦工作站的 Linux 使用者，或是負責維護網路伺服器的系統管理員，當有需要的時候，《Linux 技術手冊》隨時都可以為你提供最專業的建言。&lt;/p&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt; &lt;h3&gt;&lt;a id=&quot;mrlq&quot; title=&quot;Linux 網路管理&quot; href=&quot;http://www.books.com.tw/exep/assp.php/mesmerli/exep/prod/booksfile.php?item=0010294072&quot; target=&quot;_blank&quot;&gt;Linux 網路管理&lt;/a&gt; (歐萊禮)&lt;/h3&gt; &lt;p&gt;&lt;img style=&quot;margin: 1em 1em 0pt 0pt; float: left; width: 200px; height: 200px;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_268ghsjc8z6&quot;&gt;Linux 是最受歡迎的網路作業系統，也是最受歡迎的伺服器平台。本書示範如何使用 Linux 系統架設各種網路伺服器，並提供許多關於管理上的建議。本書涵蓋的題材，從基本的網路介面設定工作開始，TCP/IP 協定的基本觀念、閘道器的設計、如何搭建 PPP 連線、DNS server 的架設與管理、IP 防火牆的設置、電子郵件系統的架設與管理、OpenLDAP、Apache、Samba 伺服器的管理，甚至新興的無線網路與 IPv6。除了實務上的指導，每一章都提供適度的背景知識，讓讀者有能力進行更深度的研究。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; &lt;h3&gt;&lt;a id=&quot;skkz&quot; title=&quot;建構嵌入式 Linux 系統&quot; href=&quot;http://www.books.com.tw/exep/assp.php/mesmerli/exep/prod/booksfile.php?item=F010223024&quot; target=&quot;_blank&quot;&gt;建構嵌入式 Linux 系統&lt;/a&gt; (歐萊禮)&lt;img style=&quot;margin: 1em 1em 0pt 0pt; float: left; width: 200px; height: 200px;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_264fbrms2hd&quot;&gt;&lt;/h3&gt; &lt;p&gt;&lt;span id=&quot;proddetail_lb_prodsay&quot;&gt;《建構嵌入式Linux系統》是第一本深入探討基於Linux核心之嵌入式系統的指南。對想要瞭解如何將Linux應用在嵌入式系統中而不得要領的讀者來說，這是一本不可或缺的書。本書詳細的探討了各種目標板架構以及硬體組態，並且徹底的檢視了Linux對嵌入式硬體的支援。&lt;br&gt;&lt;br&gt;書中所有說明都是以開放原碼及自由軟體套件的使用為依據。本書會告訴你如何從頭開始建立作業系統元件，以及如何找到更多的文件或協助，因此不論你是基於技術上或經濟上的考量而採用Linux，本書都能輕易地讓你全盤掌控嵌入式作業系統。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot;color: rgb(0, 0, 153);&quot;&gt; &lt;/p&gt; &lt;h2 style=&quot;color: rgb(0, 0, 153);&quot;&gt;驅動程式設計&lt;/h2&gt; &lt;h3&gt;&lt;a id=&quot;c4mv&quot; title=&quot;Linux 驅動程式&quot; href=&quot;http://www.books.com.tw/exep/assp.php/mesmerli/exep/prod/booksfile.php?item=0010332242&quot; target=&quot;_blank&quot;&gt;Linux 驅動程式&lt;/a&gt; (歐萊禮)&lt;/h3&gt;&lt;img style=&quot;margin: 1em 1em 0pt 0pt; float: left; width: 170px; height: 211px;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_266g84mqdns&quot;&gt;詳論設計 Linux 驅動程式的各種技術。&lt;br&gt;探討 Linux 核心內部運作的各種相關細節。&lt;br&gt;設計驅動程式所需的各種 API 之參考手冊。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt; &lt;h2 style=&quot;color: rgb(0, 0, 153);&quot;&gt;ARM 架構&lt;/h2&gt; &lt;h3&gt;&lt;a id=&quot;z_cu&quot; title=&quot;ARM 系統開發者指南&quot; href=&quot;http://www.books.com.tw/exep/assp.php/mesmerli/exep/prod/booksfile.php?item=0010312252&quot; target=&quot;_blank&quot;&gt;ARM 系統開發者指南&lt;/a&gt; (全華)&lt;/h3&gt; &lt;p&gt;&lt;img style=&quot;margin: 1em 1em 0pt 0pt; float: left; width: 200px; height: 274px;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_267g3znpshh&quot;&gt;本書從軟體設計的角度，全面、而有系統的介紹ARM處理器基本族系架構和軟體設計與最佳化方法。內容包括：ARM處理器基礎；ARM/Thumb指令集； C與組合語言程式的設計與最佳化；基本運算、操作的最佳化；基於ARM的DSP；異常與中斷處理；韌體與嵌入式OS；Cache與記憶體管理；ARMv6 架構的特點等。全書內容完整，針對各種不同的ARM核心架構都有詳盡論述，並有大量的範例和原始程式碼。附錄部分提供了完整的 ARMv4/v5/Thumb指令的功能、編碼、時序週期，以及組合語言參考。&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt; &lt;h2&gt;&lt;font color=&quot;#000099&quot;&gt;深入了解用書&lt;/font&gt;&lt;/h2&gt; &lt;h3&gt;&lt;a id=&quot;taih&quot; title=&quot;Linux 核心詳解&quot; href=&quot;http://www.books.com.tw/exep/assp.php/mesmerli/exep/prod/booksfile.php?item=0010340529&quot; target=&quot;_blank&quot;&gt;Linux 核心詳解&lt;/a&gt; (歐萊禮)&lt;/h3&gt;&lt;h3&gt;&lt;a id=&quot;taih&quot; title=&quot;Linux 核心詳解&quot; href=&quot;http://www.books.com.tw/exep/assp.php/mesmerli/exep/prod/booksfile.php?item=0010340529&quot; target=&quot;_blank&quot;&gt;&lt;br&gt;&lt;/a&gt; &lt;/h3&gt; &lt;p&gt;&lt;img id=&quot;y841&quot; style=&quot;margin: 1em 1em 0px 0px; float: left;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_281cn5c8cd3&quot;&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt;為了全面瞭解是什麼讓 Linux 起作用，以及為什麼 Linux 能在各種系統上運作得那麼好，你必須對核心有深入的瞭解。核心會處理 CPU 和外面世界的所有互動，決定哪些行程可以共用處理器時間，以及它們的使用次序。核心把有限的記憶體管理得很好，讓上百個行程能以有效率的方式共用系統。核心以巧妙的方式安排資料的傳輸，使得 CPU 再也不用等待速度緩慢的硬碟存取。  &lt;p&gt;　　本書要帶領你瞭解，核心中最重要的資料結構、演算法以及程式設計技巧。探索核心功能背後的真相時，對那些想瞭解自己的機器究竟是怎麼運作的讀者，作者提出了寶貴的見解。本書會討論 Intel 特有的重要功能，也會逐一解析相關的程式片段。但是，本書不只談論程式的作用而已，也會說明 Linux 之所以這麼運作的理論基礎。 &lt;/p&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;h3&gt;&lt;a id=&quot;w0m6&quot; title=&quot;Linux 網路原理&quot; href=&quot;http://www.books.com.tw/exep/assp.php/mesmerli/exep/prod/booksfile.php?item=0010352972&quot; target=&quot;_blank&quot;&gt;Linux 網路原理&lt;/a&gt; (歐萊禮)&lt;/h3&gt;&lt;h3&gt; &lt;/h3&gt; &lt;p&gt;&lt;img id=&quot;vpgc&quot; style=&quot;margin: 1em 1em 0px 0px; float: left;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_28073fnnxdm&quot;&gt; &lt;/p&gt; &lt;p&gt; Linux受歡迎的部分原因是，它擁有效率高且功能豐富的網路疊層。如果你想知道Linux如何利用IP協定把複雜的任務搞定，或者只想透過真實的案例來瞭解現代網路的功能，《Linux 網路原理》就是你的指南。&lt;/p&gt; &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt; &lt;h3&gt;&lt;a id=&quot;cldk&quot; title=&quot;Linux 系統管理&quot; href=&quot;http://www.books.com.tw/exep/assp.php/mesmerli/exep/prod/booksfile.php?item=0010385380&quot; target=&quot;_blank&quot;&gt;Linux 系統管理&lt;/a&gt; (歐萊禮)&lt;/h3&gt;&lt;h3&gt; &lt;/h3&gt; &lt;p&gt;&lt;img id=&quot;wq4y&quot; style=&quot;margin: 1em 1em 0px 0px; float: left;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_282gwmjs7cr&quot;&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;　　對經驗老道、想學習Linux技巧的系統管理員，以及面對新挑戰的資深Linux用戶而言，本書提供管理各種系統和伺服器的建言。本書總結了一些必要的步驟，幫助你建立獨立式SOHO Hub、網站伺服器、LAN伺服器所組成的負載平衡叢集、以及透過虛擬化方式合併的伺服器。另外，你也會學到設立和維護這些工作環境所需的工具。  &lt;/p&gt;&lt;p&gt;　　本書可作為Unix老兵、MCSE、以及大型電腦管理員的Linux簡介，也可作為現職Linux管理員補充和提昇技巧的進階指南。在本書中，你會學到：  &lt;/p&gt;&lt;p&gt;．安裝、組態、維護、以及對DNS伺服器除錯﹙使用BIND﹚。&lt;br&gt;．為中小型公司設立電子郵件服務，並具備完整的認證機制。&lt;br&gt;．從頭開始在網站伺服器上安裝和組態Apache、PHP、以及MySQL。&lt;br&gt;．利用免費的Linux Virtual Server結合一些電腦，組成負載平衡的Apache網站伺服器叢集。&lt;br&gt;．透過Xen或VMWare運用Linux虛擬化，在一件硬體上執行多個核心；管理每個核心對處理器時間、設備、以及記憶體的存取。&lt;br&gt;．建立命令稿，按你的需求做調整。&lt;br&gt;．使用&lt;i&gt;rsync、tar、cdrecord&lt;/i&gt;、Amanda、及MySQL工具，備份和回存資料。&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;</content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/4908523310819374868/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/4908523310819374868' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/4908523310819374868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/4908523310819374868'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2007/12/armlinux-linux-linux-linux-linux-linux.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-3519138427930720403</id><published>2007-11-24T07:22:00.000+08:00</published><updated>2007-12-17T22:05:19.254+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 除錯工具篇"/><title type='text'></title><content type='html'>  &lt;h1&gt;  gprof&lt;/h1&gt;&lt;br&gt;&lt;div id=&quot;ybsq&quot; style=&quot;padding: 1em 0pt; text-align: left;&quot;&gt;&lt;img style=&quot;width: 507px; height: 449px;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_242djzkd4g4&quot;&gt;&lt;/div&gt;&lt;div id=&quot;lof5&quot; style=&quot;padding: 1em 0pt; text-align: left;&quot;&gt;&lt;img style=&quot;width: 472px; height: 561px;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_243hsmhw3c5&quot;&gt;&lt;/div&gt;gprof thread&lt;br&gt;&lt;div id=&quot;gkxr&quot; style=&quot;padding: 1em 0pt; text-align: left;&quot;&gt;&lt;div id=&quot;m.2d&quot; style=&quot;padding: 1em 0pt; text-align: left;&quot;&gt;&lt;img style=&quot;width: 470px; height: 585px;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_245hc7sqjg5&quot;&gt;&lt;/div&gt;vmstat&lt;br&gt;&lt;div id=&quot;c3is&quot; style=&quot;padding: 1em 0pt; text-align: left;&quot;&gt;&lt;img style=&quot;width: 554px; height: 243px;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_246cz3f4zfj&quot;&gt;&lt;/div&gt;&lt;br&gt;top&lt;br&gt;&lt;div id=&quot;xlvq&quot; style=&quot;padding: 1em 0pt; text-align: left;&quot;&gt;&lt;img style=&quot;width: 571px; height: 489px;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_247hb4gzqhz&quot;&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;  </content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/3519138427930720403/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/3519138427930720403' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/3519138427930720403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/3519138427930720403'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2007/11/gprof-gprof-thread-vmstat-top.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-2866910477948612659</id><published>2007-11-24T07:21:00.001+08:00</published><updated>2007-11-24T08:46:57.255+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 除錯工具篇"/><title type='text'></title><content type='html'>&lt;h1&gt;  Memory Leak&lt;/h1&gt;&lt;br&gt;Valgrind&lt;br&gt;&lt;br&gt;&lt;div id=&quot;fk74&quot; style=&quot;padding: 1em 0pt; text-align: left;&quot;&gt;&lt;img style=&quot;width: 1089px; height: 741px;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_249d2wctfdh&quot;&gt;&lt;/div&gt;mtrace&lt;br&gt;&lt;div id=&quot;x4fh&quot; style=&quot;padding: 1em 0pt; text-align: left;&quot;&gt;&lt;img style=&quot;width: 401px; height: 207px;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_250hkhjb76m&quot;&gt;&lt;/div&gt;&lt;br&gt;  </content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/2866910477948612659/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/2866910477948612659' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/2866910477948612659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/2866910477948612659'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2007/11/memory-leak-valgrind-mtrace.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-468883129149940047</id><published>2007-11-24T07:21:00.000+08:00</published><updated>2007-11-24T08:48:07.922+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 除錯工具篇"/><title type='text'></title><content type='html'>&lt;h1&gt;  Backtrace&lt;/h1&gt;&lt;br&gt;&lt;div id=&quot;ubpc&quot; style=&quot;padding: 1em 0pt; text-align: left;&quot;&gt;&lt;img style=&quot;width: 1017px; height: 322px;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_240f98xx27b&quot;&gt;&lt;/div&gt;&lt;br&gt;  </content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/468883129149940047/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/468883129149940047' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/468883129149940047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/468883129149940047'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2007/11/backtrace.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-510161556395076697</id><published>2007-11-24T07:17:00.000+08:00</published><updated>2007-11-24T08:53:02.465+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 除錯工具篇"/><title type='text'></title><content type='html'>&lt;h1&gt;  GDB advanced&lt;/h1&gt;&lt;br&gt;Debug Process&lt;br&gt;&lt;img alt=&quot;&quot;&gt;&lt;img alt=&quot;&quot;&gt;&lt;div id=&quot;ksb-&quot; style=&quot;padding: 1em 0pt; text-align: left;&quot;&gt;&lt;div id=&quot;smq.&quot; style=&quot;padding: 1em 0pt; text-align: left;&quot;&gt;&lt;img style=&quot;width: 539px; height: 280px;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_235ccwn5wfr&quot;&gt;&lt;/div&gt;&lt;br&gt;Debug Thread&lt;br&gt;&lt;div id=&quot;nl.d&quot; style=&quot;padding: 1em 0pt; text-align: left;&quot;&gt;&lt;img style=&quot;width: 547px; height: 844px;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_236dbgknkdv&quot;&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;Debug Signal&lt;br&gt;&lt;div id=&quot;j5h6&quot; style=&quot;padding: 1em 0pt; text-align: left;&quot;&gt;&lt;img style=&quot;width: 540px; height: 518px;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_237gh3zz2fj&quot;&gt;&lt;/div&gt;&lt;div id=&quot;jk1g&quot; style=&quot;padding: 1em 0pt; text-align: left;&quot;&gt;&lt;img style=&quot;width: 536px; height: 785px;&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_238d5nxg4w8&quot;&gt;&lt;/div&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;&lt;img alt=&quot;&quot;&gt;&lt;img alt=&quot;&quot;&gt;  </content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/510161556395076697/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/510161556395076697' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/510161556395076697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/510161556395076697'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2007/11/gdb-advanced-debug-process-debug-thread.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-6649228077278526034</id><published>2007-06-30T15:14:00.000+08:00</published><updated>2007-06-30T15:29:07.136+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 綜合開發篇"/><title type='text'></title><content type='html'>&lt;h1&gt;USB DISK&lt;/h1&gt;&lt;p&gt;&lt;/p&gt;&lt;div style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=d22xvwb_175ftz784hr&quot; /&gt;&lt;/div&gt;&lt;div style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;div style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=d22xvwb_176f22xmnck&quot; /&gt;&lt;/div&gt;&lt;div style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=d22xvwb_177hdv3dggd&quot; /&gt;&lt;/div&gt;&lt;div style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=d22xvwb_178gzz8w5g7&quot; /&gt;&lt;/div&gt;&lt;div style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=d22xvwb_179dfnw3dhg&quot; /&gt;&lt;/div&gt;&lt;div style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=d22xvwb_180cz76n5th&quot; /&gt;&lt;/div&gt;&lt;div style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=d22xvwb_181hk2966gt&quot; /&gt;&lt;/div&gt;&lt;div style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=d22xvwb_182d3hwv7fw&quot; /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;div style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=d22xvwb_183fhv3m5gp&quot; /&gt;&lt;/div&gt;&lt;div style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=d22xvwb_184rbkfmhgf&quot; /&gt;&lt;/div&gt;&lt;div style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;div style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=d22xvwb_187f5rcmgc3&quot; /&gt;&lt;/div&gt;&lt;div style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=d22xvwb_188g3dncbp2&quot; /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/6649228077278526034/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/6649228077278526034' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/6649228077278526034'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/6649228077278526034'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2007/06/usb-disk.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-8715061626409115267</id><published>2007-05-25T20:34:00.000+08:00</published><updated>2007-05-25T21:00:12.833+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 系統建置篇"/><title type='text'></title><content type='html'>&lt;H1&gt;Linux 系統設定檔 &lt;/H1&gt; &lt;H2&gt;inittab &lt;/H2&gt; &lt;H3&gt; /etc/inittab &lt;/H3&gt; &lt;OL&gt; &lt;LI&gt; init 的腳本  &lt;P&gt; &lt;/P&gt; &lt;LI&gt; 呼叫初始化硬體的腳本 /etc/rc.d/rc.sysinit  &lt;P&gt; &lt;/P&gt; &lt;LI&gt; 呼叫初始化系統參數的腳本 /etc/init.d/rcS  &lt;P&gt; &lt;/P&gt; &lt;LI&gt; 啟動 bash  &lt;P&gt; &lt;/P&gt;&lt;/LI&gt;&lt;/OL&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG style=&quot;WIDTH: 448px; HEIGHT: 129px&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_60dmc59fgs&quot;&gt; &lt;/DIV&gt; &lt;H3 style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;/etc/rc.d/rc.sysinit &lt;/H3&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;初始化硬體  &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG style=&quot;WIDTH: 388px; HEIGHT: 155px&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_64dnjx47gz&quot;&gt; &lt;/DIV&gt;&lt;/DIV&gt; &lt;H3 style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;/etc/rc.d/rc.modules &lt;/H3&gt; &lt;P style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;網路驅動程式在此啟動 &lt;/P&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG style=&quot;WIDTH: 503px; HEIGHT: 104px&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_62d7spr3xt&quot;&gt; &lt;/DIV&gt; &lt;P&gt; &lt;/P&gt; &lt;H3&gt;/etc/init.d/rcS &lt;/H3&gt; &lt;P&gt;初始化系統參數 &lt;/P&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG style=&quot;WIDTH: 501px; HEIGHT: 185px&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_63gh925qgz&quot;&gt; &lt;/DIV&gt; &lt;H3&gt;/etc/init.d/umountfs &lt;/H3&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG style=&quot;WIDTH: 422px; HEIGHT: 45px&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_65hd44rngk&quot;&gt; &lt;/DIV&gt; &lt;DIV&gt; &lt;TABLE cellSpacing=0 cellPadding=3 bgColor=#000000 border=0&gt; &lt;TBODY&gt; &lt;TR&gt; &lt;TD width=&quot;100%&quot;&gt;&lt;FONT color=#006600&gt; &lt;P&gt;copy kernel...OK&lt;/P&gt; &lt;P&gt;copy rootfs...OK&lt;BR&gt;Uncompressing Linux................................................ done, booting the kernel.&lt;BR&gt;Linux version 2.4.18-rmk7-swl8 (&lt;A href=&quot;mailto:root@MDS-Linux-01&quot;&gt;root@MDS-Linux-01&lt;/A&gt;) (gcc version 2.95.3 20010315 (release)) #3 三 10月 27 14:02:49 CST 24&lt;BR&gt;CPU: SAMSUNG S3C2410(Arm920T)sid(wb) revision 0&lt;BR&gt;Machine: create ARM920T-S3C2410&lt;BR&gt;On node 0 totalpages: 16384&lt;BR&gt;zone(0): 16384 pages.&lt;BR&gt;zone(1): 0 pages.&lt;BR&gt;zone(2): 0 pages.&lt;BR&gt;Kernel command line: root=/dev/ram0 console=ttyS0&lt;BR&gt;Calibrating delay loop... 101.37 BogoMIPS&lt;BR&gt;Memory: 64MB = 64MB total&lt;BR&gt;Memory: 52600KB available (1299K code, 286K data, 44K init)&lt;BR&gt;Dentry-cache hash table entries: 8192 (order: 4, 65536 bytes)&lt;BR&gt;Inode-cache hash table entries: 4096 (order: 3, 32768 bytes)&lt;BR&gt;Mount-cache hash table entries: 1024 (order: 1, 8192 bytes)&lt;BR&gt;Buffer-cache hash table entries: 4096 (order: 2, 16384 bytes)&lt;BR&gt;Page-cache hash table entries: 16384 (order: 4, 65536 bytes)&lt;BR&gt;POSIX conformance testing by UNIFIX&lt;BR&gt;Linux NET4.0 for Linux 2.4&lt;BR&gt;Based upon Swansea University Computer Society NET3.039&lt;BR&gt;Initializing RT netlink socket&lt;BR&gt;Starting kswapd&lt;BR&gt;JFFS version 1.0, (C) 1999, 2000  Axis Communications AB&lt;BR&gt;JFFS2 version 2.1. (C) 2001 Red Hat, Inc., designed by Axis Communications AB.&lt;BR&gt;l3 S3C2410 Adapter Initialized&lt;BR&gt;ttyS0 at MEM 0xe0000000 (irq = 52) is a S3C2410&lt;BR&gt;ttyS1 at MEM 0xe0004000 (irq = 55) is a S3C2410&lt;BR&gt;pty: 256 Unix98 ptys configured&lt;BR&gt;Installing S3C2410 RTC&lt;BR&gt;S3C Real Time Clock driver v1.00&lt;BR&gt;block: 128 slots per queue, batch=32&lt;BR&gt;RAMDISK driver initialized: 16 RAM disks of 8192K size 1024 blocksize&lt;BR&gt;loop: loaded (max 8 devices)&lt;BR&gt;S3C2410 UDA1341 / IIS  initialized&lt;BR&gt;usb.c: registered new driver hub&lt;BR&gt;usb-ohci.c: USB OHCI at membase 0xd9000000, IRQ 26&lt;BR&gt;usb.c: new USB bus registered, assigned bus number 1&lt;BR&gt;hub.c: USB hub found&lt;BR&gt;hub.c: 2 ports detected&lt;BR&gt;NET4: Linux TCP/IP 1.0 for NET4.0&lt;BR&gt;IP Protocols: ICMP, UDP, TCP&lt;BR&gt;IP: routing cache hash table of 512 buckets, 4Kbytes&lt;BR&gt;TCP: Hash tables configured (established 4096 bind 4096)&lt;BR&gt;NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.&lt;BR&gt;NetWinder Floating Point Emulator V0.95 (c) 1998-1999 Rebel.com&lt;BR&gt;RAMDISK: ext2 filesystem found at block 0&lt;BR&gt;RAMDISK: Loading 8192 blocks [1 disk] into ram disk... done.&lt;BR&gt;Freeing initrd memory: 10240K&lt;BR&gt;VFS: Mounted root (ext2 filesystem).&lt;BR&gt;Freeing init memory: 44K&lt;BR&gt;INIT: version 2.78 booting&lt;BR&gt;eth0: cs8900 rev K(3.3 Volts) found at 0xf0000300&lt;BR&gt;cs89x0 media RJ-45, IRQ 37&lt;BR&gt;INIT: Entering runlevel: 2&lt;BR&gt;EXT2-fs: Unrecognized mount option&lt;BR&gt;EXT2-fs: Unrecognized mount option&lt;BR&gt;mount: / not mounted already, or bad option&lt;BR&gt;Starting Network&lt;BR&gt;bash-2.04#&lt;/FONT&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/DIV&gt;&lt;BR&gt;</content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/8715061626409115267/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/8715061626409115267' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/8715061626409115267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/8715061626409115267'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2007/05/linux-inittab-etcinittab-init-etcrc.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-3075817620403215465</id><published>2007-05-19T11:02:00.000+08:00</published><updated>2007-05-20T20:47:49.991+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 應用程式篇"/><title type='text'></title><content type='html'>&lt;H1&gt;建構 Insight 6.1 &lt;/H1&gt; &lt;P&gt;V1.2 &lt;/P&gt; &lt;P&gt;&lt;A href=&quot;mailto:copyright@2006&quot;&gt;copyright@2006&lt;/A&gt; &lt;/P&gt; &lt;P&gt;email: &lt;A href=&quot;mailto:mesmerli@hotmail.com&quot;&gt;mesmerli@hotmail.com&lt;/A&gt; &lt;/P&gt; &lt;H3&gt;什麼是 Insight? &lt;/H3&gt; &lt;P&gt;本文主要介紹如何建構搭配 ARM 處理器的應用程式除錯工具。 &lt;/P&gt; &lt;P&gt;Insight 是一個可以搭配 gdbserver 的圖形化除錯工具。&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;H3&gt;建構 Insight 6.1 &lt;/H3&gt; &lt;P&gt;解壓縮 insight 6.1 所有原始碼到一個檔案夾，&lt;/P&gt; &lt;P&gt;接下來，在該檔案夾下建立以下檔案夾 &lt;/P&gt; &lt;OL&gt; &lt;LI&gt;insight-arm-linux-6.1  &lt;LI&gt;gdbserver-arm-6.1. &lt;/LI&gt;&lt;/OL&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;完畢後，檔案夾結構應如下所示: &lt;/P&gt; &lt;OL&gt; &lt;LI&gt;./gdbserver-arm-6.1 (empty)  &lt;LI&gt;./insight-6.1 (the source tree)  &lt;LI&gt;./insight-arm-linux-6.1 (empty) &lt;/LI&gt;&lt;/OL&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG style=&quot;WIDTH: 800px; HEIGHT: 540px&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_52dwbf6tgk&quot;&gt;&lt;/DIV&gt;進入 insight-arm-linux-6.1 檔案夾下使用下面的命令建構 Insight 主程式 &lt;/DIV&gt; &lt;P&gt;# cd &lt;FONT color=#000099&gt;/usr/src/creator/nfs/Day1/insight-6.1/insight-arm-linux-6.1&lt;BR&gt;&lt;/FONT&gt;# ../insight-6.1/configure --host=i686-pc-linux --target=arm-linux --prefix=/usr/local/insight-arm-6.1 --enable-sim &lt;/P&gt; &lt;P&gt;# make&lt;BR&gt;# make install &lt;/P&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG style=&quot;WIDTH: 796px; HEIGHT: 551px&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_48hfm8cspf&quot;&gt;&lt;/DIV&gt; &lt;P&gt;&lt;BR&gt;接下來，進入 gdbserver-arm-6.1 檔案夾建構 gdbserver &lt;/P&gt;&lt;FONT color=#ff0000&gt; &lt;P&gt;&lt;FONT color=#ff0000&gt;&lt;/FONT&gt; &lt;/P&gt; &lt;P&gt;&lt;FONT color=#ff0000&gt;ARM 版本須進行以下修改:&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt; &lt;P&gt;&lt;FONT color=#ff0000&gt;修改 linux-arm-low.c&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT color=#ff0000&gt;   1. vi ../insight-6.1/gdb/gdbserver/linux-arm-low.c&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT color=#ff0000&gt;   2. remark #include &amp;lt;sys/reg.h&amp;gt; in line 26&lt;/FONT&gt;&lt;/P&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG style=&quot;WIDTH: 798px; HEIGHT: 551px&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_50d38x7gm2&quot;&gt;&lt;/DIV&gt; &lt;P&gt;  &lt;/P&gt; &lt;P&gt;# ../insight-6.1/gdb/gdbserver/configure --target=arm-linux &lt;/P&gt; &lt;P&gt;&lt;FONT color=#ff0000&gt;&lt;/FONT&gt; &lt;/P&gt; &lt;P&gt;&lt;FONT color=#ff0000&gt;Note:&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT color=#ff0000&gt;修改 Make File&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT color=#ff0000&gt;    1. vi Makefile&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT color=#ff0000&gt;    2. change gcc to arm-linux-gcc in line 52&lt;/FONT&gt;&lt;/P&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG style=&quot;WIDTH: 798px; HEIGHT: 550px&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_51fs2kc7fg&quot;&gt;&lt;/DIV&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;# make &lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;  &lt;P&gt;&lt;FONT color=#000000&gt;&lt;/FONT&gt;&lt;/P&gt; &lt;H3&gt;使用Insight 與 gdbserver 除錯 &lt;/H3&gt; &lt;P&gt; &lt;/P&gt; &lt;OL&gt; &lt;LI&gt;在 gdbserver-arm-6.1 目錄夾找到 &quot;gdbserver&quot;，並把它放到您的實驗板檔案系統中。  &lt;LI&gt;重新編譯您的應用程式，並且使用 -ggdb 選項重新編譯。  &lt;LI&gt;啟動您的實驗板，並使用以下的命令在實驗板執行應用程式&lt;BR&gt;# gbdserver &amp;lt;your PC TCP/IP address&amp;gt;:&amp;lt;2345 or your port&amp;gt; &amp;lt;your program&amp;gt; &amp;lt;your arguments&amp;gt;  &lt;LI&gt;在 Host 端執行 Insight。 &lt;FONT color=#000099&gt;/usr/local/insight-arm-6.1/bin/arm-linux-insight&lt;/FONT&gt;  &lt;LI&gt;在 Insight 圖形介面，依下面說明操作 &lt;/LI&gt;&lt;/OL&gt; &lt;P&gt;    &lt;/P&gt; &lt;P&gt;在 &quot;File&quot; -&amp;gt; &quot;Target settings&quot; 選單設定以下選項 &lt;/P&gt; &lt;P&gt;Connection:&lt;BR&gt;Target: &lt;FONT color=#ff0000&gt;GDBserver&lt;/FONT&gt;/TCP&lt;BR&gt;Hostname:&lt;BR&gt;Port: 2345 (or any free port you want) &lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;展開 &quot;More options&quot;，&lt;BR&gt;Run Options:&lt;BR&gt;[x] Attach to Target&lt;BR&gt;[ ] Download program &lt;/P&gt; &lt;P&gt;Run Method:&lt;BR&gt;&amp;lt; &amp;gt; Run program&lt;BR&gt;&amp;lt;x&amp;gt;Continue from last stop &lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;在 global options 中，確認 &quot;Set breakpoint at main&quot; 被選取。&lt;/P&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG style=&quot;WIDTH: 609px; HEIGHT: 423px&quot; src=&quot;http://docs.google.com/File?id=d22xvwb_47hn47dphj&quot;&gt;&lt;/DIV&gt; &lt;OL start=6&gt; &lt;LI&gt;在 Insight選單中選擇&quot;run&quot;-&amp;gt;&quot;Run&quot;，並選擇 ARM program binary。  &lt;LI&gt;gdbserver 此時應已與 Insight 連線，所以此時可使用 Insight 除錯實驗板上的應用程式。  &lt;/LI&gt;&lt;/OL&gt; &lt;H3&gt;後記 &lt;/H3&gt; &lt;OL&gt; &lt;LI&gt;gdbserver只適合除錯應用程式，無法除錯 Linux 核心或核心模組 (Kernel Module)。  &lt;LI&gt;如不想使用圖形化介面，亦可使用 GDB 文字模式除錯。 &lt;/LI&gt;&lt;/OL&gt; &lt;P&gt; &lt;/P&gt;</content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/3075817620403215465/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/3075817620403215465' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/3075817620403215465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/3075817620403215465'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2007/05/insight-6.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-2374699066440921820</id><published>2007-05-18T07:05:00.000+08:00</published><updated>2007-06-16T13:03:31.773+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 綜合開發篇"/><title type='text'></title><content type='html'>&lt;H1&gt;串列埠控制&lt;/H1&gt; &lt;P&gt;V1.0 &lt;/P&gt; &lt;P&gt;&lt;A href=&quot;mailto:copyright@2006&quot;&gt;copyright@2006&lt;/A&gt; &lt;/P&gt; &lt;P&gt;email: &lt;A href=&quot;mailto:mesmerli@hotmail.com&quot;&gt;mesmerli@hotmail.com&lt;/A&gt;&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_147dd4fjxwn&quot;&gt;&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_149ff7xqnm9&quot;&gt;&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_150c2qqwkhn&quot;&gt;&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_151r7nz7fch&quot;&gt;&lt;/DIV&gt;&lt;/DIV&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;#include &amp;lt;stdio.h&amp;gt;&lt;BR&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;BR&gt;#include &amp;lt;unistd.h&amp;gt;&lt;BR&gt;#include &amp;lt;errno.h&amp;gt;&lt;BR&gt;#include &amp;lt;signal.h&amp;gt;&lt;BR&gt;#include &amp;lt;termios.h&amp;gt;&lt;BR&gt;#include &amp;lt;fcntl.h&amp;gt;&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;const char *com2 = &lt;EM&gt;&lt;FONT color=#ff6600&gt;&lt;STRONG&gt;&quot;/dev/ttyS1&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/EM&gt;&quot;;&lt;BR&gt;static struct &lt;FONT color=#3366ff&gt;&lt;EM&gt;&lt;STRONG&gt;termios&lt;/STRONG&gt;&lt;/EM&gt; &lt;/FONT&gt;newtios, oldtios; // terminal settings&lt;BR&gt;static int saved_portfd = -1; // serial port fd&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;// cleanup atexit handler&lt;BR&gt;static void &lt;EM&gt;&lt;FONT color=#ff6600&gt;reset_tty_atexit&lt;/FONT&gt;&lt;/EM&gt;(void)&lt;BR&gt;{&lt;BR&gt;    if(saved_portfd != -1) {&lt;BR&gt;        &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;tcsetattr&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(saved_portfd, TCSANOW, &amp;amp;oldtios);&lt;BR&gt;    }&lt;BR&gt;}&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;// cleanup signal handler&lt;BR&gt;static void &lt;EM&gt;&lt;FONT color=#ff6600&gt;reset_tty_handler&lt;/FONT&gt;&lt;/EM&gt;(int signal)&lt;BR&gt;{&lt;BR&gt;    if(saved_portfd != -1) {&lt;BR&gt;        &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;tcsetattr&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(saved_portfd, TCSANOW, &amp;amp;oldtios);&lt;BR&gt;    }&lt;BR&gt;    _exit(EXIT_FAILURE);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;static int &lt;EM&gt;&lt;FONT color=#ff6600&gt;open_port&lt;/FONT&gt;&lt;/EM&gt;(const char *portname)&lt;BR&gt;{&lt;BR&gt;    struct sigaction sa;&lt;BR&gt;    int portfd;&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;    printf(&quot;opening serial port: %sn&quot;, portname);&lt;/P&gt; &lt;P&gt;    // open serial port&lt;BR&gt;    if((portfd = open(portname, O_RDWR|O_NOCTTY)) &amp;lt; 0) {&lt;BR&gt;        printf(&quot;open serial port %s failn&quot;, portname);&lt;BR&gt;        return portfd;&lt;BR&gt;    }&lt;/P&gt; &lt;P&gt;    // get serial port parameters, save away&lt;BR&gt;    &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;tcgetattr&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(portfd, &amp;amp;newtios);&lt;BR&gt;    memcpy(&amp;amp;oldtios, &amp;amp;newtios, sizeof newtios);&lt;/P&gt; &lt;P&gt;    // configure new values&lt;BR&gt;    &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;cfmakeraw&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(&amp;amp;newtios); // see man page&lt;BR&gt;    newtios.c_iflag |= IGNPAR; // ignore parity on input&lt;BR&gt;    newtios.c_oflag &amp;amp;= ~(OPOST|ONLCR|OLCUC|OCRNL|ONOCR|ONLRET|OFILL);&lt;BR&gt;    newtios.c_cflag = CS8|CLOCAL|CREAD;&lt;BR&gt;    newtios.c_cc[VMIN] = 1; // block until 1 char received&lt;BR&gt;    newtios.c_cc[VTIME] = 0; // no inter-character timer&lt;/P&gt; &lt;P&gt;    // 115200 bps&lt;BR&gt;    &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;cfsetospeed&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(&amp;amp;newtios, B115200);&lt;BR&gt;    &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;cfsetispeed&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(&amp;amp;newtios, B115200);&lt;/P&gt; &lt;P&gt;    // register cleanup stuff&lt;BR&gt;    &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;atexit&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(&lt;FONT color=#ff6600&gt;&lt;EM&gt;reset_tty_atexit&lt;/EM&gt;&lt;/FONT&gt;);&lt;BR&gt;    memset(&amp;amp;sa, 0 , sizeof sa);&lt;BR&gt;    sa.sa_handler = &lt;EM&gt;&lt;FONT color=#ff6600&gt;reset_tty_handler&lt;/FONT&gt;&lt;/EM&gt;;&lt;BR&gt;    sigaction(SIGHUP, &amp;amp;sa, NULL);&lt;BR&gt;    sigaction(SIGINT, &amp;amp;sa, NULL);&lt;BR&gt;    sigaction(SIGPIPE, &amp;amp;sa, NULL);&lt;BR&gt;    sigaction(SIGTERM, &amp;amp;sa, NULL);&lt;/P&gt; &lt;P&gt;    // apply modified termios&lt;BR&gt;    saved_portfd = portfd;&lt;BR&gt;    &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;tcflush&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(portfd, TCIFLUSH);&lt;BR&gt;    &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;tcsetattr&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(portfd, TCSADRAIN, &amp;amp;newtios);&lt;/P&gt; &lt;P&gt;    return portfd;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;static void close_port(int portfd)&lt;BR&gt;{&lt;BR&gt;    &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;tcsetattr&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(portfd, TCSANOW, &amp;amp;oldtios);&lt;BR&gt;    close(portfd);&lt;BR&gt;    saved_portfd = -1;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;int main(int argc, char *argv[])&lt;BR&gt;{&lt;/P&gt; &lt;P&gt;    fd_set fds;&lt;BR&gt;    int portfd;&lt;BR&gt;    int retval;&lt;BR&gt;    unsigned char c;&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;    if((&lt;FONT color=#ff6600&gt;&lt;EM&gt;portfd&lt;/EM&gt; &lt;/FONT&gt;= &lt;EM&gt;&lt;FONT color=#ff6600&gt;open_port&lt;/FONT&gt;&lt;/EM&gt;(com2)) &amp;lt; 0)&lt;BR&gt;       return -1;&lt;/P&gt; &lt;P&gt;    while(1) {&lt;BR&gt;        &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;FD_ZERO&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(&amp;amp;fds);&lt;BR&gt;        &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;FD_SET&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(&lt;EM&gt;&lt;FONT color=#ff6600&gt;portfd&lt;/FONT&gt;&lt;/EM&gt;, &amp;amp;fds);&lt;/P&gt; &lt;P&gt;        retval = &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;select&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(portfd+1, &amp;amp;fds, NULL, NULL, NULL);&lt;BR&gt;        if(&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;FD_ISSET&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(portfd, &amp;amp;fds)) {&lt;BR&gt;            if(&lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;read&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(portfd, &amp;amp;c, 1) == 1)&lt;BR&gt;                &lt;FONT color=#000000&gt;putchar&lt;/FONT&gt;(c);&lt;BR&gt;        }&lt;BR&gt;        &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;fflush&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(NULL);&lt;BR&gt;    }    &lt;BR&gt;    return 0;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;H1&gt; UART driver (serial_s3c2410.c)&lt;/H1&gt; &lt;P&gt; /*&lt;BR&gt; *  linux/drivers/char/serial_mx1ads.c&lt;BR&gt; *&lt;BR&gt; *  Driver for Samsung S3C2410&#39;s internal serial ports (UART0 &amp;amp; UART1)&lt;BR&gt; *&lt;BR&gt; *  Copyright (C) 2002 Steve Hein, SGI Inc.  (&lt;A href=&quot;mailto:ssh@sgi.com&quot;&gt;ssh@sgi.com&lt;/A&gt;)&lt;BR&gt; *  Cho, Hyun-ho &amp;lt;&lt;A href=&quot;mailto:firebird@legend.co.kr&quot;&gt;firebird@legend.co.kr&lt;/A&gt;&amp;gt; corrected baudrate config.&lt;BR&gt; *&lt;BR&gt; *  Adapted from:&lt;BR&gt; *&lt;BR&gt; *  Driver for MX1s&#39; dual serial ports.&lt;BR&gt; *&lt;BR&gt; *  Based on drivers/serial/serial_amba.c&lt;BR&gt; *   &lt;BR&gt; *&lt;BR&gt; *  Copyright 1999 ARM Limited&lt;BR&gt; *  Copyright (C) 2000 Deep Blue Solutions Ltd.&lt;BR&gt; *  Copyright (C) 2002 Shane Nay (&lt;A href=&quot;mailto:shane@minirl.com&quot;&gt;shane@minirl.com&lt;/A&gt;)&lt;BR&gt; *&lt;BR&gt; * This program is free software; you can redistribute it and/or modify&lt;BR&gt; * it under the terms of the GNU General Public License as published by&lt;BR&gt; * the Free Software Foundation; either version 2 of the License, or&lt;BR&gt; * (at your option) any later version.&lt;BR&gt; *&lt;BR&gt; * This program is distributed in the hope that it will be useful,&lt;BR&gt; * but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;BR&gt; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;BR&gt; * GNU General Public License for more details.&lt;BR&gt; *&lt;BR&gt; * You should have received a copy of the GNU General Public License&lt;BR&gt; * along with this program; if not, write to the Free Software&lt;BR&gt; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA&lt;BR&gt; *&lt;BR&gt; *&lt;BR&gt; * Based on the AMBA driver, this is a driver for the S3C2410 boards&lt;BR&gt; * UARTs.  &lt;BR&gt; */&lt;BR&gt;#include &amp;lt;linux/config.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/module.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/errno.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/signal.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/sched.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/interrupt.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/tty.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/tty_flip.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/major.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/string.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/fcntl.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/ptrace.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/ioport.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/mm.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/slab.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/init.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/circ_buf.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/serial.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/console.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/sysrq.h&amp;gt;&lt;/P&gt; &lt;P&gt;#include &amp;lt;asm/system.h&amp;gt;&lt;BR&gt;#include &amp;lt;asm/io.h&amp;gt;&lt;BR&gt;#include &amp;lt;asm/irq.h&amp;gt;&lt;BR&gt;#include &amp;lt;asm/uaccess.h&amp;gt;&lt;BR&gt;#include &amp;lt;asm/bitops.h&amp;gt;&lt;/P&gt; &lt;P&gt;#if defined(CONFIG_SERIAL_S3C2410_CONSOLE) &amp;amp;&amp;amp; defined(CONFIG_MAGIC_SYSRQ)&lt;BR&gt;#define SUPPORT_SYSRQ&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt;#include &amp;lt;linux/serial_core.h&amp;gt;&lt;/P&gt; &lt;P&gt;#include &amp;lt;asm/hardware/serial_s3c2410.h&amp;gt;&lt;/P&gt; &lt;P&gt;#define UART_NR  2&lt;/P&gt; &lt;P&gt;#define MINOR_START  64&lt;/P&gt; &lt;P&gt;#define SERIAL_S3C2410_NAME &quot;ttyS&quot;&lt;BR&gt;#define SERIAL_S3C2410_MAJOR TTY_MAJOR&lt;BR&gt;#define SERIAL_S3C2410_MINOR MINOR_START&lt;BR&gt;#define SERIAL_S3C2410_NR UART_NR&lt;/P&gt; &lt;P&gt;#define CALLOUT_S3C2410_NAME &quot;cuas&quot;&lt;BR&gt;#define CALLOUT_S3C2410_MAJOR 205&lt;BR&gt;#define CALLOUT_S3C2410_MINOR MINOR_START&lt;BR&gt;#define CALLOUT_S3C2410_NR UART_NR&lt;/P&gt; &lt;P&gt;&lt;BR&gt;static struct tty_driver normal, callout;&lt;BR&gt;static struct tty_struct *s3c2410_table[UART_NR];&lt;BR&gt;static struct termios *s3c2410_termios[UART_NR], *s3c2410_termios_locked[UART_NR];&lt;BR&gt;#ifdef SUPPORT_SYSRQ&lt;BR&gt;static struct console s3c2410_console;&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt;#define S3C2410_ISR_PASS_LIMIT 256&lt;/P&gt; &lt;P&gt;/*&lt;BR&gt; * Access macros for the S3C2410 UARTs&lt;BR&gt; */&lt;/P&gt; &lt;P&gt;#define UART_GET_CHAR(p) __raw_readb((p)-&amp;gt;membase + S3C2410_UARTRXH0_OFF)&lt;BR&gt;#define UART_PUT_CHAR(p,c) __raw_writeb((c), (p)-&amp;gt;membase + S3C2410_UARTTXH0_OFF)&lt;/P&gt; &lt;P&gt;#define UART_GET_ULCON(p)       __raw_readl((p)-&amp;gt;membase + S3C2410_UARTLCON_OFF)&lt;BR&gt;#define UART_GET_UCON(p)        __raw_readl((p)-&amp;gt;membase + S3C2410_UARTCON_OFF)&lt;BR&gt;#define UART_GET_UFCON(p)       __raw_readl((p)-&amp;gt;membase + S3C2410_UARTFCON_OFF)&lt;BR&gt;#define UART_GET_UMCON(p)       __raw_readl((p)-&amp;gt;membase + S3C2410_UARTMCON_OFF)&lt;BR&gt;#define UART_GET_UBRDIV(p)      __raw_readl((p)-&amp;gt;membase + S3C2410_UARTBRDIV_OFF)&lt;/P&gt; &lt;P&gt;#define UART_GET_UTRSTAT(p)    __raw_readl((p)-&amp;gt;membase + S3C2410_UARTTRSTAT_OFF)&lt;BR&gt;#define UART_GET_UERSTAT(p)     __raw_readl((p)-&amp;gt;membase + S3C2410_UARTERSTAT_OFF)&lt;BR&gt;#define UART_GET_UFSTAT(p)      __raw_readl((p)-&amp;gt;membase + S3C2410_UARTFSTAT_OFF)&lt;BR&gt;#define UART_GET_UMSTAT(p)      __raw_readl((p)-&amp;gt;membase + S3C2410_UARTMSTAT_OFF)&lt;/P&gt; &lt;P&gt;#define UART_PUT_ULCON(p,c)     __raw_writel(c, (p)-&amp;gt;membase + S3C2410_UARTLCON_OFF)&lt;BR&gt;#define UART_PUT_UCON(p,c)      __raw_writel(c, (p)-&amp;gt;membase + S3C2410_UARTCON_OFF)&lt;BR&gt;#define UART_PUT_UFCON(p,c)     __raw_writel(c, (p)-&amp;gt;membase + S3C2410_UARTFCON_OFF)&lt;BR&gt;#define UART_PUT_UMCON(p,c)     __raw_writel(c, (p)-&amp;gt;membase + S3C2410_UARTMCON_OFF)&lt;BR&gt;#define UART_PUT_UBRDIV(p,c)    __raw_writel(c, (p)-&amp;gt;membase + S3C2410_UARTBRDIV_OFF)&lt;/P&gt; &lt;P&gt;&lt;BR&gt;/* When using the integer divisor for the UART,&lt;BR&gt; * we must set the IR to 0xf prior to programming&lt;BR&gt; * the divisor&lt;BR&gt; */&lt;/P&gt; &lt;P&gt;&lt;BR&gt;#define UART_RX_DATA(s)  (((s) &amp;amp; S3C2410_UTRSTAT_RXDR) == S3C2410_UTRSTAT_RXDR)&lt;BR&gt;#define UART_TX_READY(s) (((s) &amp;amp; S3C2410_UTRSTAT_TXFE) == S3C2410_UTRSTAT_TXFE)&lt;BR&gt;#define TX_FIFOCOUNT(port)      (((UART_GET_UFSTAT(port))&amp;gt;&amp;gt;4)&amp;amp;0xf)&lt;/P&gt; &lt;P&gt;#define TX_IRQ(port)            (port-&amp;gt;irq + 1)&lt;BR&gt;#define RX_IRQ(port)            (port-&amp;gt;irq)&lt;/P&gt; &lt;P&gt;#define UART_DUMMY_RSR_RX 256&lt;BR&gt;#define UART_PORT_SIZE  64&lt;/P&gt; &lt;P&gt;/*&lt;BR&gt; * Our private driver data mappings.&lt;BR&gt; */&lt;/P&gt; &lt;P&gt;#define drv_old_status driver_priv&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_stop_tx&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_port *port, u_int from_tty)&lt;BR&gt;{&lt;BR&gt; disable_irq(TX_IRQ(port));&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_start_tx&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_port *port, u_int nonempty, u_int from_tty)&lt;BR&gt;{&lt;BR&gt; if (nonempty) {&lt;BR&gt;  enable_irq(TX_IRQ(port));&lt;BR&gt; }&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_stop_rx&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_port *port)&lt;BR&gt;{&lt;BR&gt; disable_irq(RX_IRQ(port));&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_enable_ms&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_port *port)&lt;BR&gt;{&lt;BR&gt; /* What is MS? */&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;#ifdef SUPPORT_SYSRQ&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_rx_chars&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_info *info, struct pt_regs *regs)&lt;BR&gt;#else&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_rx_chars&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_info *info)&lt;BR&gt;#endif&lt;BR&gt;{&lt;BR&gt; struct tty_struct *tty = info-&amp;gt;tty;&lt;BR&gt; unsigned int status, ch, max_count = 256;&lt;BR&gt; struct uart_port *port = info-&amp;gt;port;&lt;BR&gt; &lt;/P&gt; &lt;P&gt; status = UART_GET_UTRSTAT(port);&lt;BR&gt; while (UART_RX_DATA(status) &amp;amp;&amp;amp; max_count--) {&lt;BR&gt;  if (tty-&amp;gt;flip.count &amp;gt;= TTY_FLIPBUF_SIZE) {&lt;BR&gt;   tty-&amp;gt;flip.tqueue.routine((void *) tty);&lt;BR&gt;   if (tty-&amp;gt;flip.count &amp;gt;= TTY_FLIPBUF_SIZE) {&lt;BR&gt;    printk(KERN_WARNING &quot;TTY_DONT_FLIP setn&quot;);&lt;BR&gt;    return;&lt;BR&gt;   }&lt;BR&gt;  }&lt;/P&gt; &lt;P&gt;  ch = UART_GET_CHAR(port);&lt;/P&gt; &lt;P&gt;  *tty-&amp;gt;flip.char_buf_ptr = ch;&lt;BR&gt;  *tty-&amp;gt;flip.flag_buf_ptr = TTY_NORMAL;&lt;BR&gt;  port-&amp;gt;icount.rx++;&lt;BR&gt;  tty-&amp;gt;flip.flag_buf_ptr++;&lt;BR&gt;  tty-&amp;gt;flip.char_buf_ptr++;&lt;BR&gt;  tty-&amp;gt;flip.count++;&lt;BR&gt;  /* No error handling just yet.&lt;BR&gt;   * On the MX1 these are seperate&lt;BR&gt;   * IRQs, so we need to deal with&lt;BR&gt;   * the sanity of 5 IRQs for one&lt;BR&gt;   * serial port before we deal&lt;BR&gt;   * with the error path properly.&lt;BR&gt;   */&lt;BR&gt;  status = UART_GET_UTRSTAT(port);&lt;BR&gt; }&lt;BR&gt; tty_flip_buffer_push(tty);&lt;BR&gt; return;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_tx_chars&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_info *info)&lt;BR&gt;{&lt;BR&gt; struct uart_port *port = info-&amp;gt;port;&lt;BR&gt; int count;&lt;/P&gt; &lt;P&gt; if (port-&amp;gt;x_char) {&lt;BR&gt;  UART_PUT_CHAR(port, port-&amp;gt;x_char);&lt;BR&gt;  port-&amp;gt;icount.tx++;&lt;BR&gt;  port-&amp;gt;x_char = 0;&lt;BR&gt;  return;&lt;BR&gt; }&lt;BR&gt; if (info-&amp;gt;xmit.head == info-&amp;gt;xmit.tail&lt;BR&gt;     || info-&amp;gt;tty-&amp;gt;stopped || info-&amp;gt;tty-&amp;gt;hw_stopped) {&lt;BR&gt;  s3c2410uart_stop_tx(port, 0);&lt;BR&gt;  return;&lt;BR&gt; }&lt;/P&gt; &lt;P&gt; count = port-&amp;gt;fifosize - TX_FIFOCOUNT(port);&lt;BR&gt; do {&lt;BR&gt;  UART_PUT_CHAR(port, info-&amp;gt;xmit.buf[info-&amp;gt;xmit.tail]);&lt;BR&gt;  info-&amp;gt;xmit.tail = (info-&amp;gt;xmit.tail + 1) &amp;amp; (UART_XMIT_SIZE - 1);&lt;BR&gt;  port-&amp;gt;icount.tx++;&lt;BR&gt;  if (info-&amp;gt;xmit.head == info-&amp;gt;xmit.tail)&lt;BR&gt;   break;&lt;BR&gt; } while (--count &amp;gt; 0);&lt;/P&gt; &lt;P&gt; if (CIRC_CNT(info-&amp;gt;xmit.head, info-&amp;gt;xmit.tail, UART_XMIT_SIZE) &amp;lt;&lt;BR&gt;     WAKEUP_CHARS)&lt;BR&gt;  uart_event(info, EVT_WRITE_WAKEUP);&lt;/P&gt; &lt;P&gt; if (info-&amp;gt;xmit.head == info-&amp;gt;xmit.tail)&lt;BR&gt;  s3c2410uart_stop_tx(info-&amp;gt;port, 0);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_modem_status&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_info *info)&lt;BR&gt;{&lt;BR&gt; /*&lt;BR&gt;  * Not currently supported.&lt;BR&gt;  *&lt;BR&gt;  */&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_int&lt;/FONT&gt;&lt;/STRONG&gt;(int irq, void *dev_id, struct pt_regs *regs)&lt;BR&gt;{&lt;BR&gt; struct uart_info *info = dev_id;&lt;BR&gt; unsigned int status;&lt;BR&gt; status = UART_GET_UTRSTAT(info-&amp;gt;port);&lt;BR&gt; if(irq==(TX_IRQ(info-&amp;gt;port))) {&lt;BR&gt;  if (UART_TX_READY(status))&lt;BR&gt;   s3c2410uart_tx_chars(info);&lt;BR&gt; }&lt;BR&gt; &lt;BR&gt; if (UART_RX_DATA(status)) {&lt;BR&gt;#ifdef SUPPORT_SYSRQ&lt;BR&gt;  s3c2410uart_rx_chars(info, regs);&lt;BR&gt;#else&lt;BR&gt;  s3c2410uart_rx_chars(info);&lt;BR&gt;#endif&lt;BR&gt; }&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static u_int&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_tx_empty&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_port *port)&lt;BR&gt;{&lt;BR&gt; return UART_GET_UTRSTAT(port) &amp;amp; S3C2410_UTRSTAT_TXFE ? TIOCSER_TEMT : 0;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static u_int&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_get_mctrl&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_port *port)&lt;BR&gt;{&lt;BR&gt; /* Not currently supported */&lt;BR&gt; return 0;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_set_mctrl&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_port *port, u_int mctrl)&lt;BR&gt;{&lt;BR&gt; /* Not currently supported */&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_break_ctl&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_port *port, int break_state)&lt;BR&gt;{&lt;BR&gt; unsigned long ucon=UART_GET_UCON(port);&lt;BR&gt; if (break_state==-1)&lt;BR&gt;     ucon |= S3C2410_UCON_SBREAK;&lt;BR&gt; else&lt;BR&gt;     ucon &amp;amp;= ~S3C2410_UCON_SBREAK;&lt;BR&gt; UART_PUT_UCON(port,ucon);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static int&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_startup&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_port *port, struct uart_info *info)&lt;BR&gt;{&lt;/P&gt; &lt;P&gt; int retval;&lt;BR&gt; /*&lt;BR&gt;  * Allocate the IRQ&lt;BR&gt;  */&lt;BR&gt; retval = request_irq(RX_IRQ(port), s3c2410uart_int, 0, &quot;s3c2410uarx&quot;, info);&lt;BR&gt; if (retval)&lt;BR&gt;  return retval;&lt;BR&gt; retval = request_irq(TX_IRQ(port), s3c2410uart_int, 0, &quot;s3c2410uatx&quot;, info);&lt;BR&gt; if (retval)&lt;BR&gt;  return retval;&lt;BR&gt; &lt;BR&gt; UART_PUT_UCON(port, S3C2410_UCON_DEFAULT);&lt;BR&gt; UART_PUT_UFCON(port, S3C2410_UFCON_DEFAULT);&lt;BR&gt; UART_PUT_UMCON(port, 0);&lt;BR&gt;       &lt;BR&gt;     /* printk(&quot;PORT 0x%08X ULCON 0x%08X UCON 0x%08X UFCON 0x%08X UMCON 0x%08X n&quot;,&lt;BR&gt; port-&amp;gt;membase, UART_GET_ULCON(port), UART_GET_UCON(port),&lt;BR&gt; UART_GET_UFCON(port), UART_GET_UMCON(port)); &lt;BR&gt;     */&lt;/P&gt; &lt;P&gt;// UART_PUT_UBRDIV(port,(int)(PCLK/CURRENT_BAUD_RATE*16))-1);&lt;BR&gt; return 0;&lt;/P&gt; &lt;P&gt;}&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_shutdown&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_port *port, struct uart_info *info)&lt;BR&gt;{&lt;BR&gt; /*&lt;BR&gt;  * Free the interrupt&lt;BR&gt;  */&lt;/P&gt; &lt;P&gt; free_irq(RX_IRQ(port), info);&lt;BR&gt; free_irq(TX_IRQ(port), info);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_change_speed&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_port *port, u_int cflag, u_int iflag,&lt;BR&gt;   u_int quot)&lt;BR&gt;{&lt;BR&gt; unsigned long flags, lcon;&lt;BR&gt;#if DEBUG&lt;BR&gt; printk(&quot;s3c2410uart_set_cflag(0x%x) calledn&quot;, cflag);&lt;BR&gt;#endif&lt;BR&gt; /* first, disable everything */&lt;BR&gt; save_flags(flags);&lt;BR&gt; cli();&lt;BR&gt; lcon=UART_GET_ULCON(port);&lt;BR&gt; /* Clear the bits we&#39;re going to configure */&lt;BR&gt; lcon &amp;amp;= ~(S3C2410_LCON_CFGMASK);&lt;BR&gt; &lt;BR&gt; switch (cflag &amp;amp; CSIZE) {&lt;BR&gt; case CS5:&lt;BR&gt;  lcon |= S3C2410_LCON_CS5;&lt;BR&gt;  break;&lt;BR&gt; case CS6:&lt;BR&gt;  lcon |= S3C2410_LCON_CS6;&lt;BR&gt;  break;&lt;BR&gt; case CS7:&lt;BR&gt;  lcon |= S3C2410_LCON_CS7;&lt;BR&gt;  break;&lt;BR&gt; default:&lt;BR&gt;  lcon |= S3C2410_LCON_CS8;&lt;BR&gt;  break;&lt;BR&gt; }&lt;BR&gt; if(cflag &amp;amp; CSTOPB) {&lt;BR&gt;     lcon |= S3C2410_LCON_STOP;&lt;BR&gt; }&lt;BR&gt; if(cflag &amp;amp; PARENB) {&lt;BR&gt;  lcon |= (cflag &amp;amp; PARODD)? S3C2410_LCON_PODD:S3C2410_LCON_PEVEN;&lt;BR&gt; } else {&lt;BR&gt;  lcon |= S3C2410_LCON_PNONE;&lt;BR&gt; }&lt;/P&gt; &lt;P&gt; UART_PUT_ULCON(port, lcon);&lt;BR&gt; if(iflag &amp;amp; BRKINT) {&lt;BR&gt;  unsigned long ucon=UART_GET_UCON(port);&lt;BR&gt;  ucon |= S3C2410_UCON_SBREAK;&lt;BR&gt;  UART_PUT_UCON(port, ucon);&lt;BR&gt; }&lt;/P&gt; &lt;P&gt; UART_PUT_UBRDIV(port, quot);&lt;BR&gt; restore_flags(flags);&lt;/P&gt; &lt;P&gt;}&lt;/P&gt; &lt;P&gt;static const char *&lt;BR&gt;s3c2410uart_type(struct uart_port *port)&lt;BR&gt;{&lt;BR&gt; return port-&amp;gt;type == PORT_S3C2410 ? &quot;S3C2410&quot; : NULL;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;/*&lt;BR&gt; * Release the memory region(s) being used by &#39;port&#39;.&lt;BR&gt; */&lt;BR&gt;static void&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_release_port&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_port *port)&lt;BR&gt;{&lt;BR&gt; return;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;/*&lt;BR&gt; * Request the memory region(s) being used by &#39;port&#39;.&lt;BR&gt; */&lt;BR&gt;static int&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_request_port&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_port *port)&lt;BR&gt;{&lt;BR&gt; return 0;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;/*&lt;BR&gt; * Configure/autoconfigure the port.&lt;BR&gt; */&lt;BR&gt;static void&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_config_port&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_port *port, int flags)&lt;BR&gt;{&lt;BR&gt; if (flags &amp;amp; UART_CONFIG_TYPE &amp;amp;&amp;amp; s3c2410uart_request_port(port) == 0)&lt;BR&gt;  port-&amp;gt;type = PORT_S3C2410;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static int&lt;BR&gt;&lt;FONT color=#ff6600&gt;&lt;STRONG&gt;s3c2410uart_verify_port&lt;/STRONG&gt;&lt;/FONT&gt;(struct uart_port *port, struct serial_struct *ser)&lt;BR&gt;{&lt;BR&gt; return 0;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static struct &lt;FONT color=#ff6600&gt;&lt;STRONG&gt;uart_ops s3c2410_pops &lt;/STRONG&gt;&lt;/FONT&gt;= {&lt;BR&gt; tx_empty: s3c2410uart_tx_empty,&lt;BR&gt; set_mctrl: s3c2410uart_set_mctrl,&lt;BR&gt; get_mctrl: s3c2410uart_get_mctrl,&lt;BR&gt; stop_tx: s3c2410uart_stop_tx,&lt;BR&gt; start_tx: s3c2410uart_start_tx,&lt;BR&gt; stop_rx: s3c2410uart_stop_rx,&lt;BR&gt; enable_ms: s3c2410uart_enable_ms,&lt;BR&gt; break_ctl: s3c2410uart_break_ctl,&lt;BR&gt; startup: s3c2410uart_startup,&lt;BR&gt; shutdown: s3c2410uart_shutdown,&lt;BR&gt; change_speed: s3c2410uart_change_speed,&lt;BR&gt; type:  s3c2410uart_type,&lt;BR&gt; release_port: s3c2410uart_release_port,&lt;BR&gt; request_port: s3c2410uart_request_port,&lt;BR&gt; config_port: s3c2410uart_config_port,&lt;BR&gt; verify_port: s3c2410uart_verify_port,&lt;BR&gt;};&lt;/P&gt; &lt;P&gt;static struct &lt;STRONG&gt;&lt;FONT color=#ff6600&gt;uart_port s3c2410_ports&lt;/FONT&gt;&lt;/STRONG&gt;[UART_NR] = {&lt;BR&gt; {&lt;BR&gt;       membase: (void *) VA_UART_BASE,&lt;BR&gt;       mapbase: VA_UART_BASE,&lt;BR&gt;       iotype: SERIAL_IO_MEM,&lt;BR&gt;       irq: IRQ_RXD0,&lt;BR&gt;       uartclk: PCLK,&lt;BR&gt;       fifosize: 16,&lt;BR&gt;       unused: {4, 5}, &lt;BR&gt;       ops: &amp;amp;s3c2410_pops,&lt;BR&gt;       type: PORT_S3C2410,&lt;BR&gt;       flags: ASYNC_BOOT_AUTOCONF,&lt;BR&gt;  },&lt;BR&gt; {&lt;BR&gt;       membase: (void *) (VA_UART_BASE + S3C2410_UART1_OFF),&lt;BR&gt;       mapbase: (VA_UART_BASE + S3C2410_UART1_OFF),&lt;BR&gt;       iotype: SERIAL_IO_MEM,&lt;BR&gt;       irq: IRQ_RXD1,&lt;BR&gt;       uartclk: PCLK,&lt;BR&gt;       fifosize: 16,&lt;BR&gt;       unused: {6, 7},&lt;BR&gt;       ops: &amp;amp;s3c2410_pops,&lt;BR&gt;       type: PORT_S3C2410,&lt;BR&gt;       flags: ASYNC_BOOT_AUTOCONF,&lt;BR&gt;  }&lt;BR&gt;};&lt;/P&gt; &lt;P&gt;#ifdef &lt;FONT color=#6600cc&gt;CONFIG_SERIAL_S3C2410_CONSOLE&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;#ifdef used_and_not_const_char_pointer&lt;BR&gt;static int&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_console_read&lt;/FONT&gt;&lt;/STRONG&gt;(struct uart_port *port, char *s, u_int count)&lt;BR&gt;{&lt;BR&gt; unsigned int status;&lt;BR&gt; int c;&lt;/P&gt; &lt;P&gt;#if DEBUG&lt;BR&gt; printk(&quot;s3c2410uart_console_read() calledn&quot;);&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt; c = 0;&lt;BR&gt; while (c &amp;lt; count) {&lt;BR&gt;  status = UART_GET_USR2(port);&lt;BR&gt;  if (UART_RX_DATA(status)) {&lt;BR&gt;   *s++ = UART_GET_CHAR(port);&lt;BR&gt;   c++;&lt;BR&gt;  } else {&lt;BR&gt;   // nothing more to get, return&lt;BR&gt;   return c;&lt;BR&gt;  }&lt;BR&gt; }&lt;BR&gt; // return the count&lt;BR&gt; return c;&lt;BR&gt;}&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt;&lt;BR&gt;static void&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_console_write&lt;/FONT&gt;&lt;/STRONG&gt;(struct console *co, const char *s, u_int count)&lt;BR&gt;{&lt;BR&gt; struct uart_port *port = s3c2410_ports + co-&amp;gt;index;&lt;BR&gt; unsigned int status;&lt;BR&gt; int i;&lt;BR&gt; /*&lt;BR&gt;  *      Now, do each character&lt;BR&gt;  */&lt;BR&gt; for (i = 0; i &amp;lt; count; i++) {&lt;BR&gt;  do {&lt;BR&gt;   status = UART_GET_UTRSTAT(port);&lt;BR&gt;  } while (!UART_TX_READY(status));&lt;BR&gt;  UART_PUT_CHAR(port, (s[i]) &amp;amp; 0xff);&lt;BR&gt;  if (s[i] == &#39;n&#39;) {&lt;BR&gt;   do {&lt;BR&gt;    status = UART_GET_UTRSTAT(port);&lt;BR&gt;   } while (!UART_TX_READY(status));&lt;BR&gt;   UART_PUT_CHAR(port, &#39;r&#39;);&lt;BR&gt;  }&lt;BR&gt; }&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static kdev_t&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_console_device&lt;/FONT&gt;&lt;/STRONG&gt;(struct console *co)&lt;BR&gt;{&lt;/P&gt; &lt;P&gt; return MKDEV(SERIAL_S3C2410_MAJOR, SERIAL_S3C2410_MINOR + co-&amp;gt;index);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static int&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_console_wait_key&lt;/FONT&gt;&lt;/STRONG&gt;(struct console *co)&lt;BR&gt;{&lt;BR&gt; struct uart_port *port = s3c2410_ports + co-&amp;gt;index;&lt;BR&gt; unsigned int status;&lt;/P&gt; &lt;P&gt; do {&lt;BR&gt;  status = UART_GET_UTRSTAT(port);&lt;BR&gt; } while (!UART_RX_DATA(status));&lt;BR&gt; return UART_GET_CHAR(port);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void &lt;FONT color=#000099&gt;&lt;EM&gt;&lt;STRONG&gt;__init&lt;/STRONG&gt;&lt;/EM&gt;&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#ff6600&gt;&lt;STRONG&gt;s3c2410uart_console_get_options&lt;/STRONG&gt;&lt;/FONT&gt;(struct uart_port *port, int *baud, int *parity,&lt;BR&gt;          int *bits)&lt;BR&gt;{&lt;BR&gt;#if 0&lt;BR&gt; *baud = (7833600)/(UART_GET_LCR(port) +1);&lt;BR&gt;#else&lt;BR&gt; *baud = CURRENT_BAUD_RATE;&lt;BR&gt; &lt;BR&gt;#endif&lt;BR&gt; *bits = 8;&lt;BR&gt; *parity = &#39;n&#39;;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static int &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#000099&gt;__init&lt;BR&gt;&lt;/FONT&gt;&lt;/EM&gt;&lt;FONT color=#ff6600&gt;s3c2410uart_console_setup&lt;/FONT&gt;&lt;/STRONG&gt;(struct console *co, char *options)&lt;BR&gt;{&lt;BR&gt; struct uart_port *port;&lt;BR&gt; int baud = CURRENT_BAUD_RATE;&lt;BR&gt; int bits = 8;&lt;BR&gt; int parity = &#39;n&#39;;&lt;BR&gt; int flow = &#39;n&#39;;&lt;/P&gt; &lt;P&gt; /*&lt;BR&gt;  * Check whether an invalid uart number has been specified, and&lt;BR&gt;  * if so, search for the first available port that does have&lt;BR&gt;  * console support.&lt;BR&gt;  */&lt;BR&gt; port = uart_get_console(s3c2410_ports, UART_NR, co);&lt;/P&gt; &lt;P&gt; if (options)&lt;BR&gt;  uart_parse_options(options, &amp;amp;baud, &amp;amp;parity, &amp;amp;bits, &amp;amp;flow);&lt;BR&gt; else&lt;BR&gt;  s3c2410uart_console_get_options(port, &amp;amp;baud, &amp;amp;parity, &amp;amp;bits);&lt;/P&gt; &lt;P&gt; return uart_set_options(port, co, baud, parity, bits, flow);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;&lt;FONT color=#000099&gt;static struct console s3c2410_console = {&lt;BR&gt; &lt;STRONG&gt;name&lt;/STRONG&gt;:  SERIAL_S3C2410_NAME,&lt;BR&gt; &lt;STRONG&gt;write&lt;/STRONG&gt;:  s3c2410uart_console_write,&lt;BR&gt;#ifdef used_and_not_const_char_pointer&lt;BR&gt; &lt;STRONG&gt;read&lt;/STRONG&gt;:  s3c2410uart_console_read,&lt;BR&gt;#endif&lt;BR&gt; &lt;STRONG&gt;device&lt;/STRONG&gt;:  s3c2410uart_console_device,&lt;BR&gt; &lt;STRONG&gt;wait_key&lt;/STRONG&gt;: s3c2410uart_console_wait_key,&lt;BR&gt; &lt;STRONG&gt;setup&lt;/STRONG&gt;:  s3c2410uart_console_setup,&lt;BR&gt; &lt;STRONG&gt;flags&lt;/STRONG&gt;:  CON_PRINTBUFFER,&lt;BR&gt; &lt;STRONG&gt;index&lt;/STRONG&gt;:  -1,&lt;BR&gt;};&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;void &lt;FONT color=#000099&gt;&lt;EM&gt;&lt;STRONG&gt;__init&lt;/STRONG&gt;&lt;/EM&gt;&lt;/FONT&gt;&lt;BR&gt;s3c2410uart_console_init(void)&lt;BR&gt;{&lt;BR&gt; &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#000099&gt;register_console&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(&amp;amp;s3c2410_console);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;#define S3C2410_CONSOLE &amp;amp;s3c2410_console&lt;BR&gt;#else&lt;BR&gt;#define S3C2410_CONSOLE NULL&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt;static struct uart_driver s3c2410_reg = {&lt;BR&gt; owner:  THIS_MODULE,&lt;BR&gt; normal_major: SERIAL_S3C2410_MAJOR,&lt;BR&gt;#ifdef CONFIG_DEVFS_FS&lt;BR&gt; normal_name: SERIAL_S3C2410_NAME &quot;%d&quot;,&lt;BR&gt; callout_name: CALLOUT_S3C2410_NAME &quot;%d&quot;,&lt;BR&gt;#else&lt;BR&gt; normal_name: SERIAL_S3C2410_NAME,&lt;BR&gt; callout_name: CALLOUT_S3C2410_NAME,&lt;BR&gt;#endif&lt;BR&gt; normal_driver :&amp;amp;normal,&lt;BR&gt; callout_major: CALLOUT_S3C2410_MAJOR,&lt;BR&gt; callout_driver: &amp;amp;callout,&lt;BR&gt; table:  s3c2410_table,&lt;BR&gt; termios: s3c2410_termios,&lt;BR&gt; termios_locked: s3c2410_termios_locked,&lt;BR&gt; minor:  SERIAL_S3C2410_MINOR,&lt;BR&gt; nr:  UART_NR,&lt;BR&gt; port:  s3c2410_ports,&lt;BR&gt; cons:  S3C2410_CONSOLE,&lt;BR&gt;};&lt;/P&gt; &lt;P&gt;static int __init&lt;BR&gt;s3c2410uart_init(void)&lt;BR&gt;{&lt;BR&gt; return &lt;FONT color=#000099&gt;&lt;STRONG&gt;&lt;EM&gt;uart_register_driver&lt;/EM&gt;&lt;/STRONG&gt;&lt;/FONT&gt;(&amp;amp;s3c2410_reg);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void __exit&lt;BR&gt;s3c2410uart_exit(void)&lt;BR&gt;{&lt;BR&gt; &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#000099&gt;uart_unregister_driver&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(&amp;amp;s3c2410_reg);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;module_init(s3c2410uart_init);&lt;BR&gt;module_exit(s3c2410uart_exit);&lt;/P&gt; &lt;P&gt;EXPORT_NO_SYMBOLS;&lt;/P&gt; &lt;P&gt;MODULE_AUTHOR(&quot;Steve Hein &amp;lt;&lt;A href=&quot;mailto:ssh@sgi.com&quot;&gt;ssh@sgi.com&lt;/A&gt;&amp;gt;&quot;);&lt;BR&gt;MODULE_DESCRIPTION(&quot;Samsung S3C2410X01 serial port driver&quot;);&lt;BR&gt;MODULE_LICENSE(&quot;GPL&quot;);&lt;BR&gt;&lt;/P&gt;</content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/2374699066440921820/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/2374699066440921820' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/2374699066440921820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/2374699066440921820'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2007/05/v1_17.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-7397417389641063561</id><published>2007-05-17T22:43:00.001+08:00</published><updated>2007-05-17T22:47:05.395+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 網路程式篇"/><title type='text'></title><content type='html'>&lt;H1&gt;Network Core&lt;/H1&gt; &lt;H3&gt;/linux/drivers/block/genhd.c&lt;/H3&gt; &lt;P&gt;int __init device_init(void)&lt;BR&gt;{&lt;BR&gt; rwlock_init(&amp;amp;gendisk_lock);&lt;BR&gt;&lt;FONT color=#000000&gt; blk_dev_init();&lt;BR&gt;&lt;/FONT&gt; sti();&lt;BR&gt;#ifdef CONFIG_I2O&lt;BR&gt; i2o_init();&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_FUSION_BOOT&lt;BR&gt; fusion_init();&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_FC4_SOC&lt;BR&gt; /* This has to be done before scsi_dev_init */&lt;BR&gt; soc_probe();&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_BLK_CPQ_DA&lt;BR&gt; cpqarray_init();&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_NET&lt;BR&gt;&lt;FONT color=#ff0000&gt;&lt;STRONG&gt; net_dev_init();&lt;/STRONG&gt;&lt;BR&gt;&lt;/FONT&gt;#endif&lt;BR&gt;#ifdef CONFIG_ATM&lt;BR&gt; (void) atmdev_init();&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_VT&lt;BR&gt; console_map_init();&lt;BR&gt;#endif&lt;BR&gt; return 0;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;H3&gt;/linux/net/core/dev.c &lt;/H3&gt; &lt;P&gt;int __init &lt;FONT color=#ff0000&gt;&lt;STRONG&gt;net_dev_init&lt;/STRONG&gt;&lt;/FONT&gt;(void)&lt;BR&gt;{&lt;BR&gt; struct net_device *dev, **dp;&lt;BR&gt; int i;&lt;/P&gt; &lt;P&gt; if (!dev_boot_phase)&lt;BR&gt;  return 0;&lt;/P&gt; &lt;P&gt;#ifdef CONFIG_NET_DIVERT&lt;BR&gt; dv_init();&lt;BR&gt;#endif /* CONFIG_NET_DIVERT */&lt;BR&gt; &lt;BR&gt; /*&lt;BR&gt;  * Initialise the packet receive queues.&lt;BR&gt;  */&lt;/P&gt; &lt;P&gt; for (i = 0; i &amp;lt; NR_CPUS; i++) {&lt;BR&gt;  struct softnet_data *queue;&lt;/P&gt; &lt;P&gt;  queue = &amp;amp;softnet_data[i];&lt;BR&gt;  skb_queue_head_init(&amp;amp;queue-&amp;gt;input_pkt_queue);&lt;BR&gt;  queue-&amp;gt;throttle = 0;&lt;BR&gt;  queue-&amp;gt;cng_level = 0;&lt;BR&gt;  queue-&amp;gt;avg_blog = 10; /* arbitrary non-zero */&lt;BR&gt;  queue-&amp;gt;completion_queue = NULL;&lt;BR&gt; }&lt;BR&gt; &lt;BR&gt;#ifdef CONFIG_NET_PROFILE&lt;BR&gt; net_profile_init();&lt;BR&gt; NET_PROFILE_REGISTER(dev_queue_xmit);&lt;BR&gt; NET_PROFILE_REGISTER(softnet_process);&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt;#ifdef OFFLINE_SAMPLE&lt;BR&gt; samp_timer.expires = jiffies + (10 * HZ);&lt;BR&gt; add_timer(&amp;amp;samp_timer);&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt; /*&lt;BR&gt;  * Add the devices.&lt;BR&gt;  * If the call to dev-&amp;gt;init fails, the dev is removed&lt;BR&gt;  * from the chain disconnecting the device until the&lt;BR&gt;  * next reboot.&lt;BR&gt;  *&lt;BR&gt;  * NB At boot phase networking is dead. No locking is required.&lt;BR&gt;  * But we still preserve dev_base_lock for sanity.&lt;BR&gt;  */&lt;/P&gt; &lt;P&gt; dp = &amp;amp;dev_base;&lt;BR&gt; while ((dev = *dp) != NULL) {&lt;BR&gt;  spin_lock_init(&amp;amp;dev-&amp;gt;queue_lock);&lt;BR&gt;  spin_lock_init(&amp;amp;dev-&amp;gt;xmit_lock);&lt;BR&gt;#ifdef CONFIG_NET_FASTROUTE&lt;BR&gt;  dev-&amp;gt;fastpath_lock = RW_LOCK_UNLOCKED;&lt;BR&gt;#endif&lt;BR&gt;  dev-&amp;gt;xmit_lock_owner = -1;&lt;BR&gt;  dev-&amp;gt;iflink = -1;&lt;BR&gt;  dev_hold(dev);&lt;/P&gt; &lt;P&gt;  /*&lt;BR&gt;   * Allocate name. If the init() fails&lt;BR&gt;   * the name will be reissued correctly.&lt;BR&gt;   */&lt;BR&gt;  if (strchr(dev-&amp;gt;name, &#39;%&#39;))&lt;BR&gt;   dev_alloc_name(dev, dev-&amp;gt;name);&lt;/P&gt; &lt;P&gt;  /* &lt;BR&gt;   * Check boot time settings for the device.&lt;BR&gt;   */&lt;BR&gt;  netdev_boot_setup_check(dev);&lt;/P&gt; &lt;P&gt;  if (dev-&amp;gt;init &amp;amp;&amp;amp; dev-&amp;gt;init(dev)) {&lt;BR&gt;   /*&lt;BR&gt;    * It failed to come up. It will be unhooked later.&lt;BR&gt;    * dev_alloc_name can now advance to next suitable&lt;BR&gt;    * name that is checked next.&lt;BR&gt;    */&lt;BR&gt;   dev-&amp;gt;deadbeaf = 1;&lt;BR&gt;   dp = &amp;amp;dev-&amp;gt;next;&lt;BR&gt;  } else {&lt;BR&gt;   dp = &amp;amp;dev-&amp;gt;next;&lt;BR&gt;   dev-&amp;gt;ifindex = dev_new_index();&lt;BR&gt;   if (dev-&amp;gt;iflink == -1)&lt;BR&gt;    dev-&amp;gt;iflink = dev-&amp;gt;ifindex;&lt;BR&gt;   if (dev-&amp;gt;rebuild_header == NULL)&lt;BR&gt;    dev-&amp;gt;rebuild_header = default_rebuild_header;&lt;BR&gt;   dev_init_scheduler(dev);&lt;BR&gt;   set_bit(__LINK_STATE_PRESENT, &amp;amp;dev-&amp;gt;state);&lt;BR&gt;  }&lt;BR&gt; }&lt;/P&gt; &lt;P&gt; /*&lt;BR&gt;  * Unhook devices that failed to come up&lt;BR&gt;  */&lt;BR&gt; dp = &amp;amp;dev_base;&lt;BR&gt; while ((dev = *dp) != NULL) {&lt;BR&gt;  if (dev-&amp;gt;deadbeaf) {&lt;BR&gt;   write_lock_bh(&amp;amp;dev_base_lock);&lt;BR&gt;   *dp = dev-&amp;gt;next;&lt;BR&gt;   write_unlock_bh(&amp;amp;dev_base_lock);&lt;BR&gt;   dev_put(dev);&lt;BR&gt;  } else {&lt;BR&gt;   dp = &amp;amp;dev-&amp;gt;next;&lt;BR&gt;  }&lt;BR&gt; }&lt;/P&gt; &lt;P&gt;#ifdef CONFIG_PROC_FS&lt;BR&gt; proc_net_create(&quot;dev&quot;, 0, dev_get_info);&lt;BR&gt; create_proc_read_entry(&quot;net/softnet_stat&quot;, 0, 0, dev_proc_stats, NULL);&lt;BR&gt;#ifdef WIRELESS_EXT&lt;BR&gt; proc_net_create(&quot;wireless&quot;, 0, dev_get_wireless_info);&lt;BR&gt;#endif /* WIRELESS_EXT */&lt;BR&gt;#endif /* CONFIG_PROC_FS */&lt;/P&gt; &lt;P&gt; dev_boot_phase = 0;&lt;/P&gt; &lt;P&gt; open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL);&lt;BR&gt; open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL);&lt;/P&gt; &lt;P&gt; dst_init();&lt;BR&gt; dev_mcast_init();&lt;/P&gt; &lt;P&gt;#ifdef CONFIG_NET_SCHED&lt;BR&gt; pktsched_init();&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt; /*&lt;BR&gt;  * Initialise network devices&lt;BR&gt;  */&lt;BR&gt;  &lt;BR&gt; net_device_init();&lt;/P&gt; &lt;P&gt; return 0;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;H3&gt;/linux/drivers/net/Space.c &lt;/H3&gt; &lt;P&gt;static struct net_device eth7_dev = {&lt;BR&gt;    &quot;eth%d&quot;, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, &lt;STRONG&gt;&lt;FONT color=#ff6600&gt;NEXT_DEV&lt;/FONT&gt;&lt;/STRONG&gt;, ethif_probe };&lt;BR&gt;static struct net_device eth6_dev = {&lt;BR&gt;    &quot;eth%d&quot;, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, &amp;amp;eth7_dev, ethif_probe };&lt;BR&gt;static struct net_device eth5_dev = {&lt;BR&gt;    &quot;eth%d&quot;, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, &amp;amp;eth6_dev, ethif_probe };&lt;BR&gt;static struct net_device eth4_dev = {&lt;BR&gt;    &quot;eth%d&quot;, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, &amp;amp;eth5_dev, ethif_probe };&lt;BR&gt;static struct net_device eth3_dev = {&lt;BR&gt;    &quot;eth%d&quot;, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, &amp;amp;eth4_dev, ethif_probe };&lt;BR&gt;static struct net_device eth2_dev = {&lt;BR&gt;    &quot;eth%d&quot;, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, &amp;amp;eth3_dev, ethif_probe };&lt;BR&gt;static struct net_device &lt;FONT color=#ff6600&gt;&lt;STRONG&gt;eth1_dev&lt;/STRONG&gt; &lt;/FONT&gt;= {&lt;BR&gt;    &quot;eth%d&quot;, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, &amp;amp;&lt;FONT color=#ff6600&gt;&lt;STRONG&gt;eth2_dev&lt;/STRONG&gt;&lt;/FONT&gt;, ethif_probe };&lt;/P&gt; &lt;P&gt;static struct net_device &lt;FONT color=#ff6600&gt;&lt;STRONG&gt;eth0_dev&lt;/STRONG&gt; &lt;/FONT&gt;= {&lt;BR&gt;    &quot;eth%d&quot;, 0, 0, 0, 0, ETH0_ADDR, ETH0_IRQ, 0, 0, 0, &amp;amp;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;eth1_dev&lt;/FONT&gt;&lt;/STRONG&gt;, ethif_probe };&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;#   undef NEXT_DEV&lt;BR&gt;#   define NEXT_DEV (&amp;amp;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;eth0_dev&lt;/FONT&gt;&lt;/STRONG&gt;)&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;extern int loopback_init(struct net_device *dev);&lt;BR&gt;struct net_device &lt;FONT color=#ff6600&gt;loopback_dev &lt;/FONT&gt;= &lt;BR&gt; {&quot;lo&quot;, 0, 0, 0, 0, 0, 0, 0, 0, 0, &lt;STRONG&gt;&lt;FONT color=#ff6600&gt;NEXT_DEV&lt;/FONT&gt;&lt;/STRONG&gt;, loopback_init};&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;struct net_device *dev_base = &amp;amp;&lt;FONT color=#ff6600&gt;&lt;STRONG&gt;loopback_dev&lt;/STRONG&gt;&lt;/FONT&gt;;&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;static struct devprobe isa_probes[] __initdata = {&lt;BR&gt;#ifdef CONFIG_EL3  /* ISA, EISA, MCA 3c5x9 */&lt;BR&gt; {el3_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_HP100   /* ISA, EISA &amp;amp; PCI */&lt;BR&gt; {hp100_probe, 0},&lt;BR&gt;#endif &lt;BR&gt;#ifdef CONFIG_3C515&lt;BR&gt; {tc515_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_ULTRA &lt;BR&gt; {ultra_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_WD80x3 &lt;BR&gt; {wd_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_EL2   /* 3c503 */&lt;BR&gt; {el2_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_HPLAN&lt;BR&gt; {hp_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_HPLAN_PLUS&lt;BR&gt; {hp_plus_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_E2100  /* Cabletron E21xx series. */&lt;BR&gt; {e2100_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_NE2000  /* ISA (use ne2k-pci for PCI cards) */&lt;BR&gt; {ne_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_LANCE  /* ISA/VLB (use pcnet32 for PCI cards) */&lt;BR&gt; {lance_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_SMC9194&lt;BR&gt; {smc_init, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_SEEQ8005 &lt;BR&gt; {seeq8005_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_AT1500&lt;BR&gt; {at1500_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;&lt;FONT color=#ff0000&gt;&lt;STRONG&gt;#ifdef CONFIG_CS89x0&lt;BR&gt;  {cs89x0_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;&lt;/STRONG&gt;&lt;/FONT&gt;#ifdef CONFIG_AT1700&lt;BR&gt; {at1700_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_FMV18X  /* Fujitsu FMV-181/182 */&lt;BR&gt; {fmv18x_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_ETH16I&lt;BR&gt; {eth16i_probe, 0}, /* ICL EtherTeam 16i/32 */&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_ZNET  /* Zenith Z-Note and some IBM Thinkpads. */&lt;BR&gt; {znet_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_EEXPRESS  /* Intel EtherExpress */&lt;BR&gt; {express_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_EEXPRESS_PRO /* Intel EtherExpress Pro/10 */&lt;BR&gt; {eepro_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_DEPCA  /* DEC DEPCA */&lt;BR&gt; {depca_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_EWRK3             /* DEC EtherWORKS 3 */&lt;BR&gt;     {ewrk3_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#if defined(CONFIG_APRICOT) || defined(CONFIG_MVME16x_NET) || defined(CONFIG_BVME6000_NET) /* Intel I82596 */&lt;BR&gt; {i82596_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_EL1  /* 3c501 */&lt;BR&gt; {el1_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_WAVELAN  /* WaveLAN */&lt;BR&gt; {wavelan_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_ARLAN  /* Aironet */&lt;BR&gt; {arlan_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_EL16  /* 3c507 */&lt;BR&gt; {el16_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_ELPLUS  /* 3c505 */&lt;BR&gt; {elplus_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_SK_G16&lt;BR&gt; {SK_init, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_NI5010&lt;BR&gt; {ni5010_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_NI52&lt;BR&gt; {ni52_probe, 0},&lt;BR&gt;#endif&lt;BR&gt;#ifdef CONFIG_NI65&lt;BR&gt; {ni65_probe, 0},&lt;BR&gt;#endif&lt;BR&gt; {NULL, 0},&lt;BR&gt;};&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt; &lt;/P&gt;</content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/7397417389641063561/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/7397417389641063561' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/7397417389641063561'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/7397417389641063561'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2007/05/network-core-linuxdriversblockgenhd.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-192139734168033681</id><published>2007-05-17T22:43:00.000+08:00</published><updated>2007-06-22T22:35:42.384+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 網路程式篇"/><title type='text'></title><content type='html'>&lt;H2&gt;Network Programming&lt;/H2&gt; &lt;H3 style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;TCP&lt;/H3&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_154gkv5m5d6&quot;&gt;&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_155gpcb5dgh&quot;&gt;&lt;/DIV&gt; &lt;H3&gt;TcpEchoServer1.c&lt;/H3&gt; &lt;P&gt;#include &amp;lt;sys/types.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/stat.h&amp;gt;&lt;BR&gt;#include &amp;lt;fcntl.h&amp;gt;&lt;BR&gt;#include &amp;lt;unistd.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/socket.h&amp;gt;&lt;BR&gt;#include &amp;lt;netinet/in.h&amp;gt;&lt;BR&gt;#include &amp;lt;arpa/inet.h&amp;gt;&lt;BR&gt;#include &amp;lt;unistd.h&amp;gt;&lt;BR&gt;#include &amp;lt;stdio.h&amp;gt;&lt;BR&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;BR&gt;#include &amp;lt;string.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/time.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/wait.h&amp;gt;&lt;BR&gt;#include &amp;lt;errno.h&amp;gt;&lt;/P&gt; &lt;P&gt;int main(int argc,char *argv[])&lt;BR&gt;{&lt;BR&gt;    int   iServerActive,iIncomingBytes;&lt;BR&gt;    int  iSocketFD,iConnectedFD;&lt;BR&gt;    pid_t pid_tChildPid;&lt;BR&gt;    char buffer[1000];&lt;BR&gt;    socklen_t socklen_tClientLen;&lt;BR&gt;    struct    sockaddr_in sockaddr_inClientAddress;&lt;BR&gt;    struct    sockaddr_in sockaddr_inServerAddress;&lt;/P&gt; &lt;P&gt;    if(argc != 2)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;Usage:n&quot;);&lt;BR&gt;        printf(&quot;./TcpEchoServer1.exe [Port number]n&quot;);&lt;BR&gt;        printf(&quot;Port number example: 12345n&quot;);&lt;BR&gt;        exit(1);&lt;BR&gt;    }&lt;/P&gt; &lt;P&gt;    if((iSocketFD=&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;socket&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(AF_INET,&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6666&gt;SOCK_STREAM&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;,0))&amp;lt;0)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;socket errorn&quot;);&lt;BR&gt;        exit(1);&lt;BR&gt;    }&lt;/P&gt; &lt;P&gt;    memset(&amp;amp;sockaddr_inServerAddress,0,&lt;BR&gt;    sizeof(sockaddr_inServerAddress));&lt;/P&gt; &lt;P&gt;    sockaddr_inServerAddress.sin_family=&lt;EM&gt;&lt;FONT color=#3366ff&gt;&lt;STRONG&gt;AF_INET&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/EM&gt;;&lt;BR&gt;    sockaddr_inServerAddress.sin_addr.s_addr= &lt;BR&gt;     htonl(INADDR_ANY);&lt;BR&gt;    sockaddr_inServerAddress.sin_port=htons(atoi(argv[1]));&lt;/P&gt; &lt;P&gt;    if(&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;bind&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(iSocketFD,&lt;BR&gt;     (struct sockaddr *)&amp;amp;sockaddr_inServerAddress,&lt;BR&gt;     sizeof(sockaddr_inServerAddress)) &amp;lt; 0)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;bind errorn&quot;);&lt;BR&gt;        exit(1);&lt;BR&gt;    }&lt;BR&gt;    if(&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;listen&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(iSocketFD,3)&amp;lt;0)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;listen errorn&quot;);&lt;BR&gt;        exit(1);&lt;BR&gt;    }&lt;/P&gt; &lt;P&gt;    iServerActive=1;&lt;BR&gt;    while(iServerActive)&lt;BR&gt;    {&lt;BR&gt;        socklen_tClientLen=sizeof(sockaddr_inClientAddress);&lt;BR&gt;        if((iConnectedFD=&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;accept&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(iSocketFD,(struct sockaddr *)&lt;BR&gt;         &amp;amp;sockaddr_inClientAddress,&amp;amp;socklen_tClientLen))&amp;lt;0)&lt;BR&gt;        {&lt;BR&gt;            printf(&quot;accept error&quot;);&lt;BR&gt;            exit(1);&lt;BR&gt;        }&lt;/P&gt; &lt;P&gt;        printf(&quot;Connect from %sn&quot;,&lt;BR&gt;        inet_ntoa(sockaddr_inClientAddress.sin_addr));&lt;/P&gt; &lt;P&gt;        while(1)&lt;BR&gt;        {&lt;BR&gt;          memset(buffer,0,1000);         &lt;BR&gt;            if(iIncomingBytes=&lt;BR&gt;             &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;read&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(iConnectedFD,buffer,sizeof(buffer))&amp;gt;0)&lt;BR&gt;            {&lt;BR&gt;                printf(&quot;%s&quot;,buffer);&lt;BR&gt;                if(&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;write&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(iConnectedFD,buffer,sizeof(buffer)) &amp;lt; 0)&lt;BR&gt;                {&lt;BR&gt;                    printf(&quot;send error!&quot;);&lt;BR&gt;                    exit(1);&lt;BR&gt;                }&lt;BR&gt;            }&lt;BR&gt;        }&lt;BR&gt;    }&lt;BR&gt;}&lt;BR&gt;&lt;/P&gt; &lt;H3&gt;TcpEchoClient.c&lt;/H3&gt; &lt;P&gt;#include &amp;lt;sys/types.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/stat.h&amp;gt;&lt;BR&gt;#include &amp;lt;fcntl.h&amp;gt;&lt;BR&gt;#include &amp;lt;unistd.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/socket.h&amp;gt;&lt;BR&gt;#include &amp;lt;netinet/in.h&amp;gt;&lt;BR&gt;#include &amp;lt;arpa/inet.h&amp;gt;&lt;BR&gt;#include &amp;lt;unistd.h&amp;gt;&lt;BR&gt;#include &amp;lt;stdio.h&amp;gt;&lt;BR&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;BR&gt;#include &amp;lt;string.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/time.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/wait.h&amp;gt;&lt;BR&gt;#include &amp;lt;errno.h&amp;gt;&lt;/P&gt; &lt;P&gt;int main(int argc,char *argv[])&lt;BR&gt;{&lt;BR&gt;    int     iSocketFD;&lt;BR&gt;    char    buffer[1000];&lt;BR&gt;    int     iIncomingBytes;&lt;BR&gt;    struct  sockaddr_in sockaddr_inServerAddress;&lt;/P&gt; &lt;P&gt;    if(argc !=3)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;Usage: ./TcpEchoClient.exe &lt;BR&gt;               n       &amp;lt;IP address&amp;gt; &amp;lt;Port number&amp;gt;n&quot;);&lt;BR&gt;        exit(1);&lt;BR&gt;    }&lt;/P&gt; &lt;P&gt;    if((iSocketFD=&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;socket&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(AF_INET,&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6666&gt;SOCK_STREAM&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;,0))&amp;lt;0)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;socket errorn&quot;);&lt;BR&gt;        exit(1);&lt;BR&gt;    }&lt;/P&gt; &lt;P&gt;    memset(&amp;amp;sockaddr_inServerAddress,&lt;BR&gt;   0,&lt;BR&gt;   sizeof(sockaddr_inServerAddress));&lt;BR&gt;    sockaddr_inServerAddress.sin_family=AF_INET;&lt;BR&gt;    sockaddr_inServerAddress.sin_addr.s_addr=inet_addr(argv[1]);&lt;BR&gt;    sockaddr_inServerAddress.sin_port=htons(atoi(argv[2]));&lt;/P&gt; &lt;P&gt;    if(&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;connect&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(iSocketFD,&lt;BR&gt;   (struct sockaddr *)&lt;BR&gt;   &amp;amp;sockaddr_inServerAddress,&lt;BR&gt;   sizeof(sockaddr_inServerAddress)) &amp;lt; 0)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;connect errorn&quot;);&lt;BR&gt;        exit(1);&lt;BR&gt;    }&lt;/P&gt; &lt;P&gt;    while(fgets(buffer,1000,stdin)!=NULL)&lt;BR&gt;    {&lt;BR&gt;        if(&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;write&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(iSocketFD,buffer,strlen(buffer))&amp;lt;0)&lt;BR&gt;        {&lt;BR&gt;            perror(&quot;send error&quot;);&lt;BR&gt;            exit(0);&lt;BR&gt;        }&lt;BR&gt;        if(iIncomingBytes=&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;read&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(iSocketFD,buffer,sizeof(buffer))&amp;gt;0)&lt;BR&gt;        {&lt;BR&gt;            printf(&quot;%s&quot;,buffer);&lt;BR&gt;        }&lt;BR&gt;        memset(buffer,0,1000);&lt;BR&gt;    }&lt;BR&gt;    exit(0);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_156gdzhj7d9&quot;&gt;&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_157gbvc87cv&quot;&gt;&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_159cwst3sjs&quot;&gt;&lt;/DIV&gt;#include &amp;lt;sys/types.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/stat.h&amp;gt;&lt;BR&gt;#include &amp;lt;fcntl.h&amp;gt;&lt;BR&gt;#include &amp;lt;unistd.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/socket.h&amp;gt;&lt;BR&gt;#include &amp;lt;netinet/in.h&amp;gt;&lt;BR&gt;#include &amp;lt;arpa/inet.h&amp;gt;&lt;BR&gt;#include &amp;lt;unistd.h&amp;gt;&lt;BR&gt;#include &amp;lt;stdio.h&amp;gt;&lt;BR&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;BR&gt;#include &amp;lt;string.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/time.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/wait.h&amp;gt;&lt;BR&gt;#include &amp;lt;errno.h&amp;gt;&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;int main(int argc,char *argv[])&lt;BR&gt;{&lt;BR&gt;    int     iServerActive,iIncomingBytes,iSocketFD,iConnectedFD;&lt;BR&gt;    pid_t   pid_tChildPid;&lt;BR&gt;    socklen_t   socklen_tClientLen;&lt;BR&gt;    struct  sockaddr_in sockaddr_inClientAddress;&lt;BR&gt;    struct  sockaddr_in sockaddr_inServerAddress;&lt;BR&gt;    char    buffer[1000];&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;    if(argc != 2)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;Usage:n&quot;);&lt;BR&gt;        printf(&quot;./TcpEchoServer2.exe [Port number]n&quot;);&lt;BR&gt;        printf(&quot;Port number example: 12345n&quot;);&lt;BR&gt;        exit(1);&lt;BR&gt;    }&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;    if((iSocketFD=socket(AF_INET,SOCK_STREAM,0))&amp;lt;0)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;socket errorn&quot;);&lt;BR&gt;        exit(1);&lt;BR&gt;    }&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;    memset(&amp;amp;sockaddr_inServerAddress,&lt;BR&gt;           0,&lt;BR&gt;           sizeof(sockaddr_inServerAddress));&lt;BR&gt;    sockaddr_inServerAddress.sin_family=AF_INET;&lt;BR&gt;    sockaddr_inServerAddress.sin_addr.s_addr=&lt;BR&gt;     htonl(INADDR_ANY);&lt;BR&gt;    sockaddr_inServerAddress.sin_port=htons(atoi(argv[1]));&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;    if (&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#000099&gt;bind&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(iSocketFD,&lt;BR&gt;             (struct sockaddr *) &amp;amp;sockaddr_inServerAddress,&lt;BR&gt;             sizeof(sockaddr_inServerAddress)) &amp;lt; 0)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;bind errorn&quot;);&lt;BR&gt;        exit(1);&lt;BR&gt;    }&lt;BR&gt;    if(&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#000099&gt;listen&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(iSocketFD,3)&amp;lt;0)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;listen errorn&quot;);&lt;BR&gt;        exit(1);&lt;BR&gt;    }&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;    iServerActive=1;&lt;BR&gt;    while(iServerActive)&lt;BR&gt;    {&lt;BR&gt;        socklen_tClientLen=sizeof(sockaddr_inClientAddress);&lt;BR&gt;        if((&lt;FONT color=#ff0000&gt;&lt;STRONG&gt;iConnectedFD&lt;/STRONG&gt;&lt;/FONT&gt;=&lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#000099&gt;accept&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(&lt;STRONG&gt;&lt;FONT color=#ff0000&gt;iSocketFD&lt;/FONT&gt;&lt;/STRONG&gt;,(struct sockaddr *)&lt;BR&gt;        &amp;amp;sockaddr_inClientAddress,&amp;amp;socklen_tClientLen))&amp;lt;0)&lt;BR&gt;        {&lt;BR&gt;            printf(&quot;accept error&quot;);&lt;BR&gt;            exit(1);&lt;BR&gt;        }&lt;BR&gt;        if((pid_tChildPid = &lt;FONT color=#333399&gt;&lt;STRONG&gt;&lt;EM&gt;fork&lt;/EM&gt;&lt;/STRONG&gt;&lt;/FONT&gt;()) == -1)&lt;BR&gt;        {&lt;BR&gt;            printf(&quot;accept error&quot;);&lt;BR&gt;            exit(1);&lt;BR&gt;        }&lt;BR&gt;        if(&lt;STRONG&gt;&lt;FONT color=#ff0000&gt;pid_tChildPid == 0&lt;/FONT&gt;&lt;/STRONG&gt;)&lt;BR&gt;        {&lt;BR&gt;         if (close(iSocketFD) == -1)&lt;BR&gt;            {&lt;BR&gt;                printf(&quot;close error&quot;);&lt;BR&gt;                exit(1);&lt;BR&gt;            }&lt;BR&gt;            printf(&quot;Connect from %sn&quot;,&lt;BR&gt;            inet_ntoa(sockaddr_inClientAddress.sin_addr));&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;            while(1)&lt;BR&gt;            {&lt;BR&gt;               memset(buffer,0,1000);&lt;BR&gt;                if(iIncomingBytes=&lt;BR&gt;                read(iConnectedFD,buffer,sizeof(buffer))&amp;gt;0)&lt;BR&gt;                {&lt;BR&gt;                    printf(&quot;%s&quot;,buffer);&lt;BR&gt;                    if(write(iConnectedFD,&lt;BR&gt;                            buffer,&lt;BR&gt;                            sizeof(buffer)) &amp;lt; 0)&lt;BR&gt;                    {&lt;BR&gt;                        printf(&quot;send error!&quot;);&lt;BR&gt;                        exit(1);&lt;BR&gt;                    }&lt;BR&gt;                }&lt;BR&gt;            }&lt;BR&gt;            exit(0);&lt;BR&gt;        }&lt;BR&gt;        if (close(iConnectedFD) == -1)&lt;BR&gt;        {&lt;BR&gt;            printf(&quot;close error&quot;);&lt;BR&gt;            exit(1);&lt;BR&gt;        }&lt;BR&gt;    }&lt;BR&gt;}&lt;BR&gt;&lt;/DIV&gt; &lt;H2&gt;UDP&lt;/H2&gt; &lt;H2&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_160hs2b2wxq&quot;&gt;&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_161dzxq63f8&quot;&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/H2&gt; &lt;H2&gt;UdpServer.c&lt;/H2&gt; &lt;P&gt;#include &amp;lt;sys/types.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/socket.h&amp;gt;&lt;BR&gt;#include &amp;lt;netinet/in.h&amp;gt;&lt;BR&gt;#include &amp;lt;arpa/inet.h&amp;gt;&lt;BR&gt;#include &amp;lt;unistd.h&amp;gt;&lt;/P&gt; &lt;P&gt;main(int argc,char *argv[])&lt;BR&gt;{&lt;BR&gt;    int SockFD,Len;&lt;BR&gt;    struct sockaddr_in Addr;&lt;BR&gt;    int AddrLen=sizeof(struct sockaddr_in);&lt;BR&gt;    char cTemp[1000];&lt;/P&gt; &lt;P&gt;    if(argc != 2)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;Usage  : udpserver [port number]n&quot;);&lt;BR&gt;        printf(&quot;Example: udpserver 12345n&quot;);&lt;BR&gt;        exit(1);&lt;BR&gt;    }&lt;/P&gt; &lt;P&gt;    if((SockFD=&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;socket&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(AF_INET,&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6666&gt;SOCK_DGRAM&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;,0))&amp;lt;0)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;socket error!&quot;);&lt;BR&gt;        exit(1);&lt;BR&gt;    }&lt;/P&gt; &lt;P&gt;    memset(cTemp,0,1000);&lt;BR&gt;    Addr.sin_family = AF_INET;&lt;BR&gt;    Addr.sin_port = htons(atoi(argv[1]));&lt;BR&gt;    Addr.sin_addr.s_addr = htonl(INADDR_ANY);&lt;/P&gt; &lt;P&gt;    if(&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;bind&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(SockFD,&amp;amp;Addr,sizeof(Addr))&amp;lt;0)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;bind error!&quot;);&lt;BR&gt;        exit(1);&lt;BR&gt;    }&lt;BR&gt;    &lt;BR&gt;    while(1)&lt;BR&gt;    {&lt;BR&gt;    memset(cTemp,0,1000);&lt;BR&gt;    Len=&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;recvfrom&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(SockFD,&lt;BR&gt;                             cTemp,&lt;BR&gt;                             sizeof(cTemp),&lt;BR&gt;                             0,&lt;BR&gt;                             &amp;amp;Addr,&lt;BR&gt;                             &amp;amp;AddrLen);&lt;BR&gt;    if(Len&amp;gt;0)&lt;BR&gt;    {&lt;BR&gt;     printf(&quot;receive %sn&quot;,cTemp);&lt;BR&gt;     printf(&quot;Received data = %s, length = %d bytes, received from %sn&quot;,&lt;BR&gt;          cTemp,              &lt;BR&gt;          Len,                &lt;BR&gt;          inet_ntoa(Addr.sin_addr));&lt;BR&gt;     &lt;FONT color=#3366ff&gt; &lt;EM&gt;&lt;STRONG&gt;sendto&lt;/STRONG&gt;&lt;/EM&gt;&lt;/FONT&gt;(SockFD,cTemp,Len,0,&amp;amp;Addr,AddrLen);&lt;BR&gt;        }&lt;BR&gt;    }&lt;BR&gt;}&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;H2&gt;UdpClient.c&lt;/H2&gt; &lt;P&gt;#include &amp;lt;sys/stat.h&amp;gt;&lt;BR&gt;#include &amp;lt;fcntl.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/types.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/socket.h&amp;gt;&lt;BR&gt;#include &amp;lt;netinet/in.h&amp;gt;&lt;BR&gt;#include &amp;lt;arpa/inet.h&amp;gt;&lt;BR&gt;#include &amp;lt;unistd.h&amp;gt;&lt;BR&gt;#include &amp;lt;stdio.h&amp;gt;&lt;BR&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;BR&gt;#include &amp;lt;string.h&amp;gt;&lt;/P&gt; &lt;P&gt;&lt;BR&gt;main(int argc,char *argv[])&lt;BR&gt;{&lt;BR&gt;    int SockFD,Len;&lt;BR&gt;    struct sockaddr_in Addr;&lt;BR&gt;    int AddrLen=sizeof(struct sockaddr_in);&lt;BR&gt;    char cTemp[1000];&lt;/P&gt; &lt;P&gt;    if(argc != 3)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;Usage:n&quot;);&lt;BR&gt;        printf(&quot;udpclient [IP address] [Port number]nn&quot;);&lt;BR&gt;        printf(&quot;IP address example: 192.168.181.222n&quot;);&lt;BR&gt;        printf(&quot;Port number example: 12345n&quot;);&lt;BR&gt;        exit(1);&lt;BR&gt;    }&lt;/P&gt; &lt;P&gt;    if((SockFD=&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;socket&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(AF_INET,&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;SOCK_DGRAM&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;,0))&amp;lt;0)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;socket error&quot;);&lt;BR&gt;        exit(1);&lt;BR&gt;    }&lt;BR&gt;    &lt;BR&gt;    memset(&amp;amp;Addr,0,sizeof(Addr));&lt;BR&gt;    Addr.sin_family = AF_INET;&lt;BR&gt;    Addr.sin_port = htons(atoi(argv[2]));&lt;BR&gt;    Addr.sin_addr.s_addr = inet_addr(argv[1]);&lt;/P&gt; &lt;P&gt;    while(1)&lt;BR&gt;    {&lt;BR&gt;        memset(cTemp,0,1000);&lt;BR&gt;        Len=read(STDIN_FILENO,cTemp,sizeof(cTemp));&lt;BR&gt;        &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;sendto&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(SockFD,cTemp,Len,0,&amp;amp;Addr,AddrLen);&lt;BR&gt;        Len=&lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;recvfrom&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(SockFD,&lt;BR&gt;                     cTemp,&lt;BR&gt;                     sizeof(cTemp),&lt;BR&gt;                     0,&lt;BR&gt;                     &amp;amp;Addr,&lt;BR&gt;                     &amp;amp;AddrLen);&lt;BR&gt;        printf(&quot;receive %sn&quot;,cTemp);&lt;BR&gt;    }&lt;BR&gt;}&lt;BR&gt;&lt;/P&gt; &lt;P&gt; &lt;/P&gt;</content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/192139734168033681/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/192139734168033681' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/192139734168033681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/192139734168033681'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2007/05/network-programming-tcp-tcpechoserver1.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-6305769004149807178</id><published>2007-05-17T22:42:00.000+08:00</published><updated>2007-05-17T22:47:05.396+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 網路程式篇"/><title type='text'></title><content type='html'>&lt;H1&gt;Network Driver&lt;/H1&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt;/* cs89x0.c: A Crystal Semiconductor (Now Cirrus Logic) CS89[02]0&lt;BR&gt; *  driver for linux.&lt;BR&gt; */&lt;/P&gt; &lt;P&gt;/*&lt;BR&gt; Written 1996 by Russell Nelson, with reference to skeleton.c&lt;BR&gt; written 1993-1994 by Donald Becker.&lt;/P&gt; &lt;P&gt; This software may be used and distributed according to the terms&lt;BR&gt; of the GNU General Public License, incorporated herein by reference.&lt;/P&gt; &lt;P&gt;        The author may be reached at &lt;A href=&quot;mailto:nelson@crynwr.com&quot;&gt;nelson@crynwr.com&lt;/A&gt;, Crynwr&lt;BR&gt;        Software, 521 Pleasant Valley Rd., Potsdam, NY 13676&lt;/P&gt; &lt;P&gt;  Changelog:&lt;/P&gt; &lt;P&gt;  Mike Cruse        : &lt;A href=&quot;mailto:mcruse@cti-ltd.com&quot;&gt;mcruse@cti-ltd.com&lt;/A&gt;&lt;BR&gt;                    : Changes for Linux 2.0 compatibility. &lt;BR&gt;                    : Added dev_id parameter in net_interrupt(),&lt;BR&gt;                    : request_irq() and free_irq(). Just NULL for now.&lt;/P&gt; &lt;P&gt;  Mike Cruse        : Added MOD_INC_USE_COUNT and MOD_DEC_USE_COUNT macros&lt;BR&gt;                    : in net_open() and net_close() so kerneld would know&lt;BR&gt;                    : that the module is in use and wouldn&#39;t eject the &lt;BR&gt;                    : driver prematurely.&lt;/P&gt; &lt;P&gt;  Mike Cruse        : Rewrote init_module() and cleanup_module using 8390.c&lt;BR&gt;                    : as an example. Disabled autoprobing in init_module(),&lt;BR&gt;                    : not a good thing to do to other devices while Linux&lt;BR&gt;                    : is running from all accounts.&lt;/P&gt; &lt;P&gt;  Russ Nelson       : Jul 13 1998.  Added RxOnly DMA support.&lt;/P&gt; &lt;P&gt;  Melody Lee        : Aug 10 1999.  Changes for Linux 2.2.5 compatibility. &lt;BR&gt;                    : email: &lt;A href=&quot;mailto:ethernet@crystal.cirrus.com&quot;&gt;ethernet@crystal.cirrus.com&lt;/A&gt;&lt;/P&gt; &lt;P&gt;  Alan Cox          : Removed 1.2 support, added 2.1 extra counters.&lt;/P&gt; &lt;P&gt;  Andrew Morton     : &lt;A href=&quot;mailto:andrewm@uow.edu.au&quot;&gt;andrewm@uow.edu.au&lt;/A&gt;&lt;BR&gt;                    : Kernel 2.3.48&lt;BR&gt;                    : Handle kmalloc() failures&lt;BR&gt;                    : Other resource allocation fixes&lt;BR&gt;                    : Add SMP locks&lt;BR&gt;                    : Integrate Russ Nelson&#39;s ALLOW_DMA functionality back in.&lt;BR&gt;                    : If ALLOW_DMA is true, make DMA runtime selectable&lt;BR&gt;                    : Folded in changes from Cirrus (Melody Lee&lt;BR&gt;                    : &amp;lt;&lt;A href=&quot;mailto:klee@crystal.cirrus.com&quot;&gt;klee@crystal.cirrus.com&lt;/A&gt;&amp;gt;)&lt;BR&gt;                    : Don&#39;t call netif_wake_queue() in net_send_packet()&lt;BR&gt;                    : Fixed an out-of-mem bug in dma_rx()&lt;BR&gt;                    : Updated Documentation/cs89x0.txt&lt;/P&gt; &lt;P&gt;  Andrew Morton     : &lt;A href=&quot;mailto:andrewm@uow.edu.au&quot;&gt;andrewm@uow.edu.au&lt;/A&gt; / Kernel 2.3.99-pre1&lt;BR&gt;                    : Use skb_reserve to longword align IP header (two places)&lt;BR&gt;                    : Remove a delay loop from dma_rx()&lt;BR&gt;                    : Replace &#39;100&#39; with HZ&lt;BR&gt;                    : Clean up a couple of skb API abuses&lt;BR&gt;                    : Added &#39;cs89x0_dma=N&#39; kernel boot option&lt;BR&gt;                    : Correctly initialise lp-&amp;gt;lock in non-module compile&lt;/P&gt; &lt;P&gt;  Andrew Morton     : &lt;A href=&quot;mailto:andrewm@uow.edu.au&quot;&gt;andrewm@uow.edu.au&lt;/A&gt; / Kernel 2.3.99-pre4-1&lt;BR&gt;                    : MOD_INC/DEC race fix (see&lt;BR&gt;                    : &lt;A href=&quot;http://www.uwsg.indiana.edu/hypermail/linux/kernel/0003.3/1532.html&quot;&gt;http://www.uwsg.indiana.edu/hypermail/linux/kernel/0003.3/1532.html&lt;/A&gt;)&lt;/P&gt; &lt;P&gt;  Andrew Morton     : &lt;A href=&quot;mailto:andrewm@uow.edu.au&quot;&gt;andrewm@uow.edu.au&lt;/A&gt; / Kernel 2.4.0-test7-pre2&lt;BR&gt;                    : Enhanced EEPROM support to cover more devices,&lt;BR&gt;                    :   abstracted IRQ mapping to support CONFIG_ARCH_CLPS7500 arch&lt;BR&gt;                    :   (Jason Gunthorpe &amp;lt;&lt;A href=&quot;mailto:jgg@ualberta.ca&quot;&gt;jgg@ualberta.ca&lt;/A&gt;&amp;gt;)&lt;/P&gt; &lt;P&gt;  Andrew Morton     : Kernel 2.4.0-test11-pre4&lt;BR&gt;                    : Use dev-&amp;gt;name in request_*() (Andrey Panin)&lt;BR&gt;                    : Fix an error-path memleak in init_module()&lt;BR&gt;                    : Preserve return value from request_irq()&lt;BR&gt;                    : Fix type of `media&#39; module parm (Keith Owens)&lt;BR&gt;                    : Use SET_MODULE_OWNER()&lt;BR&gt;                    : Tidied up strange request_irq() abuse in net_open().&lt;/P&gt; &lt;P&gt;  Andrew Morton     : Kernel 2.4.3-pre1&lt;BR&gt;                    : Request correct number of pages for DMA (Hugh Dickens)&lt;BR&gt;                    : Select PP_ChipID _after_ unregister_netdev in cleanup_module()&lt;BR&gt;                    :  because unregister_netdev() calls get_stats.&lt;BR&gt;                    : Make `version[]&#39; __initdata&lt;BR&gt;                    : Uninlined the read/write reg/word functions.&lt;/P&gt; &lt;P&gt;*/&lt;/P&gt; &lt;P&gt;/* Always include &#39;config.h&#39; first in case the user wants to turn on&lt;BR&gt;   or override something. */&lt;BR&gt;#include &amp;lt;linux/config.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/module.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/version.h&amp;gt;&lt;/P&gt; &lt;P&gt;/*&lt;BR&gt; * Set this to zero to disable DMA code&lt;BR&gt; *&lt;BR&gt; * Note that even if DMA is turned off we still support the &#39;dma&#39; and  &#39;use_dma&#39;&lt;BR&gt; * module options so we don&#39;t break any startup scripts.&lt;BR&gt; */&lt;BR&gt;#define ALLOW_DMA 1&lt;/P&gt; &lt;P&gt;/*&lt;BR&gt; * Set this to zero to remove all the debug statements via&lt;BR&gt; * dead code elimination&lt;BR&gt; */&lt;BR&gt;#define DEBUGGING 0&lt;BR&gt;//#define DEBUGGING 1&lt;/P&gt; &lt;P&gt;/*&lt;BR&gt;  Sources:&lt;/P&gt; &lt;P&gt; Crynwr packet driver epktisa.&lt;/P&gt; &lt;P&gt; Crystal Semiconductor data sheets.&lt;/P&gt; &lt;P&gt;*/&lt;/P&gt; &lt;P&gt;#include &amp;lt;linux/config.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/kernel.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/sched.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/types.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/fcntl.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/interrupt.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/ptrace.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/ioport.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/in.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/slab.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/string.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/init.h&amp;gt;&lt;BR&gt;#include &amp;lt;asm/system.h&amp;gt;&lt;BR&gt;#include &amp;lt;asm/bitops.h&amp;gt;&lt;BR&gt;#include &amp;lt;asm/io.h&amp;gt;&lt;BR&gt;#if ALLOW_DMA&lt;BR&gt;#include &amp;lt;asm/dma.h&amp;gt;&lt;BR&gt;#endif&lt;BR&gt;#include &amp;lt;linux/errno.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/spinlock.h&amp;gt;&lt;/P&gt; &lt;P&gt;#include &amp;lt;linux/netdevice.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/etherdevice.h&amp;gt;&lt;BR&gt;#include &amp;lt;linux/skbuff.h&amp;gt;&lt;/P&gt; &lt;P&gt;#ifdef CONFIG_ARCH_S3C2410&lt;BR&gt;#include &amp;lt;asm/irq.h&amp;gt;&lt;BR&gt;#include &amp;lt;asm/hardware.h&amp;gt;&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt;#include &quot;cs89x0.h&quot;&lt;/P&gt; &lt;P&gt;static char version[] __initdata =&lt;BR&gt;&quot;cs89x0.c: v2.4.3-pre1 Russell Nelson &amp;lt;&lt;A href=&quot;mailto:nelson@crynwr.com&quot;&gt;nelson@crynwr.com&lt;/A&gt;&amp;gt;, Andrew Morton &amp;lt;&lt;A href=&quot;mailto:andrewm@uow.edu.au&gt;n&quot;&gt;andrewm@uow.edu.au&amp;gt;n&lt;/A&gt;&quot;;&lt;/P&gt; &lt;P&gt;/* First, a few definitions that the brave might change.&lt;BR&gt;   A zero-terminated list of I/O addresses to be probed. Some special flags..&lt;BR&gt;      Addr &amp;amp; 1 = Read back the address port, look for signature and reset&lt;BR&gt;                 the page window before probing &lt;BR&gt;      Addr &amp;amp; 3 = Reset the page window and probe &lt;BR&gt;   The CLPS eval board has the Cirrus chip at 0x80090300, in ARM IO space,&lt;BR&gt;   but it is possible that a Cirrus board could be plugged into the ISA&lt;BR&gt;   slots. */&lt;BR&gt;/* The cs8900 has 4 IRQ pins, software selectable. cs8900_irq_map maps &lt;BR&gt;   them to system IRQ numbers. This mapping is card specific and is set to&lt;BR&gt;   the configuration of the Cirrus Eval board for this chip. */&lt;BR&gt;#ifdef CONFIG_ARCH_CLPS7500&lt;BR&gt;static unsigned int netcard_portlist[] __initdata =&lt;BR&gt;   { 0x80090303, 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};&lt;BR&gt;static unsigned int cs8900_irq_map[] = {12,0,0,0};&lt;/P&gt; &lt;P&gt;#elif defined(CONFIG_ARCH_S3C2410)&lt;BR&gt; /* &lt;BR&gt;  * Samsung SMDK2410 (Samsung S3C2410 eval board) has the Cirrus chip&lt;BR&gt;         * on CS3, using external interrupt EINT9 &lt;BR&gt;  */&lt;BR&gt;static unsigned int netcard_portlist[] __initdata =&lt;BR&gt;   { VA_CS8900A_BASE+DEFAULTIOBASE, 0};&lt;BR&gt;static unsigned int cs8900_irq_map[] = {IRQ_EINT9,0,0,0};&lt;BR&gt;        /*&lt;BR&gt;         * on the SMDK2410, we are mapped into IO memory space instead of IO port space,&lt;BR&gt;     * so redirect request/release_region to use IO memory versus IO ports &lt;BR&gt;  */&lt;BR&gt;#ifdef request_region&lt;BR&gt;#undef request_region&lt;BR&gt;#endif&lt;BR&gt;#ifdef release_region&lt;BR&gt;#undef release_region&lt;BR&gt;#endif&lt;BR&gt;#define request_region(a,s,n)  request_mem_region(a,s,n)&lt;BR&gt;#define release_region(a,s)    release_mem_region(a,s)&lt;BR&gt;#else  /* End of S3C2410 */&lt;/P&gt; &lt;P&gt;static unsigned int netcard_portlist[] __initdata =&lt;BR&gt;   { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};&lt;BR&gt;static unsigned int cs8900_irq_map[] = {10,11,12,5};&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt;#if DEBUGGING&lt;BR&gt;static unsigned int net_debug = DEBUGGING;&lt;BR&gt;#else&lt;BR&gt;#define net_debug 0 /* gcc will remove all the debug code for us */&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt;/* The number of low I/O ports used by the ethercard. */&lt;BR&gt;#define NETCARD_IO_EXTENT 16&lt;/P&gt; &lt;P&gt;/* we allow the user to override various values normally set in the EEPROM */&lt;BR&gt;#define FORCE_RJ45 0x0001    /* pick one of these three */&lt;BR&gt;#define FORCE_AUI 0x0002&lt;BR&gt;#define FORCE_BNC 0x0004&lt;/P&gt; &lt;P&gt;#define FORCE_AUTO 0x0010    /* pick one of these three */&lt;BR&gt;#define FORCE_HALF 0x0020&lt;BR&gt;#define FORCE_FULL 0x0030&lt;/P&gt; &lt;P&gt;/* Information that need to be kept for each board. */&lt;BR&gt;struct net_local {&lt;BR&gt; struct net_device_stats stats;&lt;BR&gt; int chip_type;  /* one of: CS8900, CS8920, CS8920M */&lt;BR&gt; char chip_revision; /* revision letter of the chip (&#39;A&#39;...) */&lt;BR&gt; int send_cmd;  /* the proper send command: TX_NOW, TX_AFTER_381, or TX_AFTER_ALL */&lt;BR&gt; int auto_neg_cnf; /* auto-negotiation word from EEPROM */&lt;BR&gt; int adapter_cnf; /* adapter configuration from EEPROM */&lt;BR&gt; int isa_config;  /* ISA configuration from EEPROM */&lt;BR&gt; int irq_map;  /* IRQ map from EEPROM */&lt;BR&gt; int rx_mode;  /* what mode are we in? 0, RX_MULTCAST_ACCEPT, or RX_ALL_ACCEPT */&lt;BR&gt; int curr_rx_cfg; /* a copy of PP_RxCFG */&lt;BR&gt; int linectl;  /* either 0 or LOW_RX_SQUELCH, depending on configuration. */&lt;BR&gt; int send_underrun; /* keep track of how many underruns in a row we get */&lt;BR&gt; int force;  /* force various values; see FORCE* above. */&lt;BR&gt; spinlock_t lock;&lt;BR&gt;#if ALLOW_DMA&lt;BR&gt; int use_dma;  /* Flag: we&#39;re using dma */&lt;BR&gt; int dma;  /* DMA channel */&lt;BR&gt; int dmasize;  /* 16 or 64 */&lt;BR&gt; unsigned char *dma_buff; /* points to the beginning of the buffer */&lt;BR&gt; unsigned char *end_dma_buff; /* points to the end of the buffer */&lt;BR&gt; unsigned char *rx_dma_ptr; /* points to the next packet  */&lt;BR&gt;#endif&lt;BR&gt;};&lt;/P&gt; &lt;P&gt;/* Index to functions, as function prototypes. */&lt;/P&gt; &lt;P&gt;extern int cs89x0_probe(struct net_device *dev);&lt;/P&gt; &lt;P&gt;static int cs89x0_probe1(struct net_device *dev, int ioaddr);&lt;BR&gt;static int net_open(struct net_device *dev);&lt;BR&gt;static int net_send_packet(struct sk_buff *skb, struct net_device *dev);&lt;BR&gt;static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs);&lt;BR&gt;static void set_multicast_list(struct net_device *dev);&lt;BR&gt;static void net_timeout(struct net_device *dev);&lt;BR&gt;static void net_rx(struct net_device *dev);&lt;BR&gt;static int net_close(struct net_device *dev);&lt;BR&gt;static struct net_device_stats *net_get_stats(struct net_device *dev);&lt;BR&gt;static void reset_chip(struct net_device *dev);&lt;BR&gt;static int get_eeprom_data(struct net_device *dev, int off, int len, int *buffer);&lt;BR&gt;static int get_eeprom_cksum(int off, int len, int *buffer);&lt;BR&gt;static int set_mac_address(struct net_device *dev, void *addr);&lt;BR&gt;static void count_rx_errors(int status, struct net_local *lp);&lt;BR&gt;#if ALLOW_DMA&lt;BR&gt;static void get_dma_channel(struct net_device *dev);&lt;BR&gt;static void release_dma_buff(struct net_local *lp);&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt;/* Example routines you must write ;-&amp;gt;. */&lt;BR&gt;#define tx_done(dev) 1&lt;/P&gt; &lt;P&gt;/*&lt;BR&gt; * Permit &#39;cs89x0_dma=N&#39; in the kernel boot environment&lt;BR&gt; */&lt;BR&gt;#if !defined(MODULE) &amp;amp;&amp;amp; (ALLOW_DMA != 0)&lt;BR&gt;static int g_cs89x0_dma;&lt;/P&gt; &lt;P&gt;static int __init dma_fn(char *str)&lt;BR&gt;{&lt;BR&gt; g_cs89x0_dma = simple_strtol(str,NULL,0);&lt;BR&gt; return 1;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;__setup(&quot;cs89x0_dma=&quot;, dma_fn);&lt;BR&gt;#endif /* !defined(MODULE) &amp;amp;&amp;amp; (ALLOW_DMA != 0) */&lt;/P&gt; &lt;P&gt;&lt;BR&gt;/* Check for a network adaptor of this type, and return &#39;0&#39; iff one exists.&lt;BR&gt;   If dev-&amp;gt;base_addr == 0, probe all likely locations.&lt;BR&gt;   If dev-&amp;gt;base_addr == 1, always return failure.&lt;BR&gt;   If dev-&amp;gt;base_addr == 2, allocate space for the device and return success&lt;BR&gt;   (detachable devices only).&lt;BR&gt;   Return 0 on success.&lt;BR&gt;   */&lt;/P&gt; &lt;P&gt;&lt;BR&gt;#ifdef S3C2410_HWINIT_ETHER_INFORMATION&lt;BR&gt;int __init S3C2410_HWinit()&lt;BR&gt;{&lt;/P&gt; &lt;P&gt;&lt;BR&gt;/******* S3C2410  *****************/&lt;BR&gt;#define CS8900_Tacs (0x0) // 0clk&lt;BR&gt;#define CS8900_Tcos (0x3) // 4clk&lt;BR&gt;#define CS8900_Tacc (0x7) // 14clk&lt;BR&gt;#define CS8900_Tcoh (0x1) // 1clk&lt;BR&gt;#define CS8900_Tah (0x3) // 4clk&lt;BR&gt;#define CS8900_Tacp (0x3) // 6clk&lt;BR&gt;#define CS8900_PMC (0x0) // normal(1data)&lt;/P&gt; &lt;P&gt;&lt;BR&gt; // initialize CS8900&lt;/P&gt; &lt;P&gt;        rBWSCON  = (rBWSCON&amp;amp;~(0xf&amp;lt;&amp;lt;12))|(0xd&amp;lt;&amp;lt;12);  /*  nWAIT */&lt;BR&gt; // rGSTATUS0;  /* Read Only */&lt;BR&gt;        rGPACON;  /* look up uncomress.h */&lt;BR&gt;   rGPGCON = (rGPGCON&amp;amp;~(3&amp;lt;&amp;lt;2))|(2&amp;lt;&amp;lt;2); /* EXINT 9 */&lt;BR&gt; rBANKCON3=((CS8900_Tacs&amp;lt;&amp;lt;13)+(CS8900_Tcos&amp;lt;&amp;lt;11)+(CS8900_Tacc&amp;lt;&amp;lt;8)&lt;BR&gt;     +(CS8900_Tcoh&amp;lt;&amp;lt;6)+(CS8900_Tah&amp;lt;&amp;lt;4)+(CS8900_Tacp&amp;lt;&amp;lt;2)+(CS8900_PMC));&lt;BR&gt;   rEXTINT1 = (rEXTINT1&amp;amp;~(7&amp;lt;&amp;lt;4))|(4&amp;lt;&amp;lt;4); /* Rising Edge Detect Mode */&lt;BR&gt; return 0;&lt;BR&gt;}&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt;int __init &lt;FONT color=#ff0000&gt;&lt;STRONG&gt;cs89x0_probe&lt;/STRONG&gt;&lt;/FONT&gt;(struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; int i;&lt;BR&gt; int base_addr = dev ? dev-&amp;gt;base_addr : 0;&lt;/P&gt; &lt;P&gt; SET_MODULE_OWNER(dev);&lt;/P&gt; &lt;P&gt;        // initialize CS8900&lt;BR&gt; if (net_debug)&lt;BR&gt;  printk(&quot;cs89x0:cs89x0_probe(0x%x)n&quot;, base_addr);&lt;/P&gt; &lt;P&gt; if (base_addr &amp;gt; 0x1ff)  /* Check a single specified location. */&lt;BR&gt;  return cs89x0_probe1(dev, base_addr);&lt;BR&gt; else if (base_addr != 0) /* Don&#39;t probe at all. */&lt;BR&gt;  return -ENXIO;&lt;/P&gt; &lt;P&gt; for (i = 0; netcard_portlist[i]; i++) {&lt;BR&gt;  if (&lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#ff6600&gt;cs89x0_probe1&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(dev, netcard_portlist[i]) == 0)&lt;BR&gt;   return 0;&lt;BR&gt; }&lt;BR&gt; printk(KERN_WARNING &quot;cs89x0: no cs8900 or cs8920 detected.  Be sure to disable PnP with SETUPn&quot;);&lt;BR&gt; return -ENODEV;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static int&lt;BR&gt;readreg(struct net_device *dev, int portno)&lt;BR&gt;{&lt;BR&gt; outw(portno, dev-&amp;gt;base_addr + ADD_PORT);&lt;BR&gt; return inw(dev-&amp;gt;base_addr + DATA_PORT);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;writereg(struct net_device *dev, int portno, int value)&lt;BR&gt;{&lt;BR&gt; outw(portno, dev-&amp;gt;base_addr + ADD_PORT);&lt;BR&gt; outw(value, dev-&amp;gt;base_addr + DATA_PORT);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static int&lt;BR&gt;readword(struct net_device *dev, int portno)&lt;BR&gt;{&lt;BR&gt; return inw(dev-&amp;gt;base_addr + portno);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;writeword(struct net_device *dev, int portno, int value)&lt;BR&gt;{&lt;BR&gt; outw(value, dev-&amp;gt;base_addr + portno);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static int __init&lt;BR&gt;wait_eeprom_ready(struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; int timeout = jiffies;&lt;BR&gt; /* check to see if the EEPROM is ready, a timeout is used -&lt;BR&gt;    just in case EEPROM is ready when SI_BUSY in the&lt;BR&gt;    PP_SelfST is clear */&lt;BR&gt; while(readreg(dev, PP_SelfST) &amp;amp; SI_BUSY)&lt;BR&gt;  if (jiffies - timeout &amp;gt;= 40)&lt;BR&gt;   return -1;&lt;BR&gt; return 0;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static int __init&lt;BR&gt;get_eeprom_data(struct net_device *dev, int off, int len, int *buffer)&lt;BR&gt;{&lt;BR&gt; int i;&lt;/P&gt; &lt;P&gt; if (net_debug &amp;gt; 3) printk(&quot;EEPROM data from %x for %x:n&quot;,off,len);&lt;BR&gt; for (i = 0; i &amp;lt; len; i++) {&lt;BR&gt;  if (wait_eeprom_ready(dev) &amp;lt; 0) return -1;&lt;BR&gt;  /* Now send the EEPROM read command and EEPROM location to read */&lt;BR&gt;  writereg(dev, PP_EECMD, (off + i) | EEPROM_READ_CMD);&lt;BR&gt;  if (wait_eeprom_ready(dev) &amp;lt; 0) return -1;&lt;BR&gt;  buffer[i] = readreg(dev, PP_EEData);&lt;BR&gt;  if (net_debug &amp;gt; 3) printk(&quot;%04x &quot;, buffer[i]);&lt;BR&gt; }&lt;BR&gt; if (net_debug &amp;gt; 3) printk(&quot;n&quot;);&lt;BR&gt;        return 0;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static int  __init&lt;BR&gt;get_eeprom_cksum(int off, int len, int *buffer)&lt;BR&gt;{&lt;BR&gt; int i, cksum;&lt;/P&gt; &lt;P&gt; cksum = 0;&lt;BR&gt; for (i = 0; i &amp;lt; len; i++)&lt;BR&gt;  cksum += buffer[i];&lt;BR&gt; cksum &amp;amp;= 0xffff;&lt;BR&gt; if (cksum == 0)&lt;BR&gt;  return 0;&lt;BR&gt; return -1;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;/* This is the real probe routine.  Linux has a history of friendly device&lt;BR&gt;   probes on the ISA bus.  A good device probes avoids doing writes, and&lt;BR&gt;   verifies that the correct device exists and functions.&lt;BR&gt;   Return 0 on success.&lt;BR&gt; */&lt;/P&gt; &lt;P&gt;static int __init&lt;BR&gt;&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;cs89x0_probe1&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(struct net_device *dev, int ioaddr)&lt;BR&gt;{&lt;BR&gt; struct net_local *lp;&lt;BR&gt; static unsigned version_printed;&lt;BR&gt; int i;&lt;BR&gt; unsigned rev_type = 0;&lt;BR&gt; int eeprom_buff[CHKSUM_LEN];&lt;BR&gt; int retval;&lt;/P&gt; &lt;P&gt; /* Initialize the device structure. */&lt;BR&gt; if (dev-&amp;gt;priv == NULL) {&lt;BR&gt;  dev-&amp;gt;priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);&lt;BR&gt;  if (dev-&amp;gt;priv == 0) {&lt;BR&gt;   retval = -ENOMEM;&lt;BR&gt;   goto out;&lt;BR&gt;  }&lt;BR&gt;  lp = (struct net_local *)dev-&amp;gt;priv;&lt;BR&gt;  memset(lp, 0, sizeof(*lp));&lt;BR&gt;  spin_lock_init(&amp;amp;lp-&amp;gt;lock);&lt;BR&gt;#if !defined(MODULE) &amp;amp;&amp;amp; (ALLOW_DMA != 0)&lt;BR&gt;  if (g_cs89x0_dma) {&lt;BR&gt;   lp-&amp;gt;use_dma = 1;&lt;BR&gt;   lp-&amp;gt;dma = g_cs89x0_dma;&lt;BR&gt;   lp-&amp;gt;dmasize = 16; /* Could make this an option... */&lt;BR&gt;  }&lt;BR&gt;#endif&lt;BR&gt;        }&lt;BR&gt; lp = (struct net_local *)dev-&amp;gt;priv;&lt;/P&gt; &lt;P&gt; /* Grab the region so we can find another board if autoIRQ fails. */&lt;BR&gt; if (!&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;request_region&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(ioaddr &amp;amp; ~3, NETCARD_IO_EXTENT, dev-&amp;gt;name)) {&lt;BR&gt;  printk(KERN_ERR &quot;%s: request_region(0x%x, 0x%x) failedn&quot;,&lt;BR&gt;    dev-&amp;gt;name, ioaddr, NETCARD_IO_EXTENT);&lt;BR&gt;  retval = -EBUSY;&lt;BR&gt;  goto out1;&lt;BR&gt; }&lt;/P&gt; &lt;P&gt; /* if they give us an odd I/O address, then do ONE write to&lt;BR&gt;           the address port, to get it back to address zero, where we&lt;BR&gt;           expect to find the EISA signature word. An IO with a base of 0x3&lt;BR&gt;     will skip the test for the ADD_PORT. */&lt;BR&gt; if (ioaddr &amp;amp; 1) {&lt;BR&gt;  if (net_debug &amp;gt; 1)&lt;BR&gt;   printk(KERN_INFO &quot;%s: odd ioaddr 0x%xn&quot;, dev-&amp;gt;name, ioaddr);&lt;BR&gt;          if ((ioaddr &amp;amp; 2) != 2)&lt;BR&gt;          if ((inw((ioaddr &amp;amp; ~3)+ ADD_PORT) &amp;amp; ADD_MASK) != ADD_SIG) {&lt;BR&gt;    printk(KERN_ERR &quot;%s: bad signature 0x%xn&quot;,&lt;BR&gt;     dev-&amp;gt;name, inw((ioaddr &amp;amp; ~3)+ ADD_PORT));&lt;BR&gt;           retval = -ENODEV;&lt;BR&gt;    goto out2;&lt;BR&gt;   }&lt;BR&gt;   ioaddr &amp;amp;= ~3;&lt;BR&gt; }&lt;BR&gt; &lt;BR&gt; outw(PP_ChipID, ioaddr + ADD_PORT);&lt;BR&gt;       &lt;BR&gt;  if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG) {&lt;BR&gt;  printk(KERN_ERR &quot;%s: incorrect signature 0x%xn&quot;,&lt;BR&gt;   dev-&amp;gt;name, inw(ioaddr + DATA_PORT));&lt;BR&gt;  retval = -ENODEV;&lt;BR&gt;    goto out2;&lt;BR&gt; }&lt;BR&gt; &lt;BR&gt; /* Fill in the &#39;dev&#39; fields. */&lt;BR&gt; dev-&amp;gt;base_addr = ioaddr;&lt;/P&gt; &lt;P&gt; /* get the chip type */&lt;BR&gt; rev_type = readreg(dev, PRODUCT_ID_ADD);&lt;/P&gt; &lt;P&gt; lp-&amp;gt;chip_type = rev_type &amp;amp;~ REVISON_BITS;&lt;BR&gt; lp-&amp;gt;chip_revision = ((rev_type &amp;amp; REVISON_BITS) &amp;gt;&amp;gt; 8) + &#39;A&#39;;&lt;/P&gt; &lt;P&gt; /* Check the chip type and revision in order to set the correct send command&lt;BR&gt; CS8920 revision C and CS8900 revision F can use the faster send. */&lt;BR&gt; lp-&amp;gt;send_cmd = TX_AFTER_381;&lt;BR&gt; if (lp-&amp;gt;chip_type == CS8900 &amp;amp;&amp;amp; lp-&amp;gt;chip_revision &amp;gt;= &#39;F&#39;)&lt;BR&gt;  lp-&amp;gt;send_cmd = TX_NOW;&lt;BR&gt; if (lp-&amp;gt;chip_type != CS8900 &amp;amp;&amp;amp; lp-&amp;gt;chip_revision &amp;gt;= &#39;C&#39;)&lt;BR&gt;  lp-&amp;gt;send_cmd = TX_NOW;&lt;/P&gt; &lt;P&gt; if (net_debug  &amp;amp;&amp;amp;  version_printed++ == 0)&lt;BR&gt;  printk(version);&lt;/P&gt; &lt;P&gt; printk(KERN_INFO &quot;%s: cs89%c0%s rev %c found at %#3lx &quot;,&lt;BR&gt;        dev-&amp;gt;name,&lt;BR&gt;        lp-&amp;gt;chip_type==CS8900?&#39;0&#39;:&#39;2&#39;,&lt;BR&gt;        lp-&amp;gt;chip_type==CS8920M?&quot;M&quot;:&quot;&quot;,&lt;BR&gt;        lp-&amp;gt;chip_revision,&lt;BR&gt;        dev-&amp;gt;base_addr);&lt;/P&gt; &lt;P&gt; reset_chip(dev);&lt;/P&gt; &lt;P&gt;#ifdef CONFIG_ARCH_S3C2410&lt;BR&gt; /* The SMDK2410 eval board does not have an EEPROM attached&lt;BR&gt;    to the CS8900A.... so set some defaults */&lt;BR&gt; /* Force a 10 Base-T connection. */&lt;BR&gt; lp-&amp;gt;force = FORCE_RJ45;&lt;BR&gt; lp-&amp;gt;auto_neg_cnf = IMM_BIT;  /* don&#39;t error if no cable plugged */&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt;        /* Here we read the current configuration of the chip. If there&lt;BR&gt;    is no Extended EEPROM then the idea is to not disturb the chip&lt;BR&gt;    configuration, it should have been correctly setup by automatic&lt;BR&gt;    EEPROM read on reset. So, if the chip says it read the EEPROM&lt;BR&gt;    the driver will always do *something* instead of complain that&lt;BR&gt;    adapter_cnf is 0. */&lt;BR&gt;        if ((readreg(dev, PP_SelfST) &amp;amp; (EEPROM_OK | EEPROM_PRESENT)) == &lt;BR&gt;       (EEPROM_OK|EEPROM_PRESENT)) {&lt;BR&gt;         /* Load the MAC. */&lt;BR&gt;  for (i=0; i &amp;lt; ETH_ALEN/2; i++) {&lt;BR&gt;                 unsigned int Addr;&lt;BR&gt;   Addr = readreg(dev, PP_IA+i*2);&lt;BR&gt;          dev-&amp;gt;dev_addr[i*2] = Addr &amp;amp; 0xFF;&lt;BR&gt;          dev-&amp;gt;dev_addr[i*2+1] = Addr &amp;gt;&amp;gt; 8;&lt;BR&gt;  }&lt;BR&gt;   &lt;BR&gt;     /* Load the Adapter Configuration. &lt;BR&gt;     Note:  Barring any more specific information from some &lt;BR&gt;     other source (ie EEPROM+Schematics), we would not know &lt;BR&gt;     how to operate a 10Base2 interface on the AUI port. &lt;BR&gt;     However, since we  do read the status of HCB1 and use &lt;BR&gt;     settings that always result in calls to control_dc_dc(dev,0) &lt;BR&gt;     a BNC interface should work if the enable pin &lt;BR&gt;     (dc/dc converter) is on HCB1. It will be called AUI &lt;BR&gt;     however. */&lt;BR&gt;    &lt;BR&gt;  lp-&amp;gt;adapter_cnf = 0;&lt;BR&gt;  i = readreg(dev, PP_LineCTL);&lt;BR&gt;  /* Preserve the setting of the HCB1 pin. */&lt;BR&gt;  if ((i &amp;amp; (HCB1 | HCB1_ENBL)) ==  (HCB1 | HCB1_ENBL))&lt;BR&gt;   lp-&amp;gt;adapter_cnf |= A_CNF_DC_DC_POLARITY;&lt;BR&gt;  /* Save the sqelch bit */&lt;BR&gt;  if ((i &amp;amp; LOW_RX_SQUELCH) == LOW_RX_SQUELCH)&lt;BR&gt;   lp-&amp;gt;adapter_cnf |= A_CNF_EXTND_10B_2 | A_CNF_LOW_RX_SQUELCH;&lt;BR&gt;  /* Check if the card is in 10Base-t only mode */&lt;BR&gt;  if ((i &amp;amp; (AUI_ONLY | AUTO_AUI_10BASET)) == 0)&lt;BR&gt;   lp-&amp;gt;adapter_cnf |=  A_CNF_10B_T | A_CNF_MEDIA_10B_T;&lt;BR&gt;  /* Check if the card is in AUI only mode */&lt;BR&gt;  if ((i &amp;amp; (AUI_ONLY | AUTO_AUI_10BASET)) == AUI_ONLY)&lt;BR&gt;   lp-&amp;gt;adapter_cnf |=  A_CNF_AUI | A_CNF_MEDIA_AUI;&lt;BR&gt;  /* Check if the card is in Auto mode. */&lt;BR&gt;  if ((i &amp;amp; (AUI_ONLY | AUTO_AUI_10BASET)) == AUTO_AUI_10BASET)&lt;BR&gt;   lp-&amp;gt;adapter_cnf |=  A_CNF_AUI | A_CNF_10B_T | &lt;BR&gt;   A_CNF_MEDIA_AUI | A_CNF_MEDIA_10B_T | A_CNF_MEDIA_AUTO;&lt;BR&gt;  &lt;BR&gt;  if (net_debug &amp;gt; 1)&lt;BR&gt;   printk(KERN_INFO &quot;%s: PP_LineCTL=0x%x, adapter_cnf=0x%xn&quot;,&lt;BR&gt;     dev-&amp;gt;name, i, lp-&amp;gt;adapter_cnf);&lt;/P&gt; &lt;P&gt;  /* IRQ. Other chips already probe, see below. */&lt;BR&gt;  if (lp-&amp;gt;chip_type == CS8900) &lt;BR&gt;   lp-&amp;gt;isa_config = readreg(dev, PP_CS8900_ISAINT) &amp;amp; INT_NO_MASK;&lt;BR&gt;    &lt;BR&gt;  printk( &quot;[Cirrus EEPROM] &quot;);&lt;BR&gt; }&lt;/P&gt; &lt;P&gt;        printk(&quot;n&quot;);&lt;BR&gt;   &lt;BR&gt; /* First check to see if an EEPROM is attached. */&lt;BR&gt; if ((readreg(dev, PP_SelfST) &amp;amp; EEPROM_PRESENT) == 0)&lt;BR&gt;  printk(KERN_WARNING &quot;cs89x0: No EEPROM, relying on command line....n&quot;);&lt;BR&gt; else if (get_eeprom_data(dev, START_EEPROM_DATA,CHKSUM_LEN,eeprom_buff) &amp;lt; 0) {&lt;BR&gt;  printk(KERN_WARNING &quot;ncs89x0: EEPROM read failed, relying on command line.n&quot;);&lt;BR&gt;        } else if (get_eeprom_cksum(START_EEPROM_DATA,CHKSUM_LEN,eeprom_buff) &amp;lt; 0) {&lt;BR&gt;  /* Check if the chip was able to read its own configuration starting&lt;BR&gt;     at 0 in the EEPROM*/&lt;BR&gt;  if ((readreg(dev, PP_SelfST) &amp;amp; (EEPROM_OK | EEPROM_PRESENT)) !=&lt;BR&gt;      (EEPROM_OK|EEPROM_PRESENT)) &lt;BR&gt;                 printk(KERN_WARNING &quot;cs89x0: Extended EEPROM checksum bad and no Cirrus EEPROM, relying on command linen&quot;);&lt;BR&gt;     &lt;BR&gt;        } else {&lt;BR&gt;  /* This reads an extended EEPROM that is not documented&lt;BR&gt;     in the CS8900 datasheet. */&lt;BR&gt;  &lt;BR&gt;                /* get transmission control word  but keep the autonegotiation bits */&lt;BR&gt;                if (!lp-&amp;gt;auto_neg_cnf) lp-&amp;gt;auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET/2];&lt;BR&gt;                /* Store adapter configuration */&lt;BR&gt;                if (!lp-&amp;gt;adapter_cnf) lp-&amp;gt;adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET/2];&lt;BR&gt;                /* Store ISA configuration */&lt;BR&gt;                lp-&amp;gt;isa_config = eeprom_buff[ISA_CNF_OFFSET/2];&lt;BR&gt;                dev-&amp;gt;mem_start = eeprom_buff[PACKET_PAGE_OFFSET/2] &amp;lt;&amp;lt; 8;&lt;/P&gt; &lt;P&gt;                /* eeprom_buff has 32-bit ints, so we can&#39;t just memcpy it */&lt;BR&gt;                /* store the initial memory base address */&lt;BR&gt;                for (i = 0; i &amp;lt; ETH_ALEN/2; i++) {&lt;BR&gt;                        dev-&amp;gt;dev_addr[i*2] = eeprom_buff[i];&lt;BR&gt;                        dev-&amp;gt;dev_addr[i*2+1] = eeprom_buff[i] &amp;gt;&amp;gt; 8;&lt;BR&gt;                }&lt;BR&gt;  if (net_debug &amp;gt; 1)&lt;BR&gt;   printk(KERN_DEBUG &quot;%s: new adapter_cnf: 0x%xn&quot;,&lt;BR&gt;    dev-&amp;gt;name, lp-&amp;gt;adapter_cnf);&lt;BR&gt;        }&lt;/P&gt; &lt;P&gt;        /* allow them to force multiple transceivers.  If they force multiple, autosense */&lt;BR&gt;        {&lt;BR&gt;  int count = 0;&lt;BR&gt;  if (lp-&amp;gt;force &amp;amp; FORCE_RJ45) {lp-&amp;gt;adapter_cnf |= A_CNF_10B_T; count++; }&lt;BR&gt;  if (lp-&amp;gt;force &amp;amp; FORCE_AUI)  {lp-&amp;gt;adapter_cnf |= A_CNF_AUI; count++; }&lt;BR&gt;  if (lp-&amp;gt;force &amp;amp; FORCE_BNC) {lp-&amp;gt;adapter_cnf |= A_CNF_10B_2; count++; }&lt;BR&gt;  if (count &amp;gt; 1)   {lp-&amp;gt;adapter_cnf |= A_CNF_MEDIA_AUTO; }&lt;BR&gt;  else if (lp-&amp;gt;force &amp;amp; FORCE_RJ45){lp-&amp;gt;adapter_cnf |= A_CNF_MEDIA_10B_T; }&lt;BR&gt;  else if (lp-&amp;gt;force &amp;amp; FORCE_AUI) {lp-&amp;gt;adapter_cnf |= A_CNF_MEDIA_AUI; }&lt;BR&gt;  else if (lp-&amp;gt;force &amp;amp; FORCE_BNC) {lp-&amp;gt;adapter_cnf |= A_CNF_MEDIA_10B_2; }&lt;BR&gt;        }&lt;/P&gt; &lt;P&gt; if (net_debug &amp;gt; 1)&lt;BR&gt;  printk(KERN_DEBUG &quot;%s: after force 0x%x, adapter_cnf=0x%xn&quot;,&lt;BR&gt;   dev-&amp;gt;name, lp-&amp;gt;force, lp-&amp;gt;adapter_cnf);&lt;/P&gt; &lt;P&gt;        /* FIXME: We don&#39;t let you set dc-dc polarity or low RX squelch from the command line: add it here */&lt;/P&gt; &lt;P&gt;        /* FIXME: We don&#39;t let you set the IMM bit from the command line: add it to lp-&amp;gt;auto_neg_cnf here */&lt;/P&gt; &lt;P&gt;        /* FIXME: we don&#39;t set the Ethernet address on the command line.  Use&lt;BR&gt;           ifconfig IFACE hw ether AABBCCDDEEFF */&lt;/P&gt; &lt;P&gt;    printk(KERN_INFO &quot;cs89x0 media %s%s&quot;,&lt;BR&gt;    (lp-&amp;gt;adapter_cnf &amp;amp; A_CNF_10B_T)?&quot;RJ-45&quot;:&quot;&quot;,&lt;BR&gt;    (lp-&amp;gt;adapter_cnf &amp;amp; A_CNF_AUI)?&quot;AUI&quot;:&quot;&quot;);&lt;/P&gt; &lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6666&gt;    dev-&amp;gt;dev_addr[0] = 0x00;&lt;BR&gt;    dev-&amp;gt;dev_addr[1] = 0x00;&lt;BR&gt;    dev-&amp;gt;dev_addr[2] = 0xc0;&lt;BR&gt;    dev-&amp;gt;dev_addr[3] = 0xff;&lt;BR&gt;    dev-&amp;gt;dev_addr[4] = 0xee;&lt;BR&gt;    dev-&amp;gt;dev_addr[5] = 0x08;&lt;BR&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;    set_mac_address(dev, dev-&amp;gt;dev_addr);&lt;/P&gt; &lt;P&gt;    dev-&amp;gt;irq = IRQ_LAN;&lt;BR&gt;    printk(&quot;, IRQ %d&quot;, dev-&amp;gt;irq);&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;P&gt; &lt;STRONG&gt;&lt;FONT color=#3366ff&gt;&lt;EM&gt;dev-&amp;gt;open&lt;/EM&gt;&lt;/FONT&gt;&lt;/STRONG&gt;  = &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;net_open&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;;&lt;BR&gt; &lt;FONT color=#3366ff&gt;&lt;STRONG&gt;&lt;EM&gt;dev-&amp;gt;stop&lt;/EM&gt;&lt;/STRONG&gt; &lt;/FONT&gt; = &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;net_close&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;;&lt;BR&gt; &lt;FONT color=#3366ff&gt;&lt;STRONG&gt;&lt;EM&gt;dev-&amp;gt;tx_timeout&lt;/EM&gt;&lt;/STRONG&gt; &lt;/FONT&gt; = &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;net_timeout&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;;&lt;BR&gt; &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;dev-&amp;gt;watchdog_timeo&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt; = &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;HZ&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;;&lt;BR&gt; &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;dev-&amp;gt;hard_start_xmit&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;  = &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;net_send_packet&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;;&lt;BR&gt; &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;dev-&amp;gt;get_stats&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;  = &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;net_get_stats&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;;&lt;BR&gt; &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;dev-&amp;gt;set_multicast_list&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt; =&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt; set_multicast_list&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;;&lt;BR&gt; &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;dev-&amp;gt;set_mac_address&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;  = &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;set_mac_address&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;;&lt;/P&gt; &lt;P&gt; /* Fill in the fields of the device structure with ethernet values. */&lt;BR&gt; &lt;FONT color=#3366ff&gt;&lt;EM&gt;&lt;STRONG&gt;ether_setup&lt;/STRONG&gt;&lt;/EM&gt;&lt;/FONT&gt;(dev);&lt;/P&gt; &lt;P&gt; printk(&quot;n&quot;);&lt;BR&gt; if (net_debug)&lt;BR&gt;  printk(&quot;cs89x0_probe1() successfuln&quot;);&lt;BR&gt; return 0;&lt;BR&gt;out2:&lt;BR&gt; release_region(ioaddr &amp;amp; ~3, NETCARD_IO_EXTENT);&lt;BR&gt;out1:&lt;BR&gt; kfree(dev-&amp;gt;priv);&lt;BR&gt; dev-&amp;gt;priv = 0;&lt;BR&gt;out:&lt;BR&gt; return retval;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;&lt;BR&gt;/*********************************&lt;BR&gt; * This page contains DMA routines&lt;BR&gt;**********************************/&lt;/P&gt; &lt;P&gt;#if ALLOW_DMA&lt;/P&gt; &lt;P&gt;#define dma_page_eq(ptr1, ptr2) ((long)(ptr1)&amp;gt;&amp;gt;17 == (long)(ptr2)&amp;gt;&amp;gt;17)&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;get_dma_channel(struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; struct net_local *lp = (struct net_local *)dev-&amp;gt;priv;&lt;/P&gt; &lt;P&gt; if (lp-&amp;gt;dma) {&lt;BR&gt;  dev-&amp;gt;dma = lp-&amp;gt;dma;&lt;BR&gt;  lp-&amp;gt;isa_config |= ISA_RxDMA;&lt;BR&gt; } else {&lt;BR&gt;  if ((lp-&amp;gt;isa_config &amp;amp; ANY_ISA_DMA) == 0)&lt;BR&gt;   return;&lt;BR&gt;  dev-&amp;gt;dma = lp-&amp;gt;isa_config &amp;amp; DMA_NO_MASK;&lt;BR&gt;  if (lp-&amp;gt;chip_type == CS8900)&lt;BR&gt;   dev-&amp;gt;dma += 5;&lt;BR&gt;  if (dev-&amp;gt;dma &amp;lt; 5 || dev-&amp;gt;dma &amp;gt; 7) {&lt;BR&gt;   lp-&amp;gt;isa_config &amp;amp;= ~ANY_ISA_DMA;&lt;BR&gt;   return;&lt;BR&gt;  }&lt;BR&gt; }&lt;BR&gt; return;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;write_dma(struct net_device *dev, int chip_type, int dma)&lt;BR&gt;{&lt;BR&gt; struct net_local *lp = (struct net_local *)dev-&amp;gt;priv;&lt;BR&gt; if ((lp-&amp;gt;isa_config &amp;amp; ANY_ISA_DMA) == 0)&lt;BR&gt;  return;&lt;BR&gt; if (chip_type == CS8900) {&lt;BR&gt;  writereg(dev, PP_CS8900_ISADMA, dma-5);&lt;BR&gt; } else {&lt;BR&gt;  writereg(dev, PP_CS8920_ISADMA, dma);&lt;BR&gt; }&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;set_dma_cfg(struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; struct net_local *lp = (struct net_local *)dev-&amp;gt;priv;&lt;/P&gt; &lt;P&gt; if (lp-&amp;gt;use_dma) {&lt;BR&gt;  if ((lp-&amp;gt;isa_config &amp;amp; ANY_ISA_DMA) == 0) {&lt;BR&gt;   if (net_debug &amp;gt; 3)&lt;BR&gt;    printk(&quot;set_dma_cfg(): no DMAn&quot;);&lt;BR&gt;   return;&lt;BR&gt;  }&lt;BR&gt;  if (lp-&amp;gt;isa_config &amp;amp; ISA_RxDMA) {&lt;BR&gt;   lp-&amp;gt;curr_rx_cfg |= RX_DMA_ONLY;&lt;BR&gt;   if (net_debug &amp;gt; 3)&lt;BR&gt;    printk(&quot;set_dma_cfg(): RX_DMA_ONLYn&quot;);&lt;BR&gt;  } else {&lt;BR&gt;   lp-&amp;gt;curr_rx_cfg |= AUTO_RX_DMA; /* not that we support it... */&lt;BR&gt;   if (net_debug &amp;gt; 3)&lt;BR&gt;    printk(&quot;set_dma_cfg(): AUTO_RX_DMAn&quot;);&lt;BR&gt;  }&lt;BR&gt; }&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static int&lt;BR&gt;dma_bufcfg(struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; struct net_local *lp = (struct net_local *)dev-&amp;gt;priv;&lt;BR&gt; if (lp-&amp;gt;use_dma)&lt;BR&gt;  return (lp-&amp;gt;isa_config &amp;amp; ANY_ISA_DMA)? RX_DMA_ENBL : 0;&lt;BR&gt; else&lt;BR&gt;  return 0;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static int&lt;BR&gt;dma_busctl(struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; int retval = 0;&lt;BR&gt; struct net_local *lp = (struct net_local *)dev-&amp;gt;priv;&lt;BR&gt; if (lp-&amp;gt;use_dma) {&lt;BR&gt;  if (lp-&amp;gt;isa_config &amp;amp; ANY_ISA_DMA)&lt;BR&gt;   retval |= RESET_RX_DMA; /* Reset the DMA pointer */&lt;BR&gt;  if (lp-&amp;gt;isa_config &amp;amp; DMA_BURST)&lt;BR&gt;   retval |= DMA_BURST_MODE; /* Does ISA config specify DMA burst ? */&lt;BR&gt;  if (lp-&amp;gt;dmasize == 64)&lt;BR&gt;   retval |= RX_DMA_SIZE_64K; /* did they ask for 64K? */&lt;BR&gt;  retval |= MEMORY_ON; /* we need memory enabled to use DMA. */&lt;BR&gt; }&lt;BR&gt; return retval;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;dma_rx(struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; struct net_local *lp = (struct net_local *)dev-&amp;gt;priv;&lt;BR&gt; struct sk_buff *skb;&lt;BR&gt; int status, length;&lt;BR&gt; unsigned char *bp = lp-&amp;gt;rx_dma_ptr;&lt;/P&gt; &lt;P&gt; status = bp[0] + (bp[1]&amp;lt;&amp;lt;8);&lt;BR&gt; length = bp[2] + (bp[3]&amp;lt;&amp;lt;8);&lt;BR&gt; bp += 4;&lt;BR&gt; if (net_debug &amp;gt; 5) {&lt;BR&gt;  printk( &quot;%s: receiving DMA packet at %lx, status %x, length %xn&quot;,&lt;BR&gt;   dev-&amp;gt;name, (unsigned long)bp, status, length);&lt;BR&gt; }&lt;BR&gt; if ((status &amp;amp; RX_OK) == 0) {&lt;BR&gt;  count_rx_errors(status, lp);&lt;BR&gt;  goto skip_this_frame;&lt;BR&gt; }&lt;/P&gt; &lt;P&gt; /* Malloc up new buffer. */&lt;BR&gt; skb = dev_alloc_skb(length + 2);&lt;BR&gt; if (skb == NULL) {&lt;BR&gt;  if (net_debug) /* I don&#39;t think we want to do this to a stressed system */&lt;BR&gt;   printk(&quot;%s: Memory squeeze, dropping packet.n&quot;, dev-&amp;gt;name);&lt;BR&gt;  lp-&amp;gt;stats.rx_dropped++;&lt;/P&gt; &lt;P&gt;  /* AKPM: advance bp to the next frame */&lt;BR&gt;skip_this_frame:&lt;BR&gt;  bp += (length + 3) &amp;amp; ~3;&lt;BR&gt;  if (bp &amp;gt;= lp-&amp;gt;end_dma_buff) bp -= lp-&amp;gt;dmasize*1024;&lt;BR&gt;  lp-&amp;gt;rx_dma_ptr = bp;&lt;BR&gt;  return;&lt;BR&gt; }&lt;BR&gt; skb_reserve(skb, 2); /* longword align L3 header */&lt;BR&gt; skb-&amp;gt;dev = dev;&lt;/P&gt; &lt;P&gt; if (bp + length &amp;gt; lp-&amp;gt;end_dma_buff) {&lt;BR&gt;  int semi_cnt = lp-&amp;gt;end_dma_buff - bp;&lt;BR&gt;  memcpy(skb_put(skb,semi_cnt), bp, semi_cnt);&lt;BR&gt;  memcpy(skb_put(skb,length - semi_cnt), lp-&amp;gt;dma_buff,&lt;BR&gt;         length - semi_cnt);&lt;BR&gt; } else {&lt;BR&gt;  memcpy(skb_put(skb,length), bp, length);&lt;BR&gt; }&lt;BR&gt; bp += (length + 3) &amp;amp; ~3;&lt;BR&gt; if (bp &amp;gt;= lp-&amp;gt;end_dma_buff) bp -= lp-&amp;gt;dmasize*1024;&lt;BR&gt; lp-&amp;gt;rx_dma_ptr = bp;&lt;/P&gt; &lt;P&gt; if (net_debug &amp;gt; 3) {&lt;BR&gt;  printk( &quot;%s: received %d byte DMA packet of type %xn&quot;,&lt;BR&gt;   dev-&amp;gt;name, length,&lt;BR&gt;   (skb-&amp;gt;data[ETH_ALEN+ETH_ALEN] &amp;lt;&amp;lt; 8) | skb-&amp;gt;data[ETH_ALEN+ETH_ALEN+1]);&lt;BR&gt; }&lt;BR&gt;        skb-&amp;gt;protocol=eth_type_trans(skb,dev);&lt;BR&gt; netif_rx(skb);&lt;BR&gt; dev-&amp;gt;last_rx = jiffies;&lt;BR&gt; lp-&amp;gt;stats.rx_packets++;&lt;BR&gt; lp-&amp;gt;stats.rx_bytes += length;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;#endif /* ALLOW_DMA */&lt;/P&gt; &lt;P&gt;void  __init reset_chip(struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; struct net_local *lp = (struct net_local *)dev-&amp;gt;priv;&lt;BR&gt; int ioaddr = dev-&amp;gt;base_addr;&lt;BR&gt; int reset_start_time;&lt;/P&gt; &lt;P&gt; writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET);&lt;/P&gt; &lt;P&gt; /* wait 30 ms */&lt;BR&gt; current-&amp;gt;state = TASK_INTERRUPTIBLE;&lt;BR&gt; schedule_timeout(30*HZ/1000);&lt;/P&gt; &lt;P&gt; if (lp-&amp;gt;chip_type != CS8900) {&lt;BR&gt;  /* Hardware problem requires PNP registers to be reconfigured after a reset */&lt;BR&gt;  outw(PP_CS8920_ISAINT, ioaddr + ADD_PORT);&lt;BR&gt;  outb(dev-&amp;gt;irq, ioaddr + DATA_PORT);&lt;BR&gt;  outb(0,      ioaddr + DATA_PORT + 1);&lt;/P&gt; &lt;P&gt;  outw(PP_CS8920_ISAMemB, ioaddr + ADD_PORT);&lt;BR&gt;  outb((dev-&amp;gt;mem_start &amp;gt;&amp;gt; 16) &amp;amp; 0xff, ioaddr + DATA_PORT);&lt;BR&gt;  outb((dev-&amp;gt;mem_start &amp;gt;&amp;gt; 8) &amp;amp; 0xff,   ioaddr + DATA_PORT + 1);&lt;BR&gt; }&lt;BR&gt; /* Wait until the chip is reset */&lt;BR&gt; reset_start_time = jiffies;&lt;BR&gt; while( (readreg(dev, PP_SelfST) &amp;amp; INIT_DONE) == 0 &amp;amp;&amp;amp; jiffies - reset_start_time &amp;lt; 2)&lt;BR&gt;  ;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;&lt;BR&gt;static void&lt;BR&gt;control_dc_dc(struct net_device *dev, int on_not_off)&lt;BR&gt;{&lt;BR&gt; struct net_local *lp = (struct net_local *)dev-&amp;gt;priv;&lt;BR&gt; unsigned int selfcontrol;&lt;BR&gt; int timenow = jiffies;&lt;BR&gt; /* control the DC to DC convertor in the SelfControl register.  &lt;BR&gt;    Note: This is hooked up to a general purpose pin, might not&lt;BR&gt;    always be a DC to DC convertor. */&lt;/P&gt; &lt;P&gt; selfcontrol = HCB1_ENBL; /* Enable the HCB1 bit as an output */&lt;BR&gt; if (((lp-&amp;gt;adapter_cnf &amp;amp; A_CNF_DC_DC_POLARITY) != 0) ^ on_not_off)&lt;BR&gt;  selfcontrol |= HCB1;&lt;BR&gt; else&lt;BR&gt;  selfcontrol &amp;amp;= ~HCB1;&lt;BR&gt; writereg(dev, PP_SelfCTL, selfcontrol);&lt;/P&gt; &lt;P&gt; /* Wait for the DC/DC converter to power up - 500ms */&lt;BR&gt; while (jiffies - timenow &amp;lt; HZ)&lt;BR&gt;  ;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;#define DETECTED_NONE  0&lt;BR&gt;#define DETECTED_RJ45H 1&lt;BR&gt;#define DETECTED_RJ45F 2&lt;BR&gt;#define DETECTED_AUI   3&lt;BR&gt;#define DETECTED_BNC   4&lt;/P&gt; &lt;P&gt;static int&lt;BR&gt;detect_tp(struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; struct net_local *lp = (struct net_local *)dev-&amp;gt;priv;&lt;BR&gt; int timenow = jiffies;&lt;BR&gt; int fdx;&lt;/P&gt; &lt;P&gt; if (net_debug &amp;gt; 1) printk(&quot;%s: Attempting TPn&quot;, dev-&amp;gt;name);&lt;/P&gt; &lt;P&gt;        /* If connected to another full duplex capable 10-Base-T card the link pulses&lt;BR&gt;           seem to be lost when the auto detect bit in the LineCTL is set.&lt;BR&gt;           To overcome this the auto detect bit will be cleared whilst testing the&lt;BR&gt;           10-Base-T interface.  This would not be necessary for the sparrow chip but&lt;BR&gt;           is simpler to do it anyway. */&lt;BR&gt; writereg(dev, PP_LineCTL, lp-&amp;gt;linectl &amp;amp;~ AUI_ONLY);&lt;BR&gt; control_dc_dc(dev, 0);&lt;/P&gt; &lt;P&gt;        /* Delay for the hardware to work out if the TP cable is present - 150ms */&lt;BR&gt; for (timenow = jiffies; jiffies - timenow &amp;lt; 15; )&lt;BR&gt;                ;&lt;BR&gt; if ((readreg(dev, PP_LineST) &amp;amp; LINK_OK) == 0)&lt;BR&gt;  return DETECTED_NONE;&lt;/P&gt; &lt;P&gt; if (lp-&amp;gt;chip_type == CS8900) {&lt;BR&gt;                switch (lp-&amp;gt;force &amp;amp; 0xf0) {&lt;BR&gt;#if 0&lt;BR&gt;                case FORCE_AUTO:&lt;BR&gt;   printk(&quot;%s: cs8900 doesn&#39;t autonegotiaten&quot;,dev-&amp;gt;name);&lt;BR&gt;                        return DETECTED_NONE;&lt;BR&gt;#endif&lt;BR&gt;  /* CS8900 doesn&#39;t support AUTO, change to HALF*/&lt;BR&gt;                case FORCE_AUTO:&lt;BR&gt;   lp-&amp;gt;force &amp;amp;= ~FORCE_AUTO;&lt;BR&gt;                        lp-&amp;gt;force |= FORCE_HALF;&lt;BR&gt;   break;&lt;BR&gt;  case FORCE_HALF:&lt;BR&gt;   break;&lt;BR&gt;                case FORCE_FULL:&lt;BR&gt;   writereg(dev, PP_TestCTL, readreg(dev, PP_TestCTL) | FDX_8900);&lt;BR&gt;   break;&lt;BR&gt;                }&lt;BR&gt;  fdx = readreg(dev, PP_TestCTL) &amp;amp; FDX_8900;&lt;BR&gt; } else {&lt;BR&gt;  switch (lp-&amp;gt;force &amp;amp; 0xf0) {&lt;BR&gt;  case FORCE_AUTO:&lt;BR&gt;   lp-&amp;gt;auto_neg_cnf = AUTO_NEG_ENABLE;&lt;BR&gt;   break;&lt;BR&gt;  case FORCE_HALF:&lt;BR&gt;   lp-&amp;gt;auto_neg_cnf = 0;&lt;BR&gt;   break;&lt;BR&gt;  case FORCE_FULL:&lt;BR&gt;   lp-&amp;gt;auto_neg_cnf = RE_NEG_NOW | ALLOW_FDX;&lt;BR&gt;   break;&lt;BR&gt;                }&lt;/P&gt; &lt;P&gt;  writereg(dev, PP_AutoNegCTL, lp-&amp;gt;auto_neg_cnf &amp;amp; AUTO_NEG_MASK);&lt;/P&gt; &lt;P&gt;  if ((lp-&amp;gt;auto_neg_cnf &amp;amp; AUTO_NEG_BITS) == AUTO_NEG_ENABLE) {&lt;BR&gt;   printk(KERN_INFO &quot;%s: negotiating duplex...n&quot;,dev-&amp;gt;name);&lt;BR&gt;   while (readreg(dev, PP_AutoNegST) &amp;amp; AUTO_NEG_BUSY) {&lt;BR&gt;    if (jiffies - timenow &amp;gt; 4000) {&lt;BR&gt;     printk(KERN_ERR &quot;**** Full / half duplex auto-negotiation timed out ****n&quot;);&lt;BR&gt;     break;&lt;BR&gt;    }&lt;BR&gt;   }&lt;BR&gt;  }&lt;BR&gt;  fdx = readreg(dev, PP_AutoNegST) &amp;amp; FDX_ACTIVE;&lt;BR&gt; }&lt;BR&gt; if (fdx)&lt;BR&gt;  return DETECTED_RJ45F;&lt;BR&gt; else&lt;BR&gt;  return DETECTED_RJ45H;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;/* send a test packet - return true if carrier bits are ok */&lt;BR&gt;static int&lt;BR&gt;send_test_pkt(struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; char test_packet[] = { 0,0,0,0,0,0, 0,0,0,0,0,0,&lt;BR&gt;     0, 46, /* A 46 in network order */&lt;BR&gt;     0, 0, /* DSAP=0 &amp;amp; SSAP=0 fields */&lt;BR&gt;     0xf3, 0 /* Control (Test Req + P bit set) */ };&lt;BR&gt; long timenow = jiffies;&lt;/P&gt; &lt;P&gt; writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_TX_ON);&lt;/P&gt; &lt;P&gt; memcpy(test_packet,          dev-&amp;gt;dev_addr, ETH_ALEN);&lt;BR&gt; memcpy(test_packet+ETH_ALEN, dev-&amp;gt;dev_addr, ETH_ALEN);&lt;/P&gt; &lt;P&gt;        writeword(dev, TX_CMD_PORT, TX_AFTER_ALL);&lt;BR&gt;        writeword(dev, TX_LEN_PORT, ETH_ZLEN);&lt;/P&gt; &lt;P&gt; /* Test to see if the chip has allocated memory for the packet */&lt;BR&gt; while (jiffies - timenow &amp;lt; 5)&lt;BR&gt;  if (readreg(dev, PP_BusST) &amp;amp; READY_FOR_TX_NOW)&lt;BR&gt;   break;&lt;BR&gt; if (jiffies - timenow &amp;gt;= 5)&lt;BR&gt;  return 0; /* this shouldn&#39;t happen */&lt;/P&gt; &lt;P&gt; /* Write the contents of the packet */&lt;BR&gt; outsw(dev-&amp;gt;base_addr + TX_FRAME_PORT,test_packet,(ETH_ZLEN+1) &amp;gt;&amp;gt;1);&lt;/P&gt; &lt;P&gt; if (net_debug &amp;gt; 1) printk(&quot;Sending test packet &quot;);&lt;BR&gt; /* wait a couple of jiffies for packet to be received */&lt;BR&gt; for (timenow = jiffies; jiffies - timenow &amp;lt; 3; )&lt;BR&gt;                ;&lt;BR&gt;        if ((readreg(dev, PP_TxEvent) &amp;amp; TX_SEND_OK_BITS) == TX_OK) {&lt;BR&gt;                if (net_debug &amp;gt; 1) printk(&quot;succeededn&quot;);&lt;BR&gt;                return 1;&lt;BR&gt;        }&lt;BR&gt; if (net_debug &amp;gt; 1) printk(&quot;failedn&quot;);&lt;BR&gt; return 0;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;&lt;BR&gt;static int&lt;BR&gt;detect_aui(struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; struct net_local *lp = (struct net_local *)dev-&amp;gt;priv;&lt;/P&gt; &lt;P&gt; if (net_debug &amp;gt; 1) printk(&quot;%s: Attempting AUIn&quot;, dev-&amp;gt;name);&lt;BR&gt; control_dc_dc(dev, 0);&lt;/P&gt; &lt;P&gt; writereg(dev, PP_LineCTL, (lp-&amp;gt;linectl &amp;amp;~ AUTO_AUI_10BASET) | AUI_ONLY);&lt;/P&gt; &lt;P&gt; if (send_test_pkt(dev))&lt;BR&gt;  return DETECTED_AUI;&lt;BR&gt; else&lt;BR&gt;  return DETECTED_NONE;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static int&lt;BR&gt;detect_bnc(struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; struct net_local *lp = (struct net_local *)dev-&amp;gt;priv;&lt;/P&gt; &lt;P&gt; if (net_debug &amp;gt; 1) printk(&quot;%s: Attempting BNCn&quot;, dev-&amp;gt;name);&lt;BR&gt; control_dc_dc(dev, 1);&lt;/P&gt; &lt;P&gt; writereg(dev, PP_LineCTL, (lp-&amp;gt;linectl &amp;amp;~ AUTO_AUI_10BASET) | AUI_ONLY);&lt;/P&gt; &lt;P&gt; if (send_test_pkt(dev))&lt;BR&gt;  return DETECTED_BNC;&lt;BR&gt; else&lt;BR&gt;  return DETECTED_NONE;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;&lt;BR&gt;static void&lt;BR&gt;write_irq(struct net_device *dev, int chip_type, int irq)&lt;BR&gt;{&lt;BR&gt; int i;&lt;/P&gt; &lt;P&gt; if (chip_type == CS8900) {&lt;BR&gt;  /* Search the mapping table for the corresponding IRQ pin. */&lt;BR&gt;  for (i = 0; i != sizeof(cs8900_irq_map)/sizeof(cs8900_irq_map[0]); i++)&lt;BR&gt;   if (cs8900_irq_map[i] == irq)&lt;BR&gt;    break;&lt;BR&gt;  /* Not found */&lt;BR&gt;  if (i == sizeof(cs8900_irq_map)/sizeof(cs8900_irq_map[0]))&lt;BR&gt;   i = 3;&lt;BR&gt;  writereg(dev, PP_CS8900_ISAINT, i);&lt;BR&gt; } else {&lt;BR&gt;  writereg(dev, PP_CS8920_ISAINT, irq);&lt;BR&gt; }&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;/* Open/initialize the board.  This is called (in the current kernel)&lt;BR&gt;   sometime after booting when the &#39;ifconfig&#39; program is run.&lt;/P&gt; &lt;P&gt;   This routine should set everything up anew at each open, even&lt;BR&gt;   registers that &quot;should&quot; only need to be set once at boot, so that&lt;BR&gt;   there is non-reboot way to recover if something goes wrong.&lt;BR&gt;   */&lt;/P&gt; &lt;P&gt;/* AKPM: do we need to do any locking here? */&lt;/P&gt; &lt;P&gt;static int&lt;BR&gt;&lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#ff6600&gt;net_open&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; struct net_local *lp = (struct net_local *)dev-&amp;gt;priv;&lt;BR&gt; int result = 0;&lt;BR&gt; int i;&lt;BR&gt; int ret;&lt;/P&gt; &lt;P&gt; if (dev-&amp;gt;irq &amp;lt; 2) {&lt;BR&gt;  /* Allow interrupts to be generated by the chip */&lt;BR&gt;/* Cirrus&#39; release had this: */&lt;BR&gt;#if 0&lt;BR&gt;  writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ );&lt;BR&gt;#endif&lt;BR&gt;/* And 2.3.47 had this: */&lt;BR&gt;  writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);&lt;/P&gt; &lt;P&gt;  for (i = 2; i &amp;lt; CS8920_NO_INTS; i++) {&lt;BR&gt;   if ((1 &amp;lt;&amp;lt; dev-&amp;gt;irq) &amp;amp; lp-&amp;gt;irq_map) {&lt;BR&gt;    if (&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;request_irq&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(i, &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;net_interrupt&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;, 0, dev-&amp;gt;name, dev) == 0) {&lt;BR&gt;     dev-&amp;gt;irq = i;&lt;BR&gt;     write_irq(dev, lp-&amp;gt;chip_type, i);&lt;BR&gt;     /* writereg(dev, PP_BufCFG, GENERATE_SW_INTERRUPT); */&lt;BR&gt;     break;&lt;BR&gt;    }&lt;BR&gt;   }&lt;BR&gt;  }&lt;/P&gt; &lt;P&gt;  if (i &amp;gt;= CS8920_NO_INTS) {&lt;BR&gt;   writereg(dev, PP_BusCTL, 0); /* disable interrupts. */&lt;BR&gt;   printk(KERN_ERR &quot;cs89x0: can&#39;t get an interruptn&quot;);&lt;BR&gt;   ret = -EAGAIN;&lt;BR&gt;   goto bad_out;&lt;BR&gt;  }&lt;BR&gt; } else {&lt;BR&gt;  if (((1 &amp;lt;&amp;lt; dev-&amp;gt;irq) &amp;amp; lp-&amp;gt;irq_map) == 0) {&lt;BR&gt;   printk(KERN_ERR &quot;%s: IRQ %d is not in our map of allowable IRQs, which is %xn&quot;,&lt;BR&gt;                               dev-&amp;gt;name, dev-&amp;gt;irq, lp-&amp;gt;irq_map);&lt;BR&gt;   ret = -EAGAIN;&lt;BR&gt;   goto bad_out;&lt;BR&gt;  }&lt;BR&gt;/* FIXME: Cirrus&#39; release had this: */&lt;BR&gt;  writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ );&lt;BR&gt;/* And 2.3.47 had this: */&lt;BR&gt;#if 0&lt;BR&gt;  writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);&lt;BR&gt;#endif&lt;BR&gt;  write_irq(dev, lp-&amp;gt;chip_type, dev-&amp;gt;irq);&lt;BR&gt;  ret = &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;request_irq&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(dev-&amp;gt;irq, &amp;amp;&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;net_interrupt&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;, 0, dev-&amp;gt;name, dev);&lt;BR&gt;  if (ret) {&lt;BR&gt;   if (net_debug)&lt;BR&gt;    printk(KERN_DEBUG &quot;cs89x0: request_irq(%d) failedn&quot;, dev-&amp;gt;irq);&lt;BR&gt;   goto bad_out;&lt;BR&gt;  }&lt;BR&gt; }&lt;/P&gt; &lt;P&gt;#if ALLOW_DMA&lt;BR&gt; if (lp-&amp;gt;use_dma) {&lt;BR&gt;  if (lp-&amp;gt;isa_config &amp;amp; ANY_ISA_DMA) {&lt;BR&gt;   unsigned long flags;&lt;BR&gt;   lp-&amp;gt;dma_buff = (unsigned char *)__get_dma_pages(GFP_KERNEL,&lt;BR&gt;       get_order(lp-&amp;gt;dmasize * 1024));&lt;/P&gt; &lt;P&gt;   if (!lp-&amp;gt;dma_buff) {&lt;BR&gt;    printk(KERN_ERR &quot;%s: cannot get %dK memory for DMAn&quot;, dev-&amp;gt;name, lp-&amp;gt;dmasize);&lt;BR&gt;    goto release_irq;&lt;BR&gt;   }&lt;BR&gt;   if (net_debug &amp;gt; 1) {&lt;BR&gt;    printk( &quot;%s: dma %lx %lxn&quot;,&lt;BR&gt;     dev-&amp;gt;name,&lt;BR&gt;     (unsigned long)lp-&amp;gt;dma_buff,&lt;BR&gt;     (unsigned long)virt_to_bus(lp-&amp;gt;dma_buff));&lt;BR&gt;   }&lt;BR&gt;   if ((unsigned long) lp-&amp;gt;dma_buff &amp;gt;= MAX_DMA_ADDRESS ||&lt;BR&gt;       !dma_page_eq(lp-&amp;gt;dma_buff, lp-&amp;gt;dma_buff+lp-&amp;gt;dmasize*1024-1)) {&lt;BR&gt;    printk(KERN_ERR &quot;%s: not usable as DMA buffern&quot;, dev-&amp;gt;name);&lt;BR&gt;    goto release_irq;&lt;BR&gt;   }&lt;BR&gt;   memset(lp-&amp;gt;dma_buff, 0, lp-&amp;gt;dmasize * 1024); /* Why? */&lt;BR&gt;   if (request_dma(dev-&amp;gt;dma, dev-&amp;gt;name)) {&lt;BR&gt;    printk(KERN_ERR &quot;%s: cannot get dma channel %dn&quot;, dev-&amp;gt;name, dev-&amp;gt;dma);&lt;BR&gt;    goto release_irq;&lt;BR&gt;   }&lt;BR&gt;   write_dma(dev, lp-&amp;gt;chip_type, dev-&amp;gt;dma);&lt;BR&gt;   lp-&amp;gt;rx_dma_ptr = lp-&amp;gt;dma_buff;&lt;BR&gt;   lp-&amp;gt;end_dma_buff = lp-&amp;gt;dma_buff + lp-&amp;gt;dmasize*1024;&lt;BR&gt;   spin_lock_irqsave(&amp;amp;lp-&amp;gt;lock, flags);&lt;BR&gt;   disable_dma(dev-&amp;gt;dma);&lt;BR&gt;   clear_dma_ff(dev-&amp;gt;dma);&lt;BR&gt;   set_dma_mode(dev-&amp;gt;dma, 0x14); /* auto_init as well */&lt;BR&gt;   set_dma_addr(dev-&amp;gt;dma, virt_to_bus(lp-&amp;gt;dma_buff));&lt;BR&gt;   set_dma_count(dev-&amp;gt;dma, lp-&amp;gt;dmasize*1024);&lt;BR&gt;   enable_dma(dev-&amp;gt;dma);&lt;BR&gt;   spin_unlock_irqrestore(&amp;amp;lp-&amp;gt;lock, flags);&lt;BR&gt;  }&lt;BR&gt; }&lt;BR&gt;#endif /* ALLOW_DMA */&lt;/P&gt; &lt;P&gt; /* set the Ethernet address */&lt;BR&gt; for (i=0; i &amp;lt; ETH_ALEN/2; i++)&lt;BR&gt;  writereg(dev, PP_IA+i*2, dev-&amp;gt;dev_addr[i*2] | (dev-&amp;gt;dev_addr[i*2+1] &amp;lt;&amp;lt; 8));&lt;/P&gt; &lt;P&gt; /* while we&#39;re testing the interface, leave interrupts disabled */&lt;BR&gt; writereg(dev, PP_BusCTL, MEMORY_ON);&lt;/P&gt; &lt;P&gt; /* Set the LineCTL quintuplet based on adapter configuration read from EEPROM */&lt;BR&gt; if ((lp-&amp;gt;adapter_cnf &amp;amp; A_CNF_EXTND_10B_2) &amp;amp;&amp;amp; (lp-&amp;gt;adapter_cnf &amp;amp; A_CNF_LOW_RX_SQUELCH))&lt;BR&gt;                lp-&amp;gt;linectl = LOW_RX_SQUELCH;&lt;BR&gt; else&lt;BR&gt;                lp-&amp;gt;linectl = 0;&lt;/P&gt; &lt;P&gt;        /* check to make sure that they have the &quot;right&quot; hardware available */&lt;BR&gt; switch(lp-&amp;gt;adapter_cnf &amp;amp; A_CNF_MEDIA_TYPE) {&lt;BR&gt; case A_CNF_MEDIA_10B_T: result = lp-&amp;gt;adapter_cnf &amp;amp; A_CNF_10B_T; break;&lt;BR&gt; case A_CNF_MEDIA_AUI:   result = lp-&amp;gt;adapter_cnf &amp;amp; A_CNF_AUI; break;&lt;BR&gt; case A_CNF_MEDIA_10B_2: result = lp-&amp;gt;adapter_cnf &amp;amp; A_CNF_10B_2; break;&lt;BR&gt;        default: result = lp-&amp;gt;adapter_cnf &amp;amp; (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2);&lt;BR&gt;        }&lt;BR&gt;        if (!result) {&lt;BR&gt;                printk(KERN_ERR &quot;%s: EEPROM is configured for unavailable median&quot;, dev-&amp;gt;name);&lt;BR&gt;        release_irq:&lt;BR&gt;#if ALLOW_DMA&lt;BR&gt;  release_dma_buff(lp);&lt;BR&gt;#endif&lt;BR&gt;                writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) &amp;amp; ~(SERIAL_TX_ON | SERIAL_RX_ON));&lt;BR&gt;                free_irq(dev-&amp;gt;irq, dev);&lt;BR&gt;  ret = -EAGAIN;&lt;BR&gt;  goto bad_out;&lt;BR&gt; }&lt;/P&gt; &lt;P&gt;        /* set the hardware to the configured choice */&lt;BR&gt; switch(lp-&amp;gt;adapter_cnf &amp;amp; A_CNF_MEDIA_TYPE) {&lt;BR&gt; case A_CNF_MEDIA_10B_T:&lt;BR&gt;                result = detect_tp(dev);&lt;BR&gt;                if (result==DETECTED_NONE) {&lt;/P&gt; &lt;P&gt;#ifdef CONFIG_ARCH_S3C2410&lt;/P&gt; &lt;P&gt;#else&lt;BR&gt;                        printk(KERN_WARNING &quot;%s: 10Base-T (RJ-45) has no cablen&quot;, dev-&amp;gt;name);&lt;BR&gt;#endif&lt;BR&gt;                        if (lp-&amp;gt;auto_neg_cnf &amp;amp; IMM_BIT) /* check &quot;ignore missing media&quot; bit */&lt;BR&gt;#ifdef CONFIG_ARCH_S3C2410&lt;BR&gt;                                result = DETECTED_RJ45F; /* Yes! I don&#39;t care if I see a link pulse */&lt;BR&gt;#else                                &lt;BR&gt;    result = DETECTED_RJ45H; /* Yes! I don&#39;t care if I see a link pulse */&lt;BR&gt;#endif&lt;BR&gt;                }&lt;BR&gt;  break;&lt;BR&gt; case A_CNF_MEDIA_AUI:&lt;BR&gt;                result = detect_aui(dev);&lt;BR&gt;                if (result==DETECTED_NONE) {&lt;BR&gt;                        printk(KERN_WARNING &quot;%s: 10Base-5 (AUI) has no cablen&quot;, dev-&amp;gt;name);&lt;BR&gt;                        if (lp-&amp;gt;auto_neg_cnf &amp;amp; IMM_BIT) /* check &quot;ignore missing media&quot; bit */&lt;BR&gt;                                result = DETECTED_AUI; /* Yes! I don&#39;t care if I see a carrrier */&lt;BR&gt;                }&lt;BR&gt;  break;&lt;BR&gt; case A_CNF_MEDIA_10B_2:&lt;BR&gt;                result = detect_bnc(dev);&lt;BR&gt;                if (result==DETECTED_NONE) {&lt;BR&gt;                        printk(KERN_WARNING &quot;%s: 10Base-2 (BNC) has no cablen&quot;, dev-&amp;gt;name);&lt;BR&gt;                        if (lp-&amp;gt;auto_neg_cnf &amp;amp; IMM_BIT) /* check &quot;ignore missing media&quot; bit */&lt;BR&gt;                                result = DETECTED_BNC; /* Yes! I don&#39;t care if I can xmit a packet */&lt;BR&gt;                }&lt;BR&gt;  break;&lt;BR&gt; case A_CNF_MEDIA_AUTO:&lt;BR&gt;  writereg(dev, PP_LineCTL, lp-&amp;gt;linectl | AUTO_AUI_10BASET);&lt;BR&gt;  if (lp-&amp;gt;adapter_cnf &amp;amp; A_CNF_10B_T)&lt;BR&gt;   if ((result = detect_tp(dev)) != DETECTED_NONE)&lt;BR&gt;    break;&lt;BR&gt;  if (lp-&amp;gt;adapter_cnf &amp;amp; A_CNF_AUI)&lt;BR&gt;   if ((result = detect_aui(dev)) != DETECTED_NONE)&lt;BR&gt;    break;&lt;BR&gt;  if (lp-&amp;gt;adapter_cnf &amp;amp; A_CNF_10B_2)&lt;BR&gt;   if ((result = detect_bnc(dev)) != DETECTED_NONE)&lt;BR&gt;    break;&lt;BR&gt;  printk(KERN_ERR &quot;%s: no media detectedn&quot;, dev-&amp;gt;name);&lt;BR&gt;                goto release_irq;&lt;BR&gt; }&lt;BR&gt; switch(result) {&lt;BR&gt; case DETECTED_NONE:&lt;BR&gt;  printk(KERN_ERR &quot;%s: no network cable attached to configured median&quot;, dev-&amp;gt;name);&lt;BR&gt;                goto release_irq;&lt;BR&gt; case DETECTED_RJ45H:&lt;BR&gt;  printk(KERN_INFO &quot;%s: using half-duplex 10Base-T (RJ-45)n&quot;, dev-&amp;gt;name);&lt;BR&gt;  break;&lt;BR&gt; case DETECTED_RJ45F:&lt;BR&gt;  printk(KERN_INFO &quot;%s: using full-duplex 10Base-T (RJ-45)n&quot;, dev-&amp;gt;name);&lt;BR&gt;  break;&lt;BR&gt; case DETECTED_AUI:&lt;BR&gt;  printk(KERN_INFO &quot;%s: using 10Base-5 (AUI)n&quot;, dev-&amp;gt;name);&lt;BR&gt;  break;&lt;BR&gt; case DETECTED_BNC:&lt;BR&gt;  printk(KERN_INFO &quot;%s: using 10Base-2 (BNC)n&quot;, dev-&amp;gt;name);&lt;BR&gt;  break;&lt;BR&gt; }&lt;/P&gt; &lt;P&gt; /* Turn on both receive and transmit operations */&lt;BR&gt; writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);&lt;/P&gt; &lt;P&gt; /* Receive only error free packets addressed to this card */&lt;BR&gt; lp-&amp;gt;rx_mode = 0;&lt;BR&gt; writereg(dev, PP_RxCTL, DEF_RX_ACCEPT);&lt;/P&gt; &lt;P&gt; lp-&amp;gt;curr_rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL;&lt;/P&gt; &lt;P&gt; if (lp-&amp;gt;isa_config &amp;amp; STREAM_TRANSFER)&lt;BR&gt;  lp-&amp;gt;curr_rx_cfg |= RX_STREAM_ENBL;&lt;BR&gt;#if ALLOW_DMA&lt;BR&gt; set_dma_cfg(dev);&lt;BR&gt;#endif&lt;BR&gt; writereg(dev, PP_RxCFG, lp-&amp;gt;curr_rx_cfg);&lt;/P&gt; &lt;P&gt; writereg(dev, PP_TxCFG, TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL |&lt;BR&gt;  TX_LATE_COL_ENBL | TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL);&lt;/P&gt; &lt;P&gt; writereg(dev, PP_BufCFG, READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL |&lt;BR&gt;#if ALLOW_DMA&lt;BR&gt;  dma_bufcfg(dev) |&lt;BR&gt;#endif&lt;BR&gt;  TX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL);&lt;/P&gt; &lt;P&gt; /* now that we&#39;ve got our act together, enable everything */&lt;BR&gt; writereg(dev, PP_BusCTL, ENABLE_IRQ&lt;BR&gt;   | (dev-&amp;gt;mem_start?MEMORY_ON : 0) /* turn memory on */&lt;BR&gt;#if ALLOW_DMA&lt;BR&gt;   | dma_busctl(dev)&lt;BR&gt;#endif&lt;BR&gt;                 );&lt;BR&gt;        &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;netif_start_queue&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(dev);&lt;BR&gt; if (net_debug &amp;gt; 1)&lt;BR&gt;  printk(&quot;cs89x0: net_open() succeededn&quot;);&lt;BR&gt; return 0;&lt;BR&gt;bad_out:&lt;BR&gt; return ret;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#ff6600&gt;net_timeout&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; /* If we get here, some higher level has decided we are broken.&lt;BR&gt;    There should really be a &quot;kick me&quot; function call instead. */&lt;BR&gt; if (net_debug &amp;gt; 0) printk(&quot;%s: transmit timed out, %s?n&quot;, dev-&amp;gt;name,&lt;BR&gt;     tx_done(dev) ? &quot;IRQ conflict ?&quot; : &quot;network cable problem&quot;);&lt;BR&gt; /* Try to restart the adaptor. */&lt;BR&gt; &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;netif_wake_queue&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(dev);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static int &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;net_send_packet&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(struct sk_buff *skb, struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; struct net_local *lp = (struct net_local *)dev-&amp;gt;priv;&lt;/P&gt; &lt;P&gt; if (net_debug &amp;gt; 3) {&lt;BR&gt;  printk(&quot;%s: sent %d byte packet of type %xn&quot;,&lt;BR&gt;   dev-&amp;gt;name, skb-&amp;gt;len,&lt;BR&gt;   (skb-&amp;gt;data[ETH_ALEN+ETH_ALEN] &amp;lt;&amp;lt; 8) | skb-&amp;gt;data[ETH_ALEN+ETH_ALEN+1]);&lt;BR&gt; }&lt;/P&gt; &lt;P&gt; /* keep the upload from being interrupted, since we&lt;BR&gt;                  ask the chip to start transmitting before the&lt;BR&gt;                  whole packet has been completely uploaded. */&lt;/P&gt; &lt;P&gt; spin_lock_irq(&amp;amp;lp-&amp;gt;lock);&lt;BR&gt; &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;netif_stop_queue&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(dev);&lt;/P&gt; &lt;P&gt; /* initiate a transmit sequence */&lt;BR&gt; writeword(dev, TX_CMD_PORT, lp-&amp;gt;send_cmd);&lt;BR&gt; writeword(dev, TX_LEN_PORT, skb-&amp;gt;len);&lt;/P&gt; &lt;P&gt; /* Test to see if the chip has allocated memory for the packet */&lt;BR&gt; if ((readreg(dev, PP_BusST) &amp;amp; READY_FOR_TX_NOW) == 0) {&lt;BR&gt;  /*&lt;BR&gt;   * Gasp!  It hasn&#39;t.  But that shouldn&#39;t happen since&lt;BR&gt;   * we&#39;re waiting for TxOk, so return 1 and requeue this packet.&lt;BR&gt;   */&lt;BR&gt;  &lt;BR&gt;  spin_unlock_irq(&amp;amp;lp-&amp;gt;lock);&lt;BR&gt;  if (net_debug) printk(&quot;cs89x0: Tx buffer not free!n&quot;);&lt;BR&gt;  return 1;&lt;BR&gt; }&lt;BR&gt; /* Write the contents of the packet */&lt;BR&gt; outsw(dev-&amp;gt;base_addr + TX_FRAME_PORT,skb-&amp;gt;data,(skb-&amp;gt;len+1) &amp;gt;&amp;gt;1);&lt;BR&gt; spin_unlock_irq(&amp;amp;lp-&amp;gt;lock);&lt;BR&gt; dev-&amp;gt;trans_start = jiffies;&lt;BR&gt; dev_kfree_skb (skb);&lt;/P&gt; &lt;P&gt; /*&lt;BR&gt;  * We DO NOT call netif_wake_queue() here.&lt;BR&gt;  * We also DO NOT call netif_start_queue().&lt;BR&gt;  *&lt;BR&gt;  * Either of these would cause another bottom half run through&lt;BR&gt;  * net_send_packet() before this packet has fully gone out.  That causes&lt;BR&gt;  * us to hit the &quot;Gasp!&quot; above and the send is rescheduled.  it runs like&lt;BR&gt;  * a dog.  We just return and wait for the Tx completion interrupt handler&lt;BR&gt;  * to restart the netdevice layer&lt;BR&gt;  */&lt;/P&gt; &lt;P&gt; return 0;&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;/* The typical workload of the driver:&lt;BR&gt;   Handle the network interface interrupts. */&lt;BR&gt;   &lt;BR&gt;static void &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;net_interrupt&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(int irq, void *dev_id, struct pt_regs * regs)&lt;BR&gt;{&lt;BR&gt; struct net_device *dev = dev_id;&lt;BR&gt; struct net_local *lp;&lt;BR&gt; int ioaddr, status;&lt;BR&gt; &lt;BR&gt; ioaddr = dev-&amp;gt;base_addr;&lt;BR&gt; lp = (struct net_local *)dev-&amp;gt;priv;&lt;/P&gt; &lt;P&gt; /* we MUST read all the events out of the ISQ, otherwise we&#39;ll never&lt;BR&gt;           get interrupted again.  As a consequence, we can&#39;t have any limit&lt;BR&gt;           on the number of times we loop in the interrupt handler.  The&lt;BR&gt;           hardware guarantees that eventually we&#39;ll run out of events.  Of&lt;BR&gt;           course, if you&#39;re on a slow machine, and packets are arriving&lt;BR&gt;           faster than you can read them off, you&#39;re screwed.  Hasta la&lt;BR&gt;           vista, baby!  */&lt;BR&gt; while ((&lt;FONT color=#ff0000&gt;status = readword(dev, ISQ_PORT)&lt;/FONT&gt;)) {&lt;BR&gt;  if (net_debug &amp;gt; 4)printk(&quot;%s: event=%04xn&quot;, dev-&amp;gt;name, status);&lt;BR&gt;  switch(status &amp;amp; ISQ_EVENT_MASK) {&lt;BR&gt;  case &lt;STRONG&gt;ISQ_RECEIVER_EVENT&lt;/STRONG&gt;:&lt;BR&gt;   /* Got a packet(s). */&lt;BR&gt;   &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;net_rx&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(dev);&lt;BR&gt;   break;&lt;BR&gt;  case &lt;STRONG&gt;ISQ_TRANSMITTER_EVENT&lt;/STRONG&gt;:&lt;BR&gt;   lp-&amp;gt;&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;stats.tx_packets&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;++;&lt;BR&gt;   &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;netif_wake_queue&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(dev); /* Inform upper layers. */&lt;BR&gt;   if ((status &amp;amp; ( TX_OK |&lt;BR&gt;     TX_LOST_CRS |&lt;BR&gt;     TX_SQE_ERROR |&lt;BR&gt;     TX_LATE_COL |&lt;BR&gt;     TX_16_COL)) != TX_OK) {&lt;BR&gt;    if ((status &amp;amp; TX_OK) == 0) lp-&amp;gt;&lt;FONT color=#3366ff&gt;&lt;EM&gt;&lt;STRONG&gt;stats.tx_errors&lt;/STRONG&gt;&lt;/EM&gt;&lt;/FONT&gt;++;&lt;BR&gt;    if (status &amp;amp; TX_LOST_CRS) lp-&amp;gt;&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;stats.tx_carrier_errors&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;++;&lt;BR&gt;    if (status &amp;amp; TX_SQE_ERROR) lp-&amp;gt;&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;stats.tx_heartbeat_errors&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;++;&lt;BR&gt;    if (status &amp;amp; TX_LATE_COL) lp-&amp;gt;&lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;stats.tx_window_errors&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;++;&lt;BR&gt;    if (status &amp;amp; TX_16_COL) lp-&amp;gt;&lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;stats.tx_aborted_errors&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;++;&lt;BR&gt;   }&lt;BR&gt;   break;&lt;BR&gt;  case &lt;STRONG&gt;ISQ_BUFFER_EVENT&lt;/STRONG&gt;:&lt;BR&gt;   if (status &amp;amp; READY_FOR_TX) {&lt;BR&gt;    /* we tried to transmit a packet earlier,&lt;BR&gt;                                   but inexplicably ran out of buffers.&lt;BR&gt;                                   That shouldn&#39;t happen since we only ever&lt;BR&gt;                                   load one packet.  Shrug.  Do the right&lt;BR&gt;                                   thing anyway. */&lt;BR&gt;    &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;netif_wake_queue&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(dev); /* Inform upper layers. */&lt;BR&gt;   }&lt;BR&gt;   if (status &amp;amp; TX_UNDERRUN) {&lt;BR&gt;    if (net_debug &amp;gt; 0) printk(&quot;%s: transmit underrunn&quot;, dev-&amp;gt;name);&lt;BR&gt;                                lp-&amp;gt;send_underrun++;&lt;BR&gt;                                if (lp-&amp;gt;send_underrun == 3) lp-&amp;gt;send_cmd = TX_AFTER_381;&lt;BR&gt;                                else if (lp-&amp;gt;send_underrun == 6) lp-&amp;gt;send_cmd = TX_AFTER_ALL;&lt;BR&gt;    /* transmit cycle is done, although&lt;BR&gt;       frame wasn&#39;t transmitted - this&lt;BR&gt;       avoids having to wait for the upper&lt;BR&gt;       layers to timeout on us, in the&lt;BR&gt;       event of a tx underrun */&lt;BR&gt;    &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;netif_wake_queue&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(dev); /* Inform upper layers. */&lt;BR&gt;                        }&lt;BR&gt;#if ALLOW_DMA&lt;BR&gt;   if (lp-&amp;gt;use_dma &amp;amp;&amp;amp; (status &amp;amp; RX_DMA)) {&lt;BR&gt;    int count = readreg(dev, PP_DmaFrameCnt);&lt;BR&gt;    while(count) {&lt;BR&gt;     if (net_debug &amp;gt; 5)&lt;BR&gt;      printk(&quot;%s: receiving %d DMA framesn&quot;, dev-&amp;gt;name, count);&lt;BR&gt;     if (net_debug &amp;gt; 2 &amp;amp;&amp;amp; count &amp;gt;1)&lt;BR&gt;      printk(&quot;%s: receiving %d DMA framesn&quot;, dev-&amp;gt;name, count);&lt;BR&gt;     dma_rx(dev);&lt;BR&gt;     if (--count == 0)&lt;BR&gt;      count = readreg(dev, PP_DmaFrameCnt);&lt;BR&gt;     if (net_debug &amp;gt; 2 &amp;amp;&amp;amp; count &amp;gt; 0)&lt;BR&gt;      printk(&quot;%s: continuing with %d DMA framesn&quot;, dev-&amp;gt;name, count);&lt;BR&gt;    }&lt;BR&gt;   }&lt;BR&gt;#endif&lt;BR&gt;   break;&lt;BR&gt;  case &lt;STRONG&gt;ISQ_RX_MISS_EVENT&lt;/STRONG&gt;:&lt;BR&gt;   lp-&amp;gt;&lt;FONT color=#3366ff&gt;&lt;STRONG&gt;&lt;EM&gt;stats.rx_missed_errors&lt;/EM&gt;&lt;/STRONG&gt; &lt;/FONT&gt;+= (status &amp;gt;&amp;gt;6);&lt;BR&gt;   break;&lt;BR&gt;  case &lt;STRONG&gt;ISQ_TX_COL_EVENT&lt;/STRONG&gt;:&lt;BR&gt;   lp-&amp;gt;&lt;FONT color=#3366ff&gt;&lt;EM&gt;&lt;STRONG&gt;stats.collisions&lt;/STRONG&gt;&lt;/EM&gt; &lt;/FONT&gt;+= (status &amp;gt;&amp;gt;6);&lt;BR&gt;   break;&lt;BR&gt;  }&lt;BR&gt; }&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void&lt;BR&gt;count_rx_errors(int status, struct net_local *lp)&lt;BR&gt;{&lt;BR&gt; lp-&amp;gt;stats.rx_errors++;&lt;BR&gt; if (status &amp;amp; RX_RUNT) lp-&amp;gt;stats.rx_length_errors++;&lt;BR&gt; if (status &amp;amp; RX_EXTRA_DATA) lp-&amp;gt;stats.rx_length_errors++;&lt;BR&gt; if (status &amp;amp; RX_CRC_ERROR) if (!(status &amp;amp; (RX_EXTRA_DATA|RX_RUNT)))&lt;BR&gt;  /* per str 172 */&lt;BR&gt;  lp-&amp;gt;stats.rx_crc_errors++;&lt;BR&gt; if (status &amp;amp; RX_DRIBBLE) lp-&amp;gt;stats.rx_frame_errors++;&lt;BR&gt; return;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;/* We have a good packet(s), get it/them out of the buffers. */&lt;BR&gt;static void&lt;BR&gt;&lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#ff6600&gt;net_rx&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; struct net_local *lp = (struct net_local *)dev-&amp;gt;priv;&lt;BR&gt; struct sk_buff *skb;&lt;BR&gt; int status, length;&lt;/P&gt; &lt;P&gt; int ioaddr = dev-&amp;gt;base_addr;&lt;BR&gt; status = inw(ioaddr + RX_FRAME_PORT);&lt;BR&gt; length = inw(ioaddr + RX_FRAME_PORT);&lt;/P&gt; &lt;P&gt; if ((status &amp;amp; RX_OK) == 0) {&lt;BR&gt;  count_rx_errors(status, lp);&lt;BR&gt;  return;&lt;BR&gt; }&lt;/P&gt; &lt;P&gt; /* Malloc up new buffer. */&lt;BR&gt; skb = dev_alloc_skb(length + 2);&lt;BR&gt; if (skb == NULL) {&lt;BR&gt;#if 0  /* Again, this seems a cruel thing to do */&lt;BR&gt;  printk(KERN_WARNING &quot;%s: Memory squeeze, dropping packet.n&quot;, dev-&amp;gt;name);&lt;BR&gt;#endif&lt;BR&gt;  lp-&amp;gt;stats.rx_dropped++;&lt;BR&gt;  return;&lt;BR&gt; }&lt;BR&gt; skb_reserve(skb, 2); /* longword align L3 header */&lt;BR&gt; skb-&amp;gt;dev = dev;&lt;/P&gt; &lt;P&gt; insw(ioaddr + RX_FRAME_PORT, skb_put(skb, length), length &amp;gt;&amp;gt; 1);&lt;BR&gt; if (length &amp;amp; 1)&lt;BR&gt;  skb-&amp;gt;data[length-1] = inw(ioaddr + RX_FRAME_PORT);&lt;/P&gt; &lt;P&gt; if (net_debug &amp;gt; 3) {&lt;BR&gt;  printk( &quot;%s: received %d byte packet of type %xn&quot;,&lt;BR&gt;   dev-&amp;gt;name, length,&lt;BR&gt;   (skb-&amp;gt;data[ETH_ALEN+ETH_ALEN] &amp;lt;&amp;lt; 8) | skb-&amp;gt;data[ETH_ALEN+ETH_ALEN+1]);&lt;BR&gt; }&lt;/P&gt; &lt;P&gt;        skb-&amp;gt;protocol=eth_type_trans(skb,dev);&lt;BR&gt; &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;netif_rx&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(skb);&lt;BR&gt; dev-&amp;gt;last_rx = jiffies;&lt;BR&gt; lp-&amp;gt;&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;stats.rx_packets&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;++;&lt;BR&gt; lp-&amp;gt;&lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;stats.rx_bytes&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt; += length;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;#if ALLOW_DMA&lt;BR&gt;static void release_dma_buff(struct net_local *lp)&lt;BR&gt;{&lt;BR&gt; if (lp-&amp;gt;dma_buff) {&lt;BR&gt;  free_pages((unsigned long)(lp-&amp;gt;dma_buff), get_order(lp-&amp;gt;dmasize * 1024));&lt;BR&gt;  lp-&amp;gt;dma_buff = 0;&lt;BR&gt; }&lt;BR&gt;}&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt;/* The inverse routine to net_open(). */&lt;BR&gt;static int&lt;BR&gt;&lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#ff6600&gt;net_close&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; struct net_local *lp = (struct net_local *)dev-&amp;gt;priv;&lt;/P&gt; &lt;P&gt; netif_stop_queue(dev);&lt;BR&gt; &lt;BR&gt; writereg(dev, PP_RxCFG, 0);&lt;BR&gt; writereg(dev, PP_TxCFG, 0);&lt;BR&gt; writereg(dev, PP_BufCFG, 0);&lt;BR&gt; writereg(dev, PP_BusCTL, 0);&lt;/P&gt; &lt;P&gt; &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;free_irq&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(dev-&amp;gt;irq, dev);&lt;/P&gt; &lt;P&gt;#if ALLOW_DMA&lt;BR&gt; if (lp-&amp;gt;use_dma &amp;amp;&amp;amp; lp-&amp;gt;dma) {&lt;BR&gt;  free_dma(dev-&amp;gt;dma);&lt;BR&gt;  release_dma_buff(lp);&lt;BR&gt; }&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt; /* Update the statistics here. */&lt;BR&gt; return 0;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;/* Get the current statistics. This may be called with the card open or&lt;BR&gt;   closed. */&lt;BR&gt;static struct net_device_stats *&lt;BR&gt;&lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#ff6600&gt;net_get_stats&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; struct net_local *lp = (struct net_local *)dev-&amp;gt;priv;&lt;BR&gt; unsigned long flags;&lt;/P&gt; &lt;P&gt; spin_lock_irqsave(&amp;amp;lp-&amp;gt;lock, flags);&lt;BR&gt; /* Update the statistics from the device registers. */&lt;BR&gt; lp-&amp;gt;&lt;FONT color=#3366ff&gt;&lt;EM&gt;&lt;STRONG&gt;stats.rx_missed_errors&lt;/STRONG&gt;&lt;/EM&gt; &lt;/FONT&gt;+= (readreg(dev, PP_RxMiss) &amp;gt;&amp;gt; 6);&lt;BR&gt; lp-&amp;gt;&lt;FONT color=#3366ff&gt;&lt;STRONG&gt;&lt;EM&gt;stats.collisions&lt;/EM&gt;&lt;/STRONG&gt; &lt;/FONT&gt;+= (readreg(dev, PP_TxCol) &amp;gt;&amp;gt; 6);&lt;BR&gt; spin_unlock_irqrestore(&amp;amp;lp-&amp;gt;lock, flags);&lt;/P&gt; &lt;P&gt; return &amp;amp;lp-&amp;gt;stats;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;static void &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;set_multicast_list&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(struct net_device *dev)&lt;BR&gt;{&lt;BR&gt; struct net_local *lp = (struct net_local *)dev-&amp;gt;priv;&lt;BR&gt; unsigned long flags;&lt;/P&gt; &lt;P&gt; spin_lock_irqsave(&amp;amp;lp-&amp;gt;lock, flags);&lt;BR&gt; if(dev-&amp;gt;flags&amp;amp;IFF_PROMISC)&lt;BR&gt; {&lt;BR&gt;  lp-&amp;gt;rx_mode = RX_ALL_ACCEPT;&lt;BR&gt; }&lt;BR&gt; else if((dev-&amp;gt;flags&amp;amp;IFF_ALLMULTI)||dev-&amp;gt;mc_list)&lt;BR&gt; {&lt;BR&gt;  /* The multicast-accept list is initialized to accept-all, and we&lt;BR&gt;     rely on higher-level filtering for now. */&lt;BR&gt;  lp-&amp;gt;rx_mode = RX_MULTCAST_ACCEPT;&lt;BR&gt; } &lt;BR&gt; else&lt;BR&gt;  lp-&amp;gt;rx_mode = 0;&lt;/P&gt; &lt;P&gt; writereg(dev, PP_RxCTL, DEF_RX_ACCEPT | lp-&amp;gt;rx_mode);&lt;/P&gt; &lt;P&gt; /* in promiscuous mode, we accept errored packets, so we have to enable interrupts on them also */&lt;BR&gt; writereg(dev, PP_RxCFG, lp-&amp;gt;curr_rx_cfg |&lt;BR&gt;      (lp-&amp;gt;rx_mode == RX_ALL_ACCEPT? (RX_CRC_ERROR_ENBL|RX_RUNT_ENBL|RX_EXTRA_DATA_ENBL) : 0));&lt;BR&gt; spin_unlock_irqrestore(&amp;amp;lp-&amp;gt;lock, flags);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;&lt;BR&gt;static int &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#ff6600&gt;set_mac_address&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(struct net_device *dev, void *addr)&lt;BR&gt;{&lt;BR&gt; int i;&lt;/P&gt; &lt;P&gt; if (netif_running(dev))&lt;BR&gt;  return -EBUSY;&lt;BR&gt; if (net_debug) {&lt;BR&gt;  printk(&quot;%s: Setting MAC address to &quot;, dev-&amp;gt;name);&lt;BR&gt;  for (i = 0; i &amp;lt; 6; i++)&lt;BR&gt;   printk(&quot; %2.2x&quot;, dev-&amp;gt;dev_addr[i] = ((unsigned char *)addr)[i]);&lt;BR&gt;  printk(&quot;.n&quot;);&lt;BR&gt; }&lt;BR&gt; /* set the Ethernet address */&lt;BR&gt; for (i=0; i &amp;lt; ETH_ALEN/2; i++)&lt;BR&gt;  writereg(dev, PP_IA+i*2, dev-&amp;gt;dev_addr[i*2] | (dev-&amp;gt;dev_addr[i*2+1] &amp;lt;&amp;lt; 8));&lt;/P&gt; &lt;P&gt; return 0;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;#ifdef MODULE&lt;/P&gt; &lt;P&gt;static struct net_device dev_cs89x0 = {&lt;BR&gt;        &quot;&quot;,&lt;BR&gt;        0, 0, 0, 0,&lt;BR&gt;        0, 0,&lt;BR&gt;        0, 0, 0, NULL, NULL };&lt;/P&gt; &lt;P&gt;/*&lt;BR&gt; * Support the &#39;debug&#39; module parm even if we&#39;re compiled for non-debug to &lt;BR&gt; * avoid breaking someone&#39;s startup scripts &lt;BR&gt; */&lt;/P&gt; &lt;P&gt;static int io;&lt;BR&gt;static int irq;&lt;BR&gt;static int debug;&lt;BR&gt;static char media[8];&lt;BR&gt;static int duplex=-1;&lt;/P&gt; &lt;P&gt;static int use_dma;   /* These generate unused var warnings if ALLOW_DMA = 0 */&lt;BR&gt;static int dma;&lt;BR&gt;static int dmasize=16;   /* or 64 */&lt;/P&gt; &lt;P&gt;MODULE_PARM(io, &quot;i&quot;);&lt;BR&gt;MODULE_PARM(irq, &quot;i&quot;);&lt;BR&gt;MODULE_PARM(debug, &quot;i&quot;);&lt;BR&gt;MODULE_PARM(media, &quot;c8&quot;);&lt;BR&gt;MODULE_PARM(duplex, &quot;i&quot;);&lt;BR&gt;MODULE_PARM(dma , &quot;i&quot;);&lt;BR&gt;MODULE_PARM(dmasize , &quot;i&quot;);&lt;BR&gt;MODULE_PARM(use_dma , &quot;i&quot;);&lt;BR&gt;MODULE_PARM_DESC(io, &quot;cs89x0 I/O base address&quot;);&lt;BR&gt;MODULE_PARM_DESC(irq, &quot;cs89x0 IRQ number&quot;);&lt;BR&gt;#if DEBUGGING&lt;BR&gt;MODULE_PARM_DESC(debug, &quot;cs89x0 debug level (0-6)&quot;);&lt;BR&gt;#else&lt;BR&gt;MODULE_PARM_DESC(debug, &quot;(ignored)&quot;);&lt;BR&gt;#endif&lt;BR&gt;MODULE_PARM_DESC(media, &quot;Set cs89x0 adapter(s) media type(s) (rj45,bnc,aui)&quot;);&lt;BR&gt;/* No other value than -1 for duplex seems to be currently interpreted */&lt;BR&gt;MODULE_PARM_DESC(duplex, &quot;(ignored)&quot;);&lt;BR&gt;#if ALLOW_DMA&lt;BR&gt;MODULE_PARM_DESC(dma , &quot;cs89x0 ISA DMA channel; ignored if use_dma=0&quot;);&lt;BR&gt;MODULE_PARM_DESC(dmasize , &quot;cs89x0 DMA size in kB (16,64); ignored if use_dma=0&quot;);&lt;BR&gt;MODULE_PARM_DESC(use_dma , &quot;cs89x0 using DMA (0-1)&quot;);&lt;BR&gt;#else&lt;BR&gt;MODULE_PARM_DESC(dma , &quot;(ignored)&quot;);&lt;BR&gt;MODULE_PARM_DESC(dmasize , &quot;(ignored)&quot;);&lt;BR&gt;MODULE_PARM_DESC(use_dma , &quot;(ignored)&quot;);&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt;MODULE_AUTHOR(&quot;Mike Cruse, Russwll Nelson &amp;lt;&lt;A href=&quot;mailto:nelson@crynwr.com&quot;&gt;nelson@crynwr.com&lt;/A&gt;&amp;gt;, Andrew Morton &amp;lt;&lt;A href=&quot;mailto:andrewm@uow.edu.au&quot;&gt;andrewm@uow.edu.au&lt;/A&gt;&amp;gt;&quot;);&lt;BR&gt;MODULE_LICENSE(&quot;GPL&quot;);&lt;/P&gt; &lt;P&gt;&lt;BR&gt;EXPORT_NO_SYMBOLS;&lt;/P&gt; &lt;P&gt;/*&lt;BR&gt;* media=t             - specify media type&lt;BR&gt;   or media=2&lt;BR&gt;   or media=aui&lt;BR&gt;   or medai=auto&lt;BR&gt;* duplex=0            - specify forced half/full/autonegotiate duplex&lt;BR&gt;* debug=#             - debug level&lt;/P&gt; &lt;P&gt;&lt;BR&gt;* Default Chip Configuration:&lt;BR&gt;  * DMA Burst = enabled&lt;BR&gt;  * IOCHRDY Enabled = enabled&lt;BR&gt;    * UseSA = enabled&lt;BR&gt;    * CS8900 defaults to half-duplex if not specified on command-line&lt;BR&gt;    * CS8920 defaults to autoneg if not specified on command-line&lt;BR&gt;    * Use reset defaults for other config parameters&lt;/P&gt; &lt;P&gt;* Assumptions:&lt;BR&gt;  * media type specified is supported (circuitry is present)&lt;BR&gt;  * if memory address is &amp;gt; 1MB, then required mem decode hw is present&lt;BR&gt;  * if 10B-2, then agent other than driver will enable DC/DC converter&lt;BR&gt;    (hw or software util)&lt;/P&gt; &lt;P&gt;&lt;BR&gt;*/&lt;/P&gt; &lt;P&gt;int&lt;BR&gt;&lt;FONT color=#ff6600&gt;&lt;STRONG&gt;&lt;EM&gt;init_module&lt;/EM&gt;&lt;/STRONG&gt;&lt;/FONT&gt;(void)&lt;BR&gt;{&lt;BR&gt; struct net_local *lp;&lt;BR&gt; int ret = 0;&lt;/P&gt; &lt;P&gt;#if DEBUGGING&lt;BR&gt; net_debug = debug;&lt;BR&gt;#else&lt;BR&gt; debug = 0;&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt; &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;dev_cs89x0.irq&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt; = irq;&lt;BR&gt; &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;dev_cs89x0.base_addr&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt; = io;&lt;/P&gt; &lt;P&gt;        &lt;FONT color=#3366ff&gt;&lt;EM&gt;&lt;STRONG&gt;dev_cs89x0.init&lt;/STRONG&gt;&lt;/EM&gt; &lt;/FONT&gt;= &lt;STRONG&gt;&lt;FONT color=#ff0000&gt;cs89x0_probe&lt;/FONT&gt;&lt;/STRONG&gt;;&lt;BR&gt;        &lt;FONT color=#3366ff&gt;&lt;STRONG&gt;&lt;EM&gt;dev_cs89x0.priv&lt;/EM&gt;&lt;/STRONG&gt;&lt;/FONT&gt; = kmalloc(sizeof(struct net_local), GFP_KERNEL);&lt;BR&gt; if (dev_cs89x0.priv == 0) {&lt;BR&gt;  printk(KERN_ERR &quot;cs89x0.c: Out of memory.n&quot;);&lt;BR&gt;  return -ENOMEM;&lt;BR&gt; }&lt;BR&gt; memset(dev_cs89x0.priv, 0, sizeof(struct net_local));&lt;BR&gt; lp = (struct net_local *)dev_cs89x0.priv;&lt;/P&gt; &lt;P&gt;#if ALLOW_DMA&lt;BR&gt; if (use_dma) {&lt;BR&gt;  lp-&amp;gt;use_dma = use_dma;&lt;BR&gt;  lp-&amp;gt;dma = dma;&lt;BR&gt;  lp-&amp;gt;dmasize = dmasize;&lt;BR&gt; }&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt; spin_lock_init(&amp;amp;lp-&amp;gt;lock);&lt;/P&gt; &lt;P&gt;        /* boy, they&#39;d better get these right */&lt;BR&gt;        if (!strcmp(media, &quot;rj45&quot;))&lt;BR&gt;  lp-&amp;gt;adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T;&lt;BR&gt; else if (!strcmp(media, &quot;aui&quot;))&lt;BR&gt;  lp-&amp;gt;adapter_cnf = A_CNF_MEDIA_AUI   | A_CNF_AUI;&lt;BR&gt; else if (!strcmp(media, &quot;bnc&quot;))&lt;BR&gt;  lp-&amp;gt;adapter_cnf = A_CNF_MEDIA_10B_2 | A_CNF_10B_2;&lt;BR&gt; else&lt;BR&gt;  lp-&amp;gt;adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T;&lt;/P&gt; &lt;P&gt;        if (duplex==-1)&lt;BR&gt;  lp-&amp;gt;auto_neg_cnf = AUTO_NEG_ENABLE;&lt;/P&gt; &lt;P&gt;        if (io == 0) {&lt;BR&gt;                printk(KERN_ERR &quot;cs89x0.c: Module autoprobing not allowed.n&quot;);&lt;BR&gt;                printk(KERN_ERR &quot;cs89x0.c: Append io=0xNNNn&quot;);&lt;BR&gt;                ret = -EPERM;&lt;BR&gt;  goto out;&lt;BR&gt;        }&lt;/P&gt; &lt;P&gt;#if ALLOW_DMA&lt;BR&gt; if (use_dma &amp;amp;&amp;amp; dmasize != 16 &amp;amp;&amp;amp; dmasize != 64) {&lt;BR&gt;  printk(KERN_ERR &quot;cs89x0.c: dma size must be either 16K or 64K, not %dKn&quot;, dmasize);&lt;BR&gt;  ret = -EPERM;&lt;BR&gt;  goto out;&lt;BR&gt; }&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt;        if (&lt;FONT color=#3366ff&gt;&lt;EM&gt;&lt;STRONG&gt;register_netdev&lt;/STRONG&gt;&lt;/EM&gt;&lt;/FONT&gt;(&amp;amp;dev_cs89x0) != 0) {&lt;BR&gt;                printk(KERN_ERR &quot;cs89x0.c: No card found at 0x%xn&quot;, io);&lt;BR&gt;                ret = -ENXIO;&lt;BR&gt;  goto out;&lt;BR&gt;        }&lt;BR&gt;out:&lt;BR&gt; if (ret)&lt;BR&gt;  kfree(dev_cs89x0.priv);&lt;BR&gt; return ret;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;void&lt;BR&gt;&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6600&gt;cleanup_module&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(void)&lt;BR&gt;{&lt;BR&gt;        if (dev_cs89x0.priv != NULL) {&lt;BR&gt;                /* Free up the private structure, or leak memory :-)  */&lt;BR&gt;                &lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;unregister_netdev&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;(&amp;amp;dev_cs89x0);&lt;BR&gt;  outw(PP_ChipID, dev_cs89x0.base_addr + ADD_PORT);&lt;BR&gt;                kfree(dev_cs89x0.priv);&lt;BR&gt;                dev_cs89x0.priv = NULL; /* gets re-allocated by cs89x0_probe1 */&lt;BR&gt;                /* If we don&#39;t do this, we can&#39;t re-insmod it later. */&lt;BR&gt;                &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;release_region&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;(dev_cs89x0.base_addr, NETCARD_IO_EXTENT);&lt;BR&gt;        }&lt;BR&gt;}&lt;BR&gt;#endif /* MODULE */&lt;BR&gt;&lt;BR&gt;/*&lt;BR&gt; * Local variables:&lt;BR&gt; *  version-control: t&lt;BR&gt; *  kept-new-versions: 5&lt;BR&gt; *  c-indent-level: 8&lt;BR&gt; *  tab-width: 8&lt;BR&gt; * End:&lt;BR&gt; *&lt;BR&gt; */&lt;BR&gt;&lt;/P&gt;</content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/6305769004149807178/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/6305769004149807178' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/6305769004149807178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/6305769004149807178'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2007/05/network-driver-cs89x0.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36435979.post-1768911704484237450</id><published>2007-05-17T22:41:00.000+08:00</published><updated>2007-06-23T00:14:12.497+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux 網路程式篇"/><title type='text'></title><content type='html'>&lt;H1&gt;CGI&lt;/H1&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_162g8jkmtc3&quot;&gt;&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_163gszhjddr&quot;&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_164c3qvjgc8&quot;&gt;&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_165fmxdvk7k&quot;&gt;&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_166g3hpvmc8&quot;&gt;&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_169hhrzw3d2&quot;&gt;&lt;/DIV&gt;&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_167t3t4zjww&quot;&gt;&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_170c9tgjjdj&quot;&gt;&lt;/DIV&gt;&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_168ffvhczfk&quot;&gt;&lt;/DIV&gt; &lt;DIV style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: left&quot;&gt;&lt;IMG src=&quot;http://docs.google.com/File?id=d22xvwb_171ftq2prcb&quot;&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt; &lt;H3&gt;CGIstr.c &lt;/H3&gt; &lt;P&gt;/*************************************************************************/&lt;BR&gt;/**                                                                     **/&lt;BR&gt;/**     getcgivars.c-- routine to read CGI input variables into an      **/&lt;BR&gt;/**         array of strings.                                           **/&lt;BR&gt;/**                                                                     **/&lt;BR&gt;/**     Written in 1996 by James Marshall, &lt;A href=&quot;mailto:james@jmarshall.com&quot;&gt;james@jmarshall.com&lt;/A&gt;, except  **/&lt;BR&gt;/**     that the x2c() and unescape_url() routines were lifted directly **/&lt;BR&gt;/**     from NCSA&#39;s sample program util.c, packaged with their HTTPD.   **/&lt;BR&gt;/**                                                                     **/&lt;BR&gt;/**     For the latest, see &lt;A href=&quot;http://www.jmarshall.com/easy/cgi/&quot;&gt;http://www.jmarshall.com/easy/cgi/&lt;/A&gt; .        **/&lt;BR&gt;/**                                                                     **/&lt;BR&gt;/*************************************************************************/&lt;/P&gt; &lt;P&gt;#include &amp;lt;stdio.h&amp;gt;&lt;BR&gt;#include &amp;lt;string.h&amp;gt;&lt;BR&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;/P&gt; &lt;P&gt;/** Convert a two-char hex string into the char it represents. **/&lt;BR&gt;char x2c(char *what)&lt;BR&gt;{&lt;BR&gt;   register char digit;&lt;/P&gt; &lt;P&gt;   digit = (what[0] &amp;gt;= &#39;A&#39; ? ((what[0] &amp;amp; 0xdf) - &#39;A&#39;)+10 : (what[0] - &#39;0&#39;));&lt;BR&gt;   digit *= 16;&lt;BR&gt;   digit += (what[1] &amp;gt;= &#39;A&#39; ? ((what[1] &amp;amp; 0xdf) - &#39;A&#39;)+10 : (what[1] - &#39;0&#39;));&lt;BR&gt;   return(digit);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;/** Reduce any %xx escape sequences to the characters they represent. **/&lt;BR&gt;void unescape_url(char *url)&lt;BR&gt;{&lt;BR&gt;    register int i,j;&lt;/P&gt; &lt;P&gt;    for(i=0,j=0; url[j]; ++i,++j) {&lt;BR&gt;        if((url[i] = url[j]) == &#39;%&#39;) {&lt;BR&gt;            url[i] = x2c(&amp;amp;url[j+1]) ;&lt;BR&gt;            j+= 2 ;&lt;BR&gt;        }&lt;BR&gt;    }&lt;BR&gt;    url[i] = &#39;0&#39; ;&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;/** Read the CGI input and place all name/val pairs into list.        **/&lt;BR&gt;/** Returns list containing name1, value1, name2, value2, ... , NULL  **/&lt;BR&gt;char **&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff9900&gt;getcgivars&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;()&lt;BR&gt;{&lt;BR&gt;    register int i ;&lt;BR&gt;    char *request_method ;&lt;BR&gt;    int content_length;&lt;BR&gt;    char *cgiinput ;&lt;BR&gt;    char **cgivars ;&lt;BR&gt;    char **pairlist ;&lt;BR&gt;    int paircount ;&lt;BR&gt;    char *nvpair ;&lt;BR&gt;    char *eqpos ;&lt;/P&gt; &lt;P&gt;    /** Depending on the request method, read all CGI input into cgiinput. **/&lt;BR&gt;    request_method= getenv(&quot;&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6666&gt;REQUEST_METHOD&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;&quot;) ;&lt;/P&gt; &lt;P&gt;    if(request_method == NULL)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;request_method is NULLn&quot;);&lt;BR&gt;     request_method= &quot;&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6666&gt;GET&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;&quot;;&lt;BR&gt;    }&lt;/P&gt; &lt;P&gt;    if (!strcmp(request_method, &quot;GET&quot;) || !strcmp(request_method, &quot;HEAD&quot;) ) {&lt;BR&gt;        /* Some servers apparently don&#39;t provide QUERY_STRING if it&#39;s empty, */&lt;BR&gt;        /*   so avoid strdup()&#39;ing a NULL pointer here.                      */&lt;BR&gt;        char *qs ;&lt;BR&gt;        qs = getenv(&quot;&lt;STRONG&gt;&lt;EM&gt;&lt;FONT color=#ff6666&gt;QUERY_STRING&lt;/FONT&gt;&lt;/EM&gt;&lt;/STRONG&gt;&quot;) ;&lt;/P&gt; &lt;P&gt;    printf(&quot;&amp;lt;p&amp;gt;qs: %s&amp;lt;/p&amp;gt;&quot;,qs);&lt;BR&gt;    if(qs == NULL)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;qs is NULLn&quot;);&lt;BR&gt;        qs = &quot;&lt;A href=&quot;http://192.168.0.200/cgi-bin/led_flash.cgi?checkedbox=LED0&amp;amp;checkedbox=LED2&amp;amp;submitbutton=Do+it%21&quot;&gt;http://192.168.0.200/cgi-bin/led_flash.cgi?checkedbox=LED0&amp;amp;checkedbox=LED2&amp;amp;submitbutton=Do+it%21&lt;/A&gt;&quot;;&lt;BR&gt;    }&lt;BR&gt; &lt;BR&gt;        cgiinput= strdup(qs  ? qs  : &quot;&quot;) ;&lt;BR&gt;    }&lt;BR&gt;    else if (!strcmp(request_method, &quot;&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6666&gt;POST&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;&quot;)) {&lt;BR&gt;        /* strcasecmp() is not supported in Windows-- use strcmpi() instead */&lt;BR&gt;        if ( strcasecmp(getenv(&quot;&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6666&gt;CONTENT_TYPE&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;&quot;), &quot;application/x-www-form-urlencoded&quot;)) {&lt;BR&gt;         printf(&quot;Content-Type: text/plainnn&quot;) ;&lt;BR&gt;            printf(&quot;getcgivars(): Unsupported Content-Type.n&quot;) ;&lt;BR&gt;            exit(1) ;&lt;BR&gt;        }&lt;BR&gt;        if ( !(content_length = atoi(getenv(&quot;&lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff6666&gt;CONTENT_LENGTH&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;&quot;))) ) {&lt;BR&gt;         printf(&quot;Content-Type: text/plainnn&quot;) ;&lt;BR&gt;            printf(&quot;getcgivars(): No Content-Length was sent with the POST request.n&quot;) ;&lt;BR&gt;            exit(1) ;&lt;BR&gt;        }&lt;BR&gt;        if ( !(cgiinput= (char *) malloc(content_length+1)) ) {&lt;BR&gt;         printf(&quot;Content-Type: text/plainnn&quot;) ;&lt;BR&gt;            printf(&quot;getcgivars(): Couldn&#39;t malloc for cgiinput.n&quot;) ;&lt;BR&gt;            exit(1) ;&lt;BR&gt;        }&lt;BR&gt;        if (!&lt;FONT color=#3366ff&gt;&lt;EM&gt;&lt;STRONG&gt;fread&lt;/STRONG&gt;&lt;/EM&gt;&lt;/FONT&gt;(cgiinput, content_length, 1, &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#3366ff&gt;stdin&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;)) {&lt;BR&gt;         printf(&quot;Content-Type: text/plainnn&quot;) ;&lt;BR&gt;            printf(&quot;getcgivars(): Couldn&#39;t read CGI input from STDIN.n&quot;) ;&lt;BR&gt;            exit(1) ;&lt;BR&gt;        }&lt;BR&gt;        cgiinput[content_length]=&#39;0&#39; ;&lt;BR&gt;    }&lt;BR&gt;    else {&lt;BR&gt;     printf(&quot;Content-Type: text/plainnn&quot;) ;&lt;BR&gt;        printf(&quot;getcgivars(): Unsupported REQUEST_METHOD.n&quot;) ;&lt;BR&gt;        exit(1) ;&lt;BR&gt;    }&lt;/P&gt; &lt;P&gt;    /** Change all plusses back to spaces. **/&lt;BR&gt;    for (i=0; cgiinput[i]; i++) if (cgiinput[i] == &#39;+&#39;) cgiinput[i] = &#39; &#39; ;&lt;/P&gt; &lt;P&gt;    /** First, split on &quot;&amp;amp;&quot; and &quot;;&quot; to extract the name-value pairs into **/&lt;BR&gt;    /**   pairlist.                                                      **/&lt;BR&gt;    pairlist= (char **) malloc(256*sizeof(char **)) ;&lt;BR&gt;    paircount= 0 ;&lt;BR&gt;    nvpair= strtok(cgiinput, &quot;&amp;amp;;?&quot;) ;&lt;BR&gt;    while (nvpair) {&lt;BR&gt;        pairlist[paircount++]= strdup(nvpair) ;&lt;BR&gt;        if (!(paircount%256))&lt;BR&gt;            pairlist= (char **) realloc(pairlist,(paircount+256)*sizeof(char **)) ;&lt;BR&gt;        nvpair= strtok(NULL, &quot;&amp;amp;;&quot;) ;&lt;BR&gt;    }&lt;BR&gt;    pairlist[paircount]= 0 ;    /* terminate the list with NULL */&lt;/P&gt; &lt;P&gt;    /** Then, from the list of pairs, extract the names and values. **/&lt;BR&gt;    cgivars= (char **) malloc((paircount*2+1)*sizeof(char **)) ;&lt;BR&gt;    for (i= 0; i&amp;lt;paircount; i++) {&lt;BR&gt;        if (eqpos=strchr(pairlist[i], &#39;=&#39;)) {&lt;BR&gt;            *eqpos= &#39;0&#39; ;&lt;BR&gt;            unescape_url(cgivars[i*2+1]= strdup(eqpos+1)) ;&lt;BR&gt;        } else {&lt;BR&gt;            unescape_url(cgivars[i*2+1]= strdup(&quot;&quot;)) ;&lt;BR&gt;        }&lt;BR&gt;        unescape_url(cgivars[i*2]= strdup(pairlist[i])) ;&lt;BR&gt;    }&lt;BR&gt;    cgivars[paircount*2]= 0 ;   /* terminate the list with NULL */&lt;BR&gt;    &lt;BR&gt;    /** Free anything that needs to be freed. **/&lt;BR&gt;    free(cgiinput) ;&lt;BR&gt;    for (i=0; pairlist[i]; i++) free(pairlist[i]) ;&lt;BR&gt;    free(pairlist) ;&lt;/P&gt; &lt;P&gt;    /** Return the list of name-value strings. **/&lt;BR&gt;    return cgivars ;&lt;BR&gt;    &lt;BR&gt;}&lt;/P&gt; &lt;P&gt;/***************** end of the getcgivars() module ********************/&lt;/P&gt; &lt;P&gt; &lt;/P&gt; &lt;H3&gt;led_flash.c &lt;/H3&gt; &lt;P&gt;/****************************************/&lt;BR&gt;/**   Creator PIO(LED) Test Program    **/&lt;BR&gt;/****************************************/&lt;BR&gt;#include &amp;lt;stdio.h&amp;gt;&lt;BR&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;BR&gt;#include &amp;lt;unistd.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/types.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/wait.h&amp;gt;&lt;/P&gt; &lt;P&gt;#include &amp;lt;signal.h&amp;gt;&lt;BR&gt;#include &amp;lt;strings.h&amp;gt;&lt;BR&gt;#include &amp;lt;fcntl.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/ioctl.h&amp;gt;&lt;BR&gt;#include &amp;lt;sys/socket.h&amp;gt;&lt;BR&gt;#include &amp;lt;netinet/in.h&amp;gt;&lt;BR&gt;#include &amp;lt;errno.h&amp;gt;&lt;BR&gt;#include &amp;lt;netdb.h&amp;gt;&lt;/P&gt; &lt;P&gt;//#include &quot;led-creator.h&quot;&lt;BR&gt;#include &quot;creator_s3c2410_lcd.h&quot;&lt;/P&gt; &lt;P&gt;char **getcgivars();&lt;/P&gt; &lt;P&gt;int  testLED(unsigned short data)&lt;BR&gt;{&lt;BR&gt; int   fd, ret;&lt;BR&gt;// unsigned short data;&lt;BR&gt; &lt;BR&gt; fd = open(&quot;/dev/lcd&quot;, O_RDWR);&lt;BR&gt; if (fd &amp;lt; 0){ &lt;BR&gt;            printf(&quot;Open /dev/lcd errorn&quot;);&lt;BR&gt;            return (-1);&lt;BR&gt;        }&lt;BR&gt;/*&lt;/P&gt; &lt;P&gt; Update the code&lt;BR&gt; &lt;BR&gt;*/ &lt;BR&gt; // 點亮全部8 LED Lamps, 1 : 亮, 0 : 不亮&lt;BR&gt;        //data = 0xff; //LED_ALL_ON; &lt;BR&gt; ioctl(fd, LED_IOCTL_SET, &amp;amp;data);&lt;BR&gt; //sleep(3);&lt;BR&gt;#if 0&lt;BR&gt; // 點亮全部8 LED Lamps, 1 : 亮, 0 : 不亮&lt;BR&gt;        data = 0xff; //LED_ALL_ON; &lt;BR&gt; ioctl(fd, LED_IOCTL_SET, &amp;amp;data);&lt;BR&gt; sleep(3);&lt;BR&gt; &lt;/P&gt; &lt;P&gt; // 熄滅單一個D9之LED Lamp &lt;BR&gt; data = 0x1; //LED_D9_INDEX;&lt;BR&gt; ret = ioctl(fd, LED_IOCTL_BIT_CLEAR, &amp;amp;data);&lt;BR&gt; sleep(3); &lt;BR&gt; &lt;BR&gt; // 點亮單一個D9之LED Lamp  &lt;BR&gt; data = 0x1; //LED_D9_INDEX;&lt;BR&gt; ret = ioctl(fd, LED_IOCTL_BIT_SET, &amp;amp;data); &lt;BR&gt;#endif&lt;BR&gt; &lt;BR&gt; close(fd); &lt;BR&gt; return (ret);&lt;BR&gt;}&lt;/P&gt; &lt;P&gt;&lt;BR&gt;//char * msg = &quot;LED toggle! q--  exit,2- led on, 1-- led off n&quot;;&lt;/P&gt; &lt;P&gt;int main()&lt;BR&gt;{&lt;BR&gt;    int i, j;&lt;BR&gt;    char** cgivars;&lt;BR&gt;    char *ptr;&lt;BR&gt;    char Index;&lt;BR&gt;    unsigned char value;&lt;/P&gt; &lt;P&gt;    printf(&quot;Content-type: text/htmlnn&quot;);   &lt;BR&gt;    printf(&quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;CGI DEMO&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;n&quot;);&lt;BR&gt;    printf(&quot;&amp;lt;body bgcolor=&quot;#FFFFFF&quot;&amp;gt;n&quot;);&lt;BR&gt;    printf(&quot;&amp;lt;h1&amp;gt;Hello CGI World!&amp;lt;/h1&amp;gt;n&quot;);&lt;BR&gt;        &lt;BR&gt;    printf(&quot;If you can read this and you can see the LED flash, then the CGI worked.n&quot;);&lt;BR&gt;    printf(&quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;n&quot;);&lt;BR&gt;    fflush(stdout);&lt;BR&gt; &lt;BR&gt;    cgivars = &lt;EM&gt;&lt;STRONG&gt;&lt;FONT color=#ff9900&gt;getcgivars&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/EM&gt;();&lt;BR&gt;    &lt;BR&gt;#if 1&lt;BR&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;    i = 0; value = 0;&lt;BR&gt;    while(cgivars[i] != 0)&lt;BR&gt;    {&lt;BR&gt;        printf(&quot;&amp;lt;p&amp;gt;%s = %s&amp;lt;/p&amp;gt;n&quot;, cgivars[i], cgivars[i+1]);&lt;BR&gt;        ptr = cgivars[i+1]; &lt;BR&gt;        Index = ptr[3] - &#39;0&#39;;&lt;BR&gt;        //printf(&quot;ptr=%s, Index=%dn&quot;, ptr, Index);&lt;/FONT&gt;&lt;/EM&gt;&lt;/P&gt; &lt;P&gt;&lt;EM&gt;&lt;FONT color=#3366ff&gt;        value += (1 &amp;lt;&amp;lt; Index);&lt;BR&gt;        i= i + 2;     &lt;BR&gt;// Compare cgivars with LEDx and then call LEDtest        &lt;BR&gt;     }&lt;/FONT&gt;&lt;/EM&gt;&lt;BR&gt;#else&lt;BR&gt;    value = 0x55;&lt;BR&gt;#endif&lt;/P&gt; &lt;P&gt;&lt;BR&gt;    printf(&quot;LED data = %xn&quot;, value);&lt;BR&gt;    testLED(value);&lt;BR&gt;    &lt;BR&gt;    free(cgivars);&lt;/P&gt; &lt;P&gt; return 0;&lt;BR&gt;}&lt;BR&gt;&lt;/P&gt; &lt;P&gt; &lt;/P&gt;</content><link rel='replies' type='application/atom+xml' href='http://bantolinux.blogspot.com/feeds/1768911704484237450/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36435979/1768911704484237450' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/1768911704484237450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36435979/posts/default/1768911704484237450'/><link rel='alternate' type='text/html' href='http://bantolinux.blogspot.com/2007/05/cgi-cgistr.html' title=''/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>