<?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: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-36581178</id><updated>2012-02-11T19:37:06.830-08:00</updated><category term='股票'/><category term='linux'/><category term='生活'/><category term='健力運動'/><category term='健康'/><category term='PCI'/><category term='File System'/><category term='linux kernel'/><category term='vim'/><category term='Ubuntu'/><category term='英文'/><category term='c program'/><category term='assembly'/><category term='bios'/><category term='Programming'/><category term='USB'/><title type='text'>bboytaiwan"少年當立凌雲志"</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>59</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-36581178.post-6968779225656205672</id><published>2011-05-01T18:10:00.000-07:00</published><updated>2011-05-01T18:40:18.643-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux kernel'/><title type='text'>How to port Cypress Barcode reader configuration from 2.6.38 to 2.6.32</title><content type='html'>一開始拿到barcode reader插入Andes的.32 kernel。UART console吐出這樣的錯誤訊息：&lt;br /&gt;&lt;br&gt;&lt;br /&gt;~ # usb 3-1: new low speed USB device using ohci_hcd and address 2&lt;br /&gt;usb 3-1: configuration #1 chosen from 1 choice&lt;br /&gt;generic-usb: probe of 0003:04B4:BCA1.0001 failed with error -22&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;br /&gt;接著在drivers/base/dd.c的really_probe()發現這段code:&lt;br /&gt;probe_failed:&lt;br /&gt; devres_release_all(dev);&lt;br /&gt; driver_sysfs_remove(dev);&lt;br /&gt; dev-&gt;driver = NULL;&lt;br /&gt;&lt;br /&gt; if (ret != -ENODEV &amp;&amp; ret != -ENXIO) {&lt;br /&gt;  /* driver matched but the probe failed */&lt;br /&gt;  printk(KERN_WARNING&lt;br /&gt;         "%s: probe of %s failed with error %d\n",&lt;br /&gt;         drv-&gt;name, dev_name(dev), ret);&lt;br /&gt; }&lt;br /&gt;&lt;br&gt;&lt;br /&gt;再試試看在really_probe()的一開頭加上dump_stack();得到：&lt;br /&gt;[&lt;c019da26&gt;] driver_probe_device+0x42/0x158&lt;br /&gt;[&lt;c019dbce&gt;] __device_attach+0x22/0x2c&lt;br /&gt;[&lt;c019d204&gt;] bus_for_each_drv+0x4c/0x7c&lt;br /&gt;[&lt;c019dc4e&gt;] device_attach+0x52/0x6c&lt;br /&gt;[&lt;c019d064&gt;] bus_probe_device+0x24/0x48&lt;br /&gt;[&lt;c019be2a&gt;] device_add+0x29a/0x3d0&lt;br /&gt;[&lt;c01f7432&gt;] hid_add_device+0x15a/0x18c&lt;br /&gt;[&lt;c01fe296&gt;] usbhid_probe+0x28a/0x2e0&lt;br /&gt;[&lt;c01d31c8&gt;] usb_probe_interface+0x104/0x148&lt;br /&gt;[&lt;c019daac&gt;] driver_probe_device+0xc8/0x158&lt;br /&gt;[&lt;c019dbce&gt;] __device_attach+0x22/0x2c&lt;br /&gt;[&lt;c019d204&gt;] bus_for_each_drv+0x4c/0x7c&lt;br /&gt;[&lt;c019dc4e&gt;] device_attach+0x52/0x6c&lt;br /&gt;[&lt;c019d064&gt;] bus_probe_device+0x24/0x48&lt;br /&gt;[&lt;c019be2a&gt;] device_add+0x29a/0x3d0&lt;br /&gt;[&lt;c01d2988&gt;] usb_set_configuration+0x514/0x584&lt;br /&gt;[&lt;c01d8a82&gt;] generic_probe+0x66/0xac&lt;br /&gt;[&lt;c01d2bea&gt;] usb_probe_device+0x26/0x30&lt;br /&gt;[&lt;c019daac&gt;] driver_probe_device+0xc8/0x158&lt;br /&gt;[&lt;c019dbce&gt;] __device_attach+0x22/0x2c&lt;br /&gt;[&lt;c019d204&gt;] bus_for_each_drv+0x4c/0x7c&lt;br /&gt;[&lt;c019dc4e&gt;] device_attach+0x52/0x6c&lt;br /&gt;[&lt;c019d064&gt;] bus_probe_device+0x24/0x48&lt;br /&gt;[&lt;c019be2a&gt;] device_add+0x29a/0x3d0&lt;br /&gt;[&lt;c01ccf50&gt;] usb_new_device+0x50/0xa4&lt;br /&gt;[&lt;c01ce542&gt;] hub_thread+0xc42/0x1174&lt;br /&gt;[&lt;c005c758&gt;] kthread+0x74/0x88&lt;br /&gt;[&lt;c004a638&gt;] do_exit+0x0/0x604&lt;br /&gt;&lt;br&gt;&lt;br /&gt;可以判斷出來這就是hid的driver找不到的問題。接著我把bca1，也就是barcode device ID拿來grep。&lt;br /&gt;果然在"hid/hid-ids.h:#define USB_DEVICE_ID_CYPRESS_BARCODE_3   0xbca1"找到define。接著在把USB_DEVICE_ID_CYPRESS_BARCODE_3拿來grep。找到&lt;br /&gt;hid/hid-core.c: { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) },&lt;br /&gt;hid/hid-cypress.c:      { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3),&lt;br /&gt;&lt;br&gt;&lt;br /&gt;再注意把menuconfig裡面的Device Drivers  ---&gt;[*] HID Devices  ---&gt;Special HID drivers  ---&gt;&lt;*&gt; Cypress打開。&lt;br /&gt;&lt;br&gt;&lt;br /&gt;還要注意一下git diff v2.6.32 v2.6.38 drivers/hid/Kconfig&lt;br /&gt;          git diff v2.6.32 v2.6.38 drivers/hid/Makefile&lt;br /&gt;          git diff v2.6.32 v2.6.38 drivers/hid/hid-cypress.c&lt;br /&gt;看起來cypress都沒什大的變動，所以可以不用修改直接上沒問題。&lt;br /&gt;重新開機後load進新的kernel就可以抓到了。&lt;br /&gt;&lt;br&gt;&lt;br /&gt;input: Guest Barcode Reader as /devices/pci0000:00/0000:00:08.1/usb3/3-1/3-1:1.0/input/input0&lt;br /&gt;cypress 0003:04B4:BCA1.0001: input: USB HID v1.00 Keyboard [Guest Barcode Reader] on usb-0000:00:08.1-1/input0&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-6968779225656205672?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/6968779225656205672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=6968779225656205672' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/6968779225656205672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/6968779225656205672'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2011/05/how-to-port-cypress-barcode-reader.html' title='How to port Cypress Barcode reader configuration from 2.6.38 to 2.6.32'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-5326985701242679624</id><published>2011-01-25T17:48:00.000-08:00</published><updated>2011-01-25T19:15:30.339-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='USB'/><title type='text'>USB OHCI Introduction(part 2:ED structure)</title><content type='html'>&lt;div&gt;不管是periodic list or non-periodic list，ED和TD的連接方式大概如下圖所示：&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_r6LKRJP8V4w/TT9_BOq0zsI/AAAAAAAAAbA/SsA38UN-Er0/s1600/ed.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 291px;" src="http://2.bp.blogspot.com/_r6LKRJP8V4w/TT9_BOq0zsI/AAAAAAAAAbA/SsA38UN-Er0/s400/ed.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5566307323547537090" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;大家都知道USB基本的結構把每個device assign一個address，&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;並且每個device會有一些endpoints，透過address &amp;amp; endpoint number(ED裡面有address和endpoint欄位)，&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;HC可以區分要把TD送到哪個device，對特定的endpoint做資料傳輸的動作。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;不同的ED就代表不同的devices上的endpoint，對每個特定endpoint做動作就是TD。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;舉個例子來說Control transferr基本上傳輸到address 0的endpoint 0，&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;所以address 0 &amp;amp; endpoint 0就佔有一個ED。一個Control transfer後面&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;接了三個transaction（setup, data, transaction）所以，會有三個TD接在ED後面。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;接下來看ED的structure:值得注意的是寫code的時候ed structu要記得16 bytes aligned。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img src="http://3.bp.blogspot.com/_r6LKRJP8V4w/TT-Ew7zynmI/AAAAAAAAAbI/Zs5ag8X4ADs/s400/edf.JPG" style="cursor:pointer; cursor:hand;width: 400px; height: 177px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5566313640676728418" /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;每個field的詳細內容：&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img src="http://1.bp.blogspot.com/_r6LKRJP8V4w/TT-FktY9fiI/AAAAAAAAAbQ/S0BY5V2770c/s400/edfd.JPG" style="cursor:pointer; cursor:hand;width: 304px; height: 400px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5566314530159296034" /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;spec 4.2.3 Endpoint Descriptor Description裡幾個keypoints:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1. 檢查&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;Halted&lt;/span&gt; &lt;/span&gt;bit &amp;amp; &lt;span class="Apple-style-span"&gt;sKip &lt;/span&gt;bit是否有on，若無繼續判斷ED裡是否有可以run的TD為比較HeadP == TailP。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;如果不等於，則代表有TD可以被執行。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;因此，需要一個dummy TD當空的，作為比較用。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;2. 當HC想要修改ED裡面的欄位，如HeadP，則可以設sKip bit。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;若是使用把ED整個移除掉，這樣要disable list(在HcControl register裡PeriodicListEnable, IsochronousEnable, ControlListEnable, BulkListEnable看是要砍哪個transfer的ED)，整個cost太大。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;HCD不應該直接動ED的HeadP/toggleCarry/Halted field，除非Halted &amp;amp; sKip bit有on。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;這個可以衍生為只要修改ED or TD有&lt;span class="Apple-style-span"&gt;兩種方式。&lt;/span&gt;&lt;span class="Apple-style-span"&gt;第一：disable ED。第二：set sKip bit。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;3. 執行完TD，有錯則設置Halted bit，並且把TD移到Done Queue。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;直到HCD處理完錯誤狀況，HC才會繼續處理這個ED，不然HC看到Halted &amp;amp; sKip就直接跳過。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-5326985701242679624?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/5326985701242679624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=5326985701242679624' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/5326985701242679624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/5326985701242679624'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2011/01/usb-ohci-introductionpart-2ed-structure.html' title='USB OHCI Introduction(part 2:ED structure)'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_r6LKRJP8V4w/TT9_BOq0zsI/AAAAAAAAAbA/SsA38UN-Er0/s72-c/ed.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-9146638987638638475</id><published>2011-01-20T18:27:00.000-08:00</published><updated>2011-01-25T19:15:40.823-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='USB'/><title type='text'>USB OHCI Introduction(part 1)</title><content type='html'>&lt;div&gt;開門見山直接進入主題：在一開機hardware reset後，device driver都還沒有介入之前，HC是在USBReset的state。OHCI spec 6.2.2提到，這個時候HC會拉reset signal通知整個bus，同時HcFmNumber這個register還不會增加count(HcFmNumber用來計算總共經過了幾個time frame)。HCD把HcControl裡的HCFS bit改成10b: UsbOPERATIONAL，從此以後進入UsbOPERATIONAL state。(其他state暫時不要管，主要focus在瞭解運作的原理)&lt;/div&gt;&lt;div&gt;&lt;img src="http://3.bp.blogspot.com/_r6LKRJP8V4w/TTj2aYD7i_I/AAAAAAAAAaw/SUS_8KH2AiY/s400/state.JPG" style="cursor:pointer; cursor:hand;width: 400px; height: 306px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5564468272612215794" /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;以下這張圖個人認為可以當作OHCI controller如何運作的一個代表。&lt;/div&gt;&lt;div&gt;每個time frame在full/low speed device來說佔有1ms，也就是在下面兩個FRAME Boundary之間間隔。在進入operational state的下一個frame boundary開始會送出SOF packet。為什麼HC會知道要送出SOF是根據HcFmRemaining這個register從0變成HcFmInterval的時候。HcFmRemaining主要的公用是用來倒數計時，初始值是11999=0x2EDF是從HcFmInterval來。full speed是12MHz，所以外部的clock每秒供給12,000,000，1ms就有12,000次。連零都算則HcFmInterval就定為11999。（這邊會有疑慮，外部的clock如果不準，這時候counter算出來就會有問題，實際上的時間就會比較短或長，因此spec上面有說這個值driver可以自己設。而且在periodic list裡，每個interrupt entry list的transaction時間長度是用usb 2.0 spec 5.11.3上面提供的公式算出來的，所以如果frame counter的時間少於實際的時間，傳輸起來會產生schedule overrun，transaction會做不完）&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;在SOF Token傳完以後(不知道多久會傳完)首先開始Non-periodic lists傳輸Non-periodic包含了control &amp;amp; bulk transfer。在OHCI裡把control transfer看得比bulk transfer還重要，所以在HcControl register有CBSR（control bulk service ratio）這兩個bits可以設定做一個bulk transaction可以做幾個control transaction。把control list的transaction結束以後會檢查有沒有滿足比率，如果是四比一，會做四個control list的transaction，再做一個bulk的transaction。等到做到爽就會開始periodic list的處理。何謂做到爽？OHCI定義了一個HcPeriodicStart這個register用來作為何時開始開始periodic list（interrupt &amp;amp; isochronous）的傳輸，HC在每次frame的結束會把HcFmRemaining拿來和HcFmRemaining做比較。如果相等periodic list傳輸開始，non-periodic結束。在periodic list裡面Interrupt list的處理，是比isochronous list還先的，之後講periodic list transfer你可以看到periodic list interrupt table那個樹狀結構，isochronous ED總是放在整個list的最後面，interrupt ED擺在前面。等到periodic list做完，才會回到Non-periodic lists，回來以後Control：Bulk繼續按照比率執行。直到Frame結束他們的比例會繼續維持著到下一個frame。&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_r6LKRJP8V4w/TTjxi7GU64I/AAAAAAAAAag/IwjlTC4_ODo/s1600/list%2Bpriority.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 192px;" src="http://2.bp.blogspot.com/_r6LKRJP8V4w/TTjxi7GU64I/AAAAAAAAAag/IwjlTC4_ODo/s400/list%2Bpriority.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5564462921898322818" /&gt;&lt;/a&gt;&lt;div&gt;在Frame Boundary做了四件事情，有前後順序：&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1. HcFrameRemaining register的值從0變成HcFrameInterval所存的值。&lt;br /&gt;&lt;/div&gt;&lt;div&gt;2. HcFrameNumber加一&lt;br /&gt;&lt;/div&gt;&lt;div&gt;3. 把HcFrameNumber的值copy到HccaFrameNumber&lt;br /&gt;&lt;/div&gt;&lt;div&gt;4. 如果StartOfFrame的bit在interrupt enable register有設定則發出StartOfFrame interrupt。&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;一開始的SOF token：就像下面的USB Bus State會K...J...K...J...這樣一直不停的變換下去。&lt;/div&gt;&lt;div&gt;&lt;img src="http://1.bp.blogspot.com/_r6LKRJP8V4w/TTjzuBZGDdI/AAAAAAAAAao/EsAajD1bHNA/s400/timing.JPG" style="cursor:pointer; cursor:hand;width: 400px; height: 230px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5564465311589469650" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-9146638987638638475?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/9146638987638638475/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=9146638987638638475' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/9146638987638638475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/9146638987638638475'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2011/01/usb-ohci-introduction.html' title='USB OHCI Introduction(part 1)'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_r6LKRJP8V4w/TTj2aYD7i_I/AAAAAAAAAaw/SUS_8KH2AiY/s72-c/state.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-4129365265864449702</id><published>2010-10-27T02:07:00.000-07:00</published><updated>2010-11-06T09:09:25.222-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux kernel'/><title type='text'>Frequency Scaling</title><content type='html'>&lt;div&gt;因為工作比較慢，所以馬上做完又換下一個，到這間公司後，好一陣子沒有寫網誌了，&lt;/div&gt;&lt;div&gt;最近完成了frequency scheduling的driver，先寫個重點紀錄一下。&lt;/div&gt;&lt;div&gt;接著又要再搞通Uboot的USB。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;全文開始：&lt;/div&gt;在linux底下首先打開make menuconfig-&gt;  Power Management support ---&gt;&lt;br /&gt;[*] CPU Frequency scaling ---&gt;&lt;br /&gt;Default CPUFreq governor (userspace)&lt;br /&gt;   &lt; &gt;   'performance' governor&lt;br /&gt;   &lt; &gt;   'powersave' governor&lt;br /&gt;   -*-   'userspace' governor for userspace frequency scaling&lt;br /&gt;   &lt; &gt;   'ondemand' cpufreq policy governor&lt;br /&gt;   &lt; &gt;   'conservative' cpufreq governor&lt;br /&gt;&lt;br /&gt;接著echo你想要的頻率到/sys底下的file node。&lt;br /&gt;ex:"echo 500000000 &gt; /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed"&lt;br /&gt;&lt;br /&gt;CPU就會到你所設的500MHz底下run。而500MHz會依據你code裡面做的趨近方式選擇最適合的frequency。&lt;br /&gt;（這邊的code要參考cpufreq_frequency_table_target，在drivers/cpufreq/freq_table.c）&lt;br /&gt;&lt;br /&gt;Code放在arch/nds32/platforms/ag102/freq-scaling.c&lt;br /&gt;當我們下echo 500000000 &gt; /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed&lt;br /&gt;最後會call到ag102_set_target這隻function。&lt;br /&gt;&lt;pre class="prettyprint lang-c"&gt;static struct cpufreq_driver ag102_cpufreq_driver = {&lt;br /&gt;&lt;br /&gt;    .verify = ag102_verify_policy,&lt;br /&gt;    .target = ag102_set_target,&lt;br /&gt;    .init   = ag102_cpufreq_init,&lt;br /&gt;    .get    = ag102_cpufreq_get,&lt;br /&gt;    .name   = "AG102",&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;基本上來說這function會再去call cpufreq_frequency_table_target()以找到最後要調的頻率。&lt;br /&gt;frequency scaling的基本運作原理為，程式裡面建個表這個表包涵了所有的可調頻率，他門是以基頻為單位(ex:33MHz)。調了scaling的raio，就如同33xn最後再除頻33n/d。&lt;br /&gt;&lt;br /&gt;這其中比較有趣的是 cpufreq_notify_transition(&amp;amp;freqs, CPUFREQ_PRECHANGE);和cpufreq_notify_transition(&amp;amp;freqs, CPUFREQ_POSTCHANGE);他們是&lt;br /&gt;&lt;br /&gt;分別寫在ag102_speedstep(idx)的前後用來通知相關人員頻率改變前後所有做的事情。&lt;br /&gt;之後有發生一個bug，原因是沒有在frequency改變之後，修正相關timer interrupt的frequency。(timer interrupt的設法：假設cpu的主頻被設為500--&gt;hclk=125--&gt;apb=62.5，假設1/1000中斷一次，則要告訴timer interrupt controller 62.5MHz/1000次clock cycles就要發中斷。如果cpu clock被調為250，則timer interrupt controller則31.25MHz/1000就要中斷一次)&lt;br /&gt;這個bug導致bogoMIPS測不準，bogoMIPS測量方式是在兩個timer tick中間測量所run的code需要多少個clock cycles。如果沒有重新設定timer，則導致所run的loop數，測出來會一樣。(原本的一秒可以run的clock cycles數，頻率調高後。因為timer interrupt controller沒有重設，所以導致一秒等比率變短，但頻率變快，雖然時間變短，還是可以run的和低頻率時的clock cycles一樣多)&lt;br /&gt;&lt;br /&gt;有趣的還有下面這段bogoMIPS測量的source code:&lt;br /&gt;&lt;pre class="prettyprint lang-c"&gt;&lt;br /&gt;#define LPS_PREC 8&lt;br /&gt;void calibration()&lt;br /&gt;{&lt;br /&gt;        unsigned long ticks, loopbit, lpj;&lt;br /&gt;        int lps_precision = LPS_PREC;  //這個8代表到時後會除八次&lt;br /&gt;&lt;br /&gt;        lpj = (1&amp;lt;&amp;lt;12); //shift 12=4096x2instructions=8192，而__delay裡的addi &amp; bgtz這兩個instruction平均是一點多個clock cycle所以再乘以一點多差不多接近一萬，這邊就用8192所以有個誤差值。現在的HZ=100，上面的8192是百分之一秒所run的instruction數量乘100就是0.8192Million instructions。&lt;br /&gt;&lt;br /&gt;        printk(KERN_INFO &amp;quot;Calibrating delay loop... &amp;quot;);&lt;br /&gt;        while ((lpj &amp;lt;&amp;lt;= 1) != 0) {&lt;br /&gt;                /* wait for &amp;quot;start of&amp;quot; clock tick */&lt;br /&gt;                ticks = jiffies; //不能一開始就計時，要等到下一個tick一開始才會準&lt;br /&gt;                while (ticks == jiffies) //直接計timer可能已經run到一半&lt;br /&gt;                        /* nothing */;&lt;br /&gt;                /* Go .. */&lt;br /&gt;                ticks = jiffies;&lt;br /&gt;                __delay(lpj);&lt;br /&gt;                ticks = jiffies - ticks;&lt;br /&gt;                if (ticks)&lt;br /&gt;                        break;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /*&lt;br /&gt;         * Do a binary approximation to get lpj set to&lt;br /&gt;         * equal one clock (up to lps_precision bits)&lt;br /&gt;         */&lt;br /&gt;        lpj &amp;gt;&amp;gt;= 1;  //最後出來的值是爆表的，所以要往回shfit一位，但是這樣又太小&lt;br /&gt;        loopbit = lpj;  &lt;br /&gt;        //因此要加自己除以二，如果還是爆掉，再除以二再加，這樣做八次，想辦法填到最滿&lt;br /&gt;        while (lps_precision-- &amp;amp;&amp;amp; (loopbit &amp;gt;&amp;gt;= 1)) {&lt;br /&gt;                lpj |= loopbit;&lt;br /&gt;                ticks = jiffies;&lt;br /&gt;                while (ticks == jiffies) //和上面一樣要等到下個jiffies開始再算&lt;br /&gt;                        /* nothing */;&lt;br /&gt;                ticks = jiffies;&lt;br /&gt;                __delay(lpj);&lt;br /&gt;                if (jiffies != ticks)   /* longer than 1 tick */&lt;br /&gt;                        lpj &amp;amp;= ~loopbit;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        printk(KERN_CONT &amp;quot;%lu.%02lu BogoMIPS modified(lpj=%lu)\n&amp;quot;,&lt;br /&gt;                        lpj/(500000/HZ), //lpj*2*HZ/10^6 想當於是後六位數都不看只看前面&lt;br /&gt;                        (lpj/(5000/HZ)) % 100, lpj); //lpj*2*HZ/10^4 %100相當於是後四位數都不看只看前面幾位，又因為mod 100的關係，所以只看四位數前面的兩位數。&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;上面lpj/(500000/HZ)=(lpj*2*HZ)/10^6解釋：lpj是loop次數，這個loop裡面run了兩個instruction，測試的時間為1/HZ，所以乘HZ。在現代的cpu通常一個instruction粗糙點可以看作是一個clock cycle，所以直接除1MHz就是多少MHz。&lt;br /&gt;&lt;br /&gt;__udelay長這樣，裡面只有兩行指令，不外乎減一和判斷有沒有大於零，如果小於就結束。&lt;br /&gt;&lt;pre class="prettyprint lang-c"&gt;&lt;br /&gt;static inline void __delay(unsigned long loops)&lt;br /&gt;{&lt;br /&gt;        __asm__ __volatile__ (&lt;br /&gt;                "1:\n"&lt;br /&gt;                "\taddi\t%0, %0, -1\n"&lt;br /&gt;                "\tbgtz\t%0, 1b\n"&lt;br /&gt;                : "=r" (loops) : "0" (loops));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;順便一提__udelay()，其實ucdelay的loop=lpj*Hz*2*usecs/10^6。&lt;br /&gt;&lt;br /&gt;乘一個0x8000000000000000ULL是放大精準度+0x80000000ULL是無條件進位。&lt;br /&gt;&lt;br /&gt;500000/HZ相當於Hz*2/10^6。所以下面function第一行是把Hz*2*usecs/10^6先做掉。&lt;br /&gt;lpj放到inline assembly裡去乘。&lt;br /&gt;&lt;br /&gt;估計會這樣做的原因是防止truncation的問題，如果直接做lpj*Hz*2*usecs再除10^6怕會truncate掉很多。&lt;br /&gt;但應該也有別的作法。&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint lang-c"&gt;&lt;br /&gt;static inline void __udelay(unsigned long usecs, unsigned long lpj)&lt;br /&gt;{&lt;br /&gt;        usecs *= (unsigned long) (((0x8000000000000000ULL / (500000 / HZ)) +&lt;br /&gt;                        0x80000000ULL) &gt;&gt; 32);&lt;br /&gt;&lt;br /&gt;        __asm__ __volatile__ (&lt;br /&gt;                "mult64\t$d0, %1, %2\n"&lt;br /&gt;                "\tmfusr\t%0, $d0.hi\n"&lt;br /&gt;                : "=r" (usecs) : "0" (usecs), "r" (lpj)&lt;br /&gt;                : "$d0.hi", "$d0.lo");&lt;br /&gt;        __delay(usecs);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;reference:&lt;a href="http://www.91linux.com/html/article/kernel/20100402/19083_2.html"&gt;linux驅動開發必看：詳解神秘內核&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-4129365265864449702?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/4129365265864449702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=4129365265864449702' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/4129365265864449702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/4129365265864449702'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2010/10/frequency-scaling.html' title='Frequency Scaling'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-3745310628825752045</id><published>2010-01-29T02:07:00.000-08:00</published><updated>2010-01-29T02:31:17.882-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c program'/><title type='text'>switch和if else的差別</title><content type='html'>下午無聊忽然想到這個問題，就寫個sample反組譯一下：&lt;br /&gt;gcc -S practice.c&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint lang-c"&gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt; int a = 1;&lt;br /&gt;&lt;br /&gt; switch(a) {&lt;br /&gt;  case 1:&lt;br /&gt;   printf("case 1\n");&lt;br /&gt;   break;&lt;br /&gt;  case 2:&lt;br /&gt;   printf("case 2\n");&lt;br /&gt;   break;&lt;br /&gt;  case 3:&lt;br /&gt;   printf("case 3\n");&lt;br /&gt; };&lt;br /&gt;&lt;br /&gt; if (a == 1) {&lt;br /&gt;  printf("case 1\n");&lt;br /&gt; } else if (a == 2) {&lt;br /&gt;  printf("case 2\n");&lt;br /&gt; } else if (a == 3) {&lt;br /&gt;  printf("case 3\n");&lt;br /&gt; }&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;組合語言的程式如下：&lt;br /&gt;&lt;pre class="prettyprint" assembly=""&gt;&lt;br /&gt;.file "practice.c"&lt;br /&gt; .section .rodata&lt;br /&gt;.LC0:&lt;br /&gt; .string "case 1"&lt;br /&gt;.LC1:&lt;br /&gt; .string "case 2"&lt;br /&gt;.LC2:&lt;br /&gt; .string "case 3"&lt;br /&gt; .text&lt;br /&gt;.globl main&lt;br /&gt; .type main, @function&lt;br /&gt;main:&lt;br /&gt; pushl %ebp&lt;br /&gt; movl %esp, %ebp&lt;br /&gt; andl $-16, %esp&lt;br /&gt; subl $32, %esp&lt;br /&gt; movl $1, 28(%esp)&lt;br /&gt; movl 28(%esp), %eax&lt;br /&gt; cmpl $2, %eax&lt;br /&gt; je .L4&lt;br /&gt; cmpl $3, %eax&lt;br /&gt; je .L5&lt;br /&gt; cmpl $1, %eax&lt;br /&gt; jne .L2&lt;br /&gt;.L3:&lt;br /&gt; movl $.LC0, (%esp)&lt;br /&gt; call puts&lt;br /&gt; jmp .L2&lt;br /&gt;.L4:&lt;br /&gt; movl $.LC1, (%esp)&lt;br /&gt; call puts&lt;br /&gt; jmp .L2&lt;br /&gt;.L5:&lt;br /&gt; movl $.LC2, (%esp)&lt;br /&gt; call puts&lt;br /&gt;.L2:&lt;br /&gt; cmpl $1, 28(%esp)&lt;br /&gt; jne .L6&lt;br /&gt; movl $.LC0, (%esp)&lt;br /&gt; call puts&lt;br /&gt; jmp .L7&lt;br /&gt;.L6:&lt;br /&gt; cmpl $2, 28(%esp)&lt;br /&gt; jne .L8&lt;br /&gt; movl $.LC1, (%esp)&lt;br /&gt; call puts&lt;br /&gt; jmp .L7&lt;br /&gt;.L8:&lt;br /&gt; cmpl $3, 28(%esp)&lt;br /&gt; jne .L7&lt;br /&gt; movl $.LC2, (%esp)&lt;br /&gt; call puts&lt;br /&gt;.L7:&lt;br /&gt; movl $0, %eax&lt;br /&gt; leave&lt;br /&gt; ret&lt;br /&gt; .size main, .-main&lt;br /&gt; .ident "GCC: (Ubuntu 4.4.1-4ubuntu8) 4.4.1"&lt;br /&gt; .section .note.GNU-stack,"",@progbits&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;你可以看出，switch case是在&lt;span style="color: rgb(255, 0, 0);"&gt;等於判斷條件&lt;/span&gt;的時候才會jmp，而if else是&lt;span style="color: rgb(255, 0, 0);"&gt;每次不等於判斷敘述&lt;/span&gt;就jmp。所以在使用上如果是case較於分散的例子，應該要用switch這種方式，若是有一種條件是主要的發生狀況（&gt;50%），則要用if else，且把他放在第一判斷條件處（因為放在第一個位置可以減少一個jmp，若是放在switch則每次至少需要一次的jmp）。其他的話用哪個都沒差，主要使用上不管是switch or if else，都一定要按照發生的比率從前面排下來，才能減少判斷上的時間浪費。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-3745310628825752045?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/3745310628825752045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=3745310628825752045' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/3745310628825752045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/3745310628825752045'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2010/01/switchif-else.html' title='switch和if else的差別'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-2699519951003505555</id><published>2010-01-07T02:21:00.000-08:00</published><updated>2010-01-11T21:20:22.887-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux kernel'/><title type='text'>Spin lock &amp; work queue 整理</title><content type='html'>&lt;span style="font-weight: bold;"&gt;SPIN LOCK&lt;/span&gt;&lt;br /&gt;essential linux device driver的第二章A peek inside the kernel裡頭的Concurreny in the kernel有提到使用spin lock的四種case。寫得非常好。可以參考看看。&lt;br /&gt;&lt;br /&gt;我的理解是這樣的，spin lock存在的目的是為了避免context switch的發生，什麼時候要避免使用context switch呢？就是處理共用變數的時間非常短。這時就不需要把process抓去睡覺，取而代之的是使用spin lock等待鎖的釋放，只要spin lock等待的時間少於兩次context switch(swap process out &amp; swap process in)的時間。這樣就划的來了。而在單cpu上面只要你佔用了processor此時你要了一個lock，剛好的這個lock已經被其他的context（process or interrupt）所佔據。無論如何，當下你一定要進行context switch才能把執行權限放給其他的context把事情做完，並且把鎖釋放，這樣你才有機會獲得這把鎖。因此才有了以下不同的spin lock在單cpu裡面實做的變形，而不是真的在那邊spin。（在單處理器裡，spin lock的實做就是disable interrupt &amp; disable preemption這樣就可以避免使用semaphore導致context switch）&lt;br /&gt;&lt;br /&gt;下面把這三個function的source code攤出來看。&lt;br /&gt;spin_lock() spin_lock_irq() spin_lock_irqsave()&lt;br /&gt;&lt;br /&gt;在我的2.6.29的kernel上面spin lock的實做在uni-processor的source code裡頭是長這樣(include/linux/spinlock_api_up.h)：&lt;br /&gt;&lt;pre class="prettyprint lang-cpp"&gt;&lt;br /&gt;#ifndef __LINUX_SPINLOCK_API_UP_H&lt;br /&gt;#define __LINUX_SPINLOCK_API_UP_H&lt;br /&gt;&lt;br /&gt;#ifndef __LINUX_SPINLOCK_H&lt;br /&gt;# error &amp;quot;please don't include this file directly&amp;quot;&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * include/linux/spinlock_api_up.h&lt;br /&gt; *&lt;br /&gt; * spinlock API implementation on UP-nondebug (inlined implementation)&lt;br /&gt; *&lt;br /&gt; * portions Copyright 2005, Red Hat, Inc., Ingo Molnar&lt;br /&gt; * Released under the General Public License (GPL).&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;#define in_lock_functions(ADDR)  0&lt;br /&gt;&lt;br /&gt;#define assert_spin_locked(lock) do { (void)(lock); } while (0)&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * In the UP-nondebug case there's no real locking going on, so the&lt;br /&gt; * only thing we have to do is to keep the preempt counts and irq&lt;br /&gt; * flags straight, to suppress compiler warnings of unused lock&lt;br /&gt; * variables, and to add the proper checker annotations:&lt;br /&gt; */&lt;br /&gt;#define __LOCK(lock) \&lt;br /&gt;  do { preempt_disable(); __acquire(lock); (void)(lock); } while (0)&lt;br /&gt;&lt;br /&gt;#define __LOCK_BH(lock) \&lt;br /&gt;  do { local_bh_disable(); __LOCK(lock); } while (0)&lt;br /&gt;&lt;br /&gt;#define __LOCK_IRQ(lock) \&lt;br /&gt;  do { local_irq_disable(); __LOCK(lock); } while (0)&lt;br /&gt;&lt;br /&gt;#define __LOCK_IRQSAVE(lock, flags) \&lt;br /&gt;  do { local_irq_save(flags); __LOCK(lock); } while (0)&lt;br /&gt;&lt;br /&gt;#define __UNLOCK(lock) \&lt;br /&gt;  do { preempt_enable(); __release(lock); (void)(lock); } while (0)&lt;br /&gt;&lt;br /&gt;#define __UNLOCK_BH(lock) \&lt;br /&gt;  do { preempt_enable_no_resched(); local_bh_enable(); __release(lock); (void)(lock); } while (0)&lt;br /&gt;&lt;br /&gt;#define __UNLOCK_IRQ(lock) \&lt;br /&gt;  do { local_irq_enable(); __UNLOCK(lock); } while (0)&lt;br /&gt;&lt;br /&gt;#define __UNLOCK_IRQRESTORE(lock, flags) \&lt;br /&gt;  do { local_irq_restore(flags); __UNLOCK(lock); } while (0)&lt;br /&gt;&lt;br /&gt;#define _spin_lock(lock)   __LOCK(lock)&lt;br /&gt;#define _spin_lock_nested(lock, subclass) __LOCK(lock)&lt;br /&gt;#define _read_lock(lock)   __LOCK(lock)&lt;br /&gt;#define _write_lock(lock)   __LOCK(lock)&lt;br /&gt;#define _spin_lock_bh(lock)   __LOCK_BH(lock)&lt;br /&gt;#define _read_lock_bh(lock)   __LOCK_BH(lock)&lt;br /&gt;#define _write_lock_bh(lock)   __LOCK_BH(lock)&lt;br /&gt;#define _spin_lock_irq(lock)   __LOCK_IRQ(lock)&lt;br /&gt;#define _read_lock_irq(lock)   __LOCK_IRQ(lock)&lt;br /&gt;#define _write_lock_irq(lock)   __LOCK_IRQ(lock)&lt;br /&gt;#define _spin_lock_irqsave(lock, flags)  __LOCK_IRQSAVE(lock, flags)&lt;br /&gt;#define _read_lock_irqsave(lock, flags)  __LOCK_IRQSAVE(lock, flags)&lt;br /&gt;#define _write_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags)&lt;br /&gt;#define _spin_trylock(lock)   ({ __LOCK(lock); 1; })&lt;br /&gt;#define _read_trylock(lock)   ({ __LOCK(lock); 1; })&lt;br /&gt;#define _write_trylock(lock)   ({ __LOCK(lock); 1; })&lt;br /&gt;#define _spin_trylock_bh(lock)   ({ __LOCK_BH(lock); 1; })&lt;br /&gt;#define _spin_unlock(lock)   __UNLOCK(lock)&lt;br /&gt;#define _read_unlock(lock)   __UNLOCK(lock)&lt;br /&gt;#define _write_unlock(lock)   __UNLOCK(lock)&lt;br /&gt;#define _spin_unlock_bh(lock)   __UNLOCK_BH(lock)&lt;br /&gt;#define _write_unlock_bh(lock)   __UNLOCK_BH(lock)&lt;br /&gt;#define _read_unlock_bh(lock)   __UNLOCK_BH(lock)&lt;br /&gt;#define _spin_unlock_irq(lock)   __UNLOCK_IRQ(lock)&lt;br /&gt;#define _read_unlock_irq(lock)   __UNLOCK_IRQ(lock)&lt;br /&gt;#define _write_unlock_irq(lock)   __UNLOCK_IRQ(lock)&lt;br /&gt;#define _spin_unlock_irqrestore(lock, flags) __UNLOCK_IRQRESTORE(lock, flags)&lt;br /&gt;#define _read_unlock_irqrestore(lock, flags) __UNLOCK_IRQRESTORE(lock, flags)&lt;br /&gt;#define _write_unlock_irqrestore(lock, flags) __UNLOCK_IRQRESTORE(lock, flags)&lt;br /&gt;&lt;br /&gt;#endif /* __LINUX_SPINLOCK_API_UP_H */&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;其中&lt;br /&gt;&lt;pre class="prettyprint lang-cpp"&gt;&lt;br /&gt;#define _spin_lock(lock)   __LOCK(lock)&lt;br /&gt;#define __LOCK(lock) \&lt;br /&gt;  do { preempt_disable(); __acquire(lock); (void)(lock); } while (0)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;所以在uni-processor裡頭spin_lock的實做根本就只有把preempt關掉。再看看preempt_disable的實做在/include/linux/preempt.h&lt;br /&gt;&lt;pre class="prettyprint lang-cpp"&gt;&lt;br /&gt;#ifdef CONFIG_PREEMPT&lt;br /&gt;#define preempt_disable() \&lt;br /&gt;do { \&lt;br /&gt; inc_preempt_count(); \&lt;br /&gt; barrier(); \&lt;br /&gt;} while (0)&lt;br /&gt;#else&lt;br /&gt;#define preempt_disable()  do { } while (0)&lt;br /&gt;&lt;br /&gt;#define inc_preempt_count() add_preempt_count(1)&lt;br /&gt;&lt;br /&gt;# define add_preempt_count(val) do { preempt_count() += (val); } while (0)&lt;br /&gt;&lt;br /&gt;#define preempt_count() (current_thread_info()-&gt;preempt_count)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;上面都在同一個檔案裡，這邊只擷取用的到的部份。&lt;br /&gt;所以preempt_disable如果在CONFIG_PREEMPT的環境就是把preempt_count加一而已。&lt;br /&gt;如果是在non-preempt就根本什麼都沒做。所以如果你知道只有在process context會使用到spin_lock就可以使用最傳統的。這時儘管是preemptible kernel如果有timer interrupt進來。time slice時間已經用完了，由於切成non_preemptible的緣故，所以也不會被換出去。&lt;br /&gt;&lt;br /&gt;接下來再看看其他幾個重要的spin_lock變形：&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;spin_lock_irq&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint lang-cpp"&gt;&lt;br /&gt;#define _spin_lock_irq(lock)   __LOCK_IRQ(lock)&lt;br /&gt;#define __LOCK_IRQ(lock) \&lt;br /&gt;  do { local_irq_disable(); __LOCK(lock); } while (0)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;include/linux/irqflags:&lt;br /&gt;&lt;pre class="prettyprint lang-cpp"&gt;&lt;br /&gt;#define local_irq_disable() \&lt;br /&gt; do { raw_local_irq_disable(); trace_hardirqs_off(); } while (0)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;arch/x86/include/asm/irqflags:&lt;br /&gt;&lt;pre class="prettyprint lang-cpp"&gt;&lt;br /&gt;static inline void raw_local_irq_disable(void)&lt;br /&gt;{&lt;br /&gt; native_irq_disable();&lt;br /&gt;}&lt;br /&gt;static inline void native_irq_disable(void)&lt;br /&gt;{&lt;br /&gt; asm volatile("cli": : :"memory");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;所以在x86裡面spin_lock_irq追到最後就是把cli關掉然後在disable preemption而已。這個時候比較吶悶的是為何中斷已經關掉還要disable preemption，有可能在沒有interrupt進來的情快下被搶佔嗎？沒有timer interrupt還有可能被搶佔？後來想一想，有一個可能是這樣，儘管關掉了外部中斷，內部有可能發生像page fault的這種trap，假設現在page fault的情況是read only導致的，這時系統會copy-on-write製造新的page給這個process使用，這時若發生了記憶體空間不足的問題。就會被抓去睡覺，如此就導致了搶佔的發生。上面是個人的理解，有錯請指教。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;spin_lock_irqsave&lt;span style="font-weight:bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint lang-cpp"&gt;&lt;br /&gt;#define _spin_lock_irqsave(lock, flags)  __LOCK_IRQSAVE(lock, flags)&lt;br /&gt;#define __LOCK_IRQSAVE(lock, flags) \&lt;br /&gt;  do { local_irq_save(flags); __LOCK(lock); } while (0)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;include/linux/irqflags.h&lt;br /&gt;&lt;pre class="prettyprint lang-cpp"&gt;&lt;br /&gt;#define local_irq_save(flags)    \&lt;br /&gt; do {      \&lt;br /&gt;  typecheck(unsigned long, flags); \&lt;br /&gt;  raw_local_irq_save(flags);  \&lt;br /&gt;  trace_hardirqs_off();   \&lt;br /&gt; } while (0)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;arch/x86/include/asm/irqflags.h&lt;br /&gt;&lt;pre class="prettyprint lang-cpp"&gt;&lt;br /&gt;#define raw_local_irq_save(flags)    \&lt;br /&gt; do { (flags) = __raw_local_irq_save(); } while (0)&lt;br /&gt;&lt;br /&gt;static inline unsigned long __raw_local_irq_save(void)&lt;br /&gt;{&lt;br /&gt; unsigned long flags = __raw_local_save_flags();&lt;br /&gt;&lt;br /&gt; raw_local_irq_disable();&lt;br /&gt;&lt;br /&gt; return flags;&lt;br /&gt;}&lt;br /&gt;static inline unsigned long __raw_local_save_flags(void)&lt;br /&gt;{&lt;br /&gt; return native_save_fl();&lt;br /&gt;}&lt;br /&gt;static inline unsigned long native_save_fl(void)&lt;br /&gt;{&lt;br /&gt; unsigned long flags;&lt;br /&gt;&lt;br /&gt; asm volatile("# __raw_save_flags\n\t"&lt;br /&gt;       "pushf ; pop %0"&lt;br /&gt;       : "=g" (flags)&lt;br /&gt;       : /* no input */&lt;br /&gt;       : "memory");&lt;br /&gt;&lt;br /&gt; return flags;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;spin_lock_irqsave和spin_lock_irq的差別：多了把flag存起來的行為。&lt;br /&gt;一般來講只要有interrupt和process context共享spin lock以及process &amp; process context間共享spin lock這兩者同時發生且preemptible的情形，都會spin_lock_irqsave。若是只有process&amp;interrupt context共享lock或是像上例但是non-preemptible kernel，則只需要local_irq_save。&lt;br /&gt;&lt;br /&gt;至於spin_lock_bh則是disable softirq，詳細的使用情形則沒有研究。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;WORK QUEUE&lt;/span&gt;&lt;br /&gt;work queue是一種延遲作業的機制。一般來說預設是使用內建的worker thread。（event0/1/2/3）&lt;br /&gt;使用方法如下：&lt;br /&gt;&lt;br /&gt;1. 如果你認為使用預設的worker thread無法處理龐大工作量。此時可以create一個專有的worker thread。&lt;br /&gt;Create_workqueue(const char *name):為每個processer都create一個worker thread。&lt;br /&gt;Create_singlethread_workque(const char *name):只為當下的cpu create一個worker thread。&lt;br /&gt;記得這邊的name就是thread的name，往後可以在程式執行起來以後由ps aux看到。&lt;br /&gt;&lt;br /&gt;2. 之後宣告可以有兩種&lt;br /&gt;compile time:DECLARE_WORK(name, void (*function)(void*), void *data)&lt;br /&gt;   run time:&lt;br /&gt;   INIT_WORK(struct work_struct *work, void (*function)(void*), void *data)&lt;br /&gt;   PREPARE_WORK(struct work_struct *work, void (*function)(void*), void *data)&lt;br /&gt;PREPARE_WORK書上（linux device driver 3rd）說沒有初始化work_struct。&lt;br /&gt;&lt;br /&gt;3. 之後就是把work排進worker thread開始執行&lt;br /&gt;有兩種，第一種是排進預設的event worker thread:&lt;br /&gt;schedule_work(), schedule_delayed_work()&lt;br /&gt;第二種是排進你自己create的worker thread:&lt;br /&gt;queue_work(struct workqueue_struct *queue, struct work_struct *work)&lt;br /&gt;queue_delayed_work(struct workqueue_struct *queue, struct work_struct *work, unsigned long delay)&lt;br /&gt;第一個參數workqueue_struct就是你自己create的worker thread。&lt;br /&gt;&lt;br /&gt;4. 若你想要快點把worker thread裡頭你自己的work執行，可以使用&lt;br /&gt;flush_workqueue(struct workqueue_struct *queue)&lt;br /&gt;若是想直接cancel你所排定的工作cancel_delayed_work(struct work_struct *work)&lt;br /&gt;還是想要直接刪除你的kernel thread:destroy_workqueue(struct workqueue_struct *queue)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-2699519951003505555?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/2699519951003505555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=2699519951003505555' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/2699519951003505555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/2699519951003505555'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2010/01/spin-lock-work-queue.html' title='Spin lock &amp; work queue 整理'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-7039508831292608867</id><published>2009-11-05T22:48:00.000-08:00</published><updated>2009-11-05T23:20:02.130-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='健力運動'/><title type='text'>Prilepin's Table</title><content type='html'>Prilepin's Table是蘇聯運動科學家Alexander Sergeyevitch Prilepin所發明的。&lt;br /&gt;&lt;br /&gt;他掌握了1975~1985年的蘇聯舉重年代，據說死於1985，卒於任內。&lt;br /&gt;&lt;br /&gt;主要用來增加力量和速度的用途。&lt;br /&gt;&lt;br /&gt;假設我的硬舉1RM = 250kg如果我這一次的訓練量是打算在90%以上，則225kg以上的重量每組&lt;br /&gt;&lt;br /&gt;最多做兩下，全部加起來不超過七下。總range在4-10下之間。過少則訓練不足，過多訓練過度。&lt;br /&gt;&lt;br /&gt;要記住的是如果用負荷較低的重量訓練，每組都要用&lt;span style="color: rgb(255, 0, 0);"&gt;盡全力&lt;/span&gt;，盡量增加槓子的速度。才有訓練到CNS。&lt;br /&gt;&lt;br /&gt;表格長這樣&lt;br /&gt;&lt;br /&gt;Percent..............Reps per Set.......Optimal.......Total Range&lt;br /&gt;&lt;br /&gt;70- ......................3-6.... ..................24 ...............18-30&lt;br /&gt;70-80 ..................3-6 ......................18 ...............12-24&lt;br /&gt;80-89 ..................2-4 ......................15 ...............10-20&lt;br /&gt;90+ ....................1-2 ........................7 ................4-10&lt;br /&gt;&lt;br /&gt;下面&lt;span class="RVTS33"&gt;A.S. Prilepin’s Scientific – Practical Contribution to the Intensification of the Modern Training of Weightlifters&lt;/span&gt;這篇文章講到了Prilepin's Table的總結：&lt;br /&gt;&lt;p class="RVPS3"&gt;&lt;span class="RVTS17"&gt;1)    a significantly higher intensity of loading in which the most effective lifts are with &lt;span style="color: rgb(255, 0, 0);"&gt;near  limit weights&lt;/span&gt;.(就是做幾乎&lt;span style="color: rgb(255, 0, 0);"&gt;極限&lt;/span&gt;的重量)&lt;/span&gt;&lt;/p&gt;   &lt;p class="RVPS3"&gt;&lt;span class="RVTS17"&gt;2)    the application of the optimum number of sets and repetitions with a fundamental weight within a workout, varied in individual exercises, workouts, and periods of training. &lt;/span&gt;&lt;/p&gt;&lt;br /&gt;參考文章：&lt;br /&gt;&lt;a href="http://www.ironaddicts.com/forums/showthread.php?t=9433"&gt;Prilepin's Table(Iron Addict Forum)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.sportivnypress.com/documents/SUB_77.html"&gt;&lt;span class="RVTS33"&gt;A.S. Prilepin’s Scientific – Practical Contribution to the Intensification of the Modern Training of Weightlifters&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.texaspowerscene.com/articles/powerlifting/prilephin.html"&gt;USING PRILEPHIN'S TABLE&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-7039508831292608867?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/7039508831292608867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=7039508831292608867' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/7039508831292608867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/7039508831292608867'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/11/prilepins-table.html' title='Prilepin&apos;s Table'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-527476968391571966</id><published>2009-10-21T01:32:00.000-07:00</published><updated>2009-10-29T00:47:23.971-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><title type='text'>利用timer interrupt讓兩個Process做context switch一個印出A一個印出B</title><content type='html'>好不容易有空了，趕快回到自己的興趣抽空學習撰寫OS底層的code。&lt;br /&gt;&lt;br /&gt;我在Linux kernel完全剖析的這本書裡面看到一個範例：&lt;br /&gt;&lt;br /&gt;他的功能是讓兩個Process利用timer interrupt互相做context switch一個印出A，&lt;br /&gt;&lt;br /&gt;當context switch到另一個process則印出B。&lt;br /&gt;&lt;br /&gt;當下感到很有興趣。&lt;br /&gt;&lt;br /&gt;於是就試著改寫成用usb碟開機的版本。&lt;br /&gt;&lt;br /&gt;最後要燒錄到usb disk的image map是長成下面這樣：&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_r6LKRJP8V4w/St7Qk92NkoI/AAAAAAAAASE/qhy3_eywoCI/s1600-h/bootimg.JPG"&gt;&lt;img style="cursor: pointer; width: 400px; height: 163px;" src="http://1.bp.blogspot.com/_r6LKRJP8V4w/St7Qk92NkoI/AAAAAAAAASE/qhy3_eywoCI/s400/bootimg.JPG" alt="" id="BLOGGER_PHOTO_ID_5394978737132245634" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;boot.bin是組成boot.img的前面1個sector也就是前面512bytes，他是由boot.S編譯而來，&lt;br /&gt;&lt;br /&gt;在燒錄到usb隨身碟以後boot.bin就順理成章的變成MBR(master boot record)。&lt;br /&gt;&lt;br /&gt;接著head.bin組成後面的11個sectors，他是由head.S編譯而來的。&lt;br /&gt;&lt;br /&gt;先不要管code到底在幹麻，首先應該要了解整個code在image裡面的擺放方式，以及在記憶體內&lt;br /&gt;&lt;br /&gt;移動的路徑。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_r6LKRJP8V4w/St7pDWTipdI/AAAAAAAAASM/7qTfr8ww1Tk/s1600-h/memorymap.JPG"&gt;&lt;img style="cursor: pointer; width: 400px; height: 297px;" src="http://4.bp.blogspot.com/_r6LKRJP8V4w/St7pDWTipdI/AAAAAAAAASM/7qTfr8ww1Tk/s400/memorymap.JPG" alt="" id="BLOGGER_PHOTO_ID_5395005647372854738" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;知道了code在memory裡移動的路線之後，接著了解一下boot.img是怎麼製作出來的。&lt;br /&gt;&lt;br /&gt;&lt;pre class="pretty lang-csh"&gt;&lt;br /&gt;# Author: Gavin Guo &amp;lt;mimi0213kimo@gmail.com&amp;gt;&lt;br /&gt;#&lt;br /&gt;# This file is licensed under the GNU General Public License;&lt;br /&gt;&lt;br /&gt;CC=gcc&lt;br /&gt;LD=ld&lt;br /&gt;OBJCOPY=objcopy&lt;br /&gt;&lt;br /&gt;CFLAGS=-c&lt;br /&gt;#gcc -c的選項是把.S檔編譯成.o檔&lt;br /&gt;TRIM_FLAGS=-R .pdr -R .comment -R.note -S -O binary&lt;br /&gt;#-R的意思是remove掉不需要的section，後面接的是section的名稱&lt;br /&gt;#-S的意思是把symbol table和relocation table拿掉&lt;br /&gt;#-O的意思是要編成怎樣的target format，這邊是binary的格式，也就不帶任何資訊&lt;br /&gt;&lt;br /&gt;LDFILE_BOOT=gavin_x86_boot.ld&lt;br /&gt;LDFILE_DOS=gavin_x86_dos.ld&lt;br /&gt;LDFLAGS_BOOT=-e c -T$(LDFILE_BOOT)&lt;br /&gt;LDFLAGS_DOS=-e c -T$(LDFILE_DOS)&lt;br /&gt;#ld的參數接上-e c，e代表的是entry point，c是進入點的symbol，因為code裡面沒有c&lt;br /&gt;#所以會叫說找不到entry point。&lt;br /&gt;#-T是選擇要用的linker script檔案，裡面敘述base address是多少。&lt;br /&gt;&lt;br /&gt;all: boot.img head.bin&lt;br /&gt;&lt;br /&gt;boot.bin: boot.S&lt;br /&gt;$(CC) $(CFLAGS) boot.S&lt;br /&gt;$(LD) boot.o -o boot.elf $(LDFLAGS_BOOT)&lt;br /&gt;$(OBJCOPY) $(TRIM_FLAGS) boot.elf $@&lt;br /&gt;&lt;br /&gt;head.bin: head.S&lt;br /&gt;$(CC) $(CFLAGS) head.S&lt;br /&gt;$(LD) head.o -o head.elf $(LDFLAGS_DOS)&lt;br /&gt;$(OBJCOPY) $(TRIM_FLAGS) head.elf $@&lt;br /&gt;&lt;br /&gt;boot.img: boot.bin head.bin&lt;br /&gt;dd if=boot.bin of=boot.img bs=512 count=1&lt;br /&gt;dd if=head.bin of=boot.img seek=1 bs=512 count=11&lt;br /&gt;&lt;br /&gt;# You must have the authority to do mount, or you must use "su root" or&lt;br /&gt;# "sudo" command to do "make copy"&lt;br /&gt;copy: boot.img&lt;br /&gt;&lt;br /&gt;clean:&lt;br /&gt;@rm -f *.o *.elf *.bin *.BIN *.img&lt;br /&gt;&lt;br /&gt;distclean:&lt;br /&gt;@rm -f *.img&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://sourceware.org/binutils/docs/binutils/objcopy.html#objcopy"&gt;objcopy的manual&lt;/a&gt;&lt;br /&gt;&lt;a href="http://sourceware.org/binutils/docs-2.20/ld/Options.html#Options"&gt;ld的manual&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.cmlab.csie.ntu.edu.tw/%7Edaniel/linux/objcopy.html"&gt;台大某人寫的objcopy用法&lt;/a&gt;&lt;br /&gt;&lt;a href="http://hi.baidu.com/konglinglong/blog/item/02c74f160e81a758f2de3206.html"&gt;《自写系统》的学习笔记之一 ——实现最小的“操作系统”(1)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;gavin_x86_boot.ld長這樣:&lt;br /&gt;&lt;pre class="prettyprint lang-csh"&gt;&lt;br /&gt;SECTIONS&lt;br /&gt;{&lt;br /&gt; . = 0x0000;&lt;br /&gt; .text :&lt;br /&gt; {&lt;br /&gt;   _ftext = .;&lt;br /&gt; } = 0&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;gavin_x86_dos.ld長這樣:&lt;br /&gt;&lt;pre class="prettyprint lang-csh"&gt;&lt;br /&gt;SECTIONS&lt;br /&gt;{&lt;br /&gt; . = 0x0000;&lt;br /&gt; .text :&lt;br /&gt; {&lt;br /&gt;   _ftext = .;&lt;br /&gt; } = 0&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;看到make file和linker script後就知道boot.img是怎麼做出來的。&lt;br /&gt;接著開始trace source code。先給出boot.S：&lt;br /&gt;&lt;pre class="prettyprint lang-asm"&gt;&lt;br /&gt;BOOTSEG = 0x07c0&lt;br /&gt;SYSSEG = 0x1000&lt;br /&gt;&lt;br /&gt;//這邊是16位元的code，所以.code16&lt;br /&gt;.code16 &lt;br /&gt;.text&lt;br /&gt;&lt;br /&gt;//要記住gavin_x86_boot.ld裡面，base是設為0x0000&lt;br /&gt; jmp $BOOTSEG, $start_code&lt;br /&gt;//因為一開始的offset是0x7c00，所以先jmp到0x07c0:start_code&lt;br /&gt;//把cs改成0x07c0，這樣sp比較好算大小&lt;br /&gt;start_code:&lt;br /&gt; movw %cs, %ax&lt;br /&gt; movw %ax, %ss&lt;br /&gt; movw $0x1000, %sp&lt;br /&gt; xorw %ax, %ax&lt;br /&gt; movw %ax, %ds&lt;br /&gt;//上面把ds設為0，底下的Packet就用自己算的比較不會錯&lt;br /&gt; movw $(Packet + 0x7c00), %si&lt;br /&gt; movb $0x80, %dl&lt;br /&gt; movb $0x42, %ah&lt;br /&gt; int $0x13&lt;br /&gt; //上面ah=0x42h，通常大於8g的硬碟都要用0x42 extension的方法讀。&lt;br /&gt; //這幾行run完以後，11 sectors就存到0x10000了。&lt;br /&gt; cli&lt;br /&gt; //先關掉中斷，待會要準備進入protected mode&lt;br /&gt; cld &lt;br /&gt; //清掉direction flag，到時候movsb就是遞增方式讀取&lt;br /&gt; //從ds:si copy 到es:di&lt;br /&gt; //所以下面這幾行把11 sectors從0x10000 copy到 0x0000&lt;br /&gt; movw $SYSSEG, %ax&lt;br /&gt; movw %ax, %ds&lt;br /&gt; xorw %ax, %ax&lt;br /&gt; movw %ax, %es&lt;br /&gt; xorw %di, %di&lt;br /&gt; xorw %si, %si&lt;br /&gt; //0x1600怎麼算出來的，11x0x200=0x1600&lt;br /&gt; movw $0x1600, %cx&lt;br /&gt; rep movsb&lt;br /&gt; // rep的counter就是%cx&lt;br /&gt; &lt;br /&gt; //因為ds剛剛改掉了，所以ds這邊要清成0&lt;br /&gt; xorw %ax, %ax&lt;br /&gt; movw %ax, %ds&lt;br /&gt; lgdtw gdt_48 + 0x7c00&lt;br /&gt; //gdt_48 + 0x7c00這邊是參考ds的位置&lt;br /&gt; inb $0x92, %al&lt;br /&gt; orb $0b00000010, %al&lt;br /&gt; outb %al, $0x92&lt;br /&gt; //上面開啟A20 gate&lt;br /&gt;&lt;br /&gt; movl %cr0, %eax&lt;br /&gt; orl $1, %eax&lt;br /&gt; movl %eax, %cr0&lt;br /&gt; //把cr0的0bit on，所以會進入保護模式&lt;br /&gt; //因為進入保護模式，所以要把pipeline裡面的16bits的code清掉&lt;br /&gt; //，後面就要馬上接一個jmp&lt;br /&gt; ljmpl $0x8, $(start_32 + 0x7c00)&lt;br /&gt;&lt;br /&gt;.code32&lt;br /&gt;start_32:&lt;br /&gt;/*&lt;br /&gt; mov $0x10, %ax&lt;br /&gt; mov %ax, %gs&lt;br /&gt; mov $0x0768, %ax&lt;br /&gt; xor %edi, %edi&lt;br /&gt; mov %ax, %gs:(%edi)&lt;br /&gt; jmp .&lt;br /&gt;*/&lt;br /&gt; //jmp到code segment的base address，因為code segment存在gdt table的第&lt;br /&gt; //8個bytes所以是8。之後就是jmp到0x0000開始head.s的code&lt;br /&gt; ljmpl $0x8, $0x0 &lt;br /&gt;&lt;br /&gt; .p2align 2&lt;br /&gt;//align 2是2^2=4所以底下的code會4bytes對齊，ex:0,4,8,12這樣&lt;br /&gt;//cpu存取的時候只需要一次就可以，若是在跨界，則需要存取兩次。&lt;br /&gt;//因為gdt, ldt在座context switch時需要大量的讀取，所以要做&lt;br /&gt;//align加速讀取的速度。&lt;br /&gt;&lt;br /&gt;//這邊如果看不懂就去查gdt code,data segment descriptor怎麼填&lt;br /&gt;gdt:&lt;br /&gt;//gdt第一個entry為空，intel定的&lt;br /&gt; .long 0, 0&lt;br /&gt;code: &lt;br /&gt; .word 0xffff&lt;br /&gt; .word 0x0000&lt;br /&gt; .word 0x9800&lt;br /&gt; .word 0x00cf&lt;br /&gt;data:&lt;br /&gt; .word 0xffff&lt;br /&gt; .word 0x0000&lt;br /&gt; .word 0x9200&lt;br /&gt; .word 0x00cf&lt;br /&gt;&lt;br /&gt;/* Video Descriptor */&lt;br /&gt;//這個selector的base address是0xb8000，以方便我門印出字串做debug&lt;br /&gt;video:&lt;br /&gt; .word 0xffff&lt;br /&gt; .word 0x8000&lt;br /&gt; .word 0x920b&lt;br /&gt; .word 0x00c0&lt;br /&gt;gdt_end:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;gdt_48:&lt;br /&gt; .word (gdt_end - gdt - 1)    //gdt的長度&lt;br /&gt; .long gdt + 0x7c00           //gdt放在哪邊&lt;br /&gt;//下面int $0x13h, ah=0x42h所以看不懂的話就去查ralf brown's interrupt list&lt;br /&gt;Packet:&lt;br /&gt; size_packet: .byte 0x10     //0x10代表這個Packet有16個bytes&lt;br /&gt; reserved: .byte 0           //這個byte沒有用&lt;br /&gt; SectorToTran: .2byte 11     //總共要抓11個sectors的data&lt;br /&gt; Offset:  .2byte 0x0000      //抓來後放在0x1000:0x0000這個地方&lt;br /&gt; Segment: .2byte 0x1000&lt;br /&gt; SectorLow: .4byte 1         //從usb disk的第二個sector開始抓，&lt;br /&gt; SectorHigh: .4byte 0        //因為sector從0開始算&lt;br /&gt;&lt;br /&gt;.org 510&lt;br /&gt;.2byte 0xaa55&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;heads.S:&lt;br /&gt;&lt;pre class="prettyprint lang-c"&gt;&lt;br /&gt;/*&lt;br /&gt; *  head.s contains the 32-bit startup code.&lt;br /&gt; *  Two L3 task multitasking. The code of tasks are in kernel area, &lt;br /&gt; *  just like the Linux. The kernel code is located at 0x10000. &lt;br /&gt; */&lt;br /&gt;KRN_BASE  = 0x0&lt;br /&gt;TSS0_SEL = 0x20&lt;br /&gt;LDT0_SEL = 0x28&lt;br /&gt;TSS1_SEL = 0x30&lt;br /&gt;LDT1_SEL = 0x38&lt;br /&gt;&lt;br /&gt;.text&lt;br /&gt;startup_32:&lt;br /&gt; movl $0x10,%eax&lt;br /&gt; mov %ax,%ds&lt;br /&gt; mov %ax,%es&lt;br /&gt; mov %ax,%fs&lt;br /&gt; mov %ax,%gs&lt;br /&gt;/*&lt;br /&gt; mov $0x0768, %ax&lt;br /&gt; xor %edi, %edi&lt;br /&gt; mov %ax, %gs:(%edi)&lt;br /&gt;*/&lt;br /&gt; lss stack_ptr,%esp&lt;br /&gt;&lt;br /&gt;# setup base fields of descriptors.&lt;br /&gt; movl $KRN_BASE, %ebx&lt;br /&gt; movl $gdt, %ecx&lt;br /&gt; lea tss0, %eax&lt;br /&gt; movl $TSS0_SEL, %edi &lt;br /&gt; call set_base&lt;br /&gt; lea ldt0, %eax&lt;br /&gt; movl $LDT0_SEL, %edi&lt;br /&gt; call set_base&lt;br /&gt; lea tss1, %eax&lt;br /&gt; movl $TSS1_SEL, %edi &lt;br /&gt; call set_base&lt;br /&gt; lea ldt1, %eax&lt;br /&gt; movl $LDT1_SEL, %edi&lt;br /&gt; call set_base&lt;br /&gt;&lt;br /&gt; call setup_idt&lt;br /&gt; call setup_gdt&lt;br /&gt; movl $0x10,%eax  # reload all the segment registers&lt;br /&gt; mov %ax,%ds  # after changing gdt. &lt;br /&gt; mov %ax,%es&lt;br /&gt; mov %ax,%fs&lt;br /&gt; mov %ax,%gs&lt;br /&gt; lss stack_ptr,%esp&lt;br /&gt;&lt;br /&gt;# setup up timer 8253 chip.&lt;br /&gt; movb $0x36, %al&lt;br /&gt; movl $0x43, %edx&lt;br /&gt; outb %al, %dx&lt;br /&gt; movl $11930, %eax        # timer frequency 100 HZ &lt;br /&gt; movl $0x40, %edx&lt;br /&gt; outb %al, %dx&lt;br /&gt; movb %ah, %al&lt;br /&gt; outb %al, %dx&lt;br /&gt;&lt;br /&gt;# setup timer &amp;amp; system call interrupt descriptors.&lt;br /&gt; movl $0x00080000, %eax &lt;br /&gt; movw $timer_interrupt, %ax&lt;br /&gt; movw $0x8E00, %dx&lt;br /&gt; movl $0x08, %ecx&lt;br /&gt; lea idt(,%ecx,8), %esi&lt;br /&gt; movl %eax,(%esi) &lt;br /&gt; movl %edx,4(%esi)&lt;br /&gt; movw $system_interrupt, %ax&lt;br /&gt; movw $0xef00, %dx&lt;br /&gt; movl $0x80, %ecx&lt;br /&gt; lea idt(,%ecx,8), %esi&lt;br /&gt; movl %eax,(%esi) &lt;br /&gt; movl %edx,4(%esi)&lt;br /&gt;&lt;br /&gt;# unmask the timer interrupt.&lt;br /&gt; movl $0x21, %edx&lt;br /&gt; inb %dx, %al&lt;br /&gt; andb $0xfe, %al&lt;br /&gt; outb %al, %dx&lt;br /&gt;&lt;br /&gt;# Move to user mode (task 0)&lt;br /&gt; pushfl&lt;br /&gt; andl $0xffffbfff, (%esp)&lt;br /&gt; popfl&lt;br /&gt; movl $TSS0_SEL, %eax&lt;br /&gt; ltr %ax&lt;br /&gt; movl $LDT0_SEL, %eax&lt;br /&gt; lldt %ax &lt;br /&gt; movl $0, current&lt;br /&gt; sti&lt;br /&gt;//這邊不是很好理解，而且可能發生一種情形。比方說，sti打開interrupt以後。有可能&lt;br /&gt;//馬上就會有interrupt進來，因為已經填了tr和ldt，所以當interrupt進來後，會把&lt;br /&gt;//所有的register存到tss segment descriptor。但要記得，現在的stack是kernel&lt;br /&gt;//mode的，所以ss &amp; sp會被存到tss裡面。所以即使現在stack裡沒有ss sp flag cs &lt;br /&gt;//ip。到時候在timer interrupt被ljmp $TSS0_SEL, $0回來的時候，還是會從下面&lt;br /&gt;//這邊的push開始run，之後還是會把user mode的堆疊啊，flag啊，cs ip給push進去&lt;br /&gt; pushl $0x17&lt;br /&gt; pushl $stack0_ptr&lt;br /&gt; pushfl&lt;br /&gt; pushl $0x0f&lt;br /&gt; pushl $task0&lt;br /&gt;// debug char 'h'&lt;br /&gt; mov $0x0018, %ax&lt;br /&gt; mov %ax, %gs &lt;br /&gt; mov $0x0768, %ax&lt;br /&gt; xor %edi, %edi&lt;br /&gt; mov %ax, %gs:(%edi)&lt;br /&gt; iret&lt;br /&gt;&lt;br /&gt;/****************************************/&lt;br /&gt;setup_gdt:&lt;br /&gt; lgdt lgdt_opcode&lt;br /&gt; ret&lt;br /&gt;&lt;br /&gt;setup_idt:&lt;br /&gt; lea ignore_int,%edx&lt;br /&gt; movl $0x00080000,%eax&lt;br /&gt; movw %dx,%ax  /* selector = 0x0008 = cs */&lt;br /&gt; movw $0x8E00,%dx /* interrupt gate - dpl=0, present */&lt;br /&gt; lea idt,%edi&lt;br /&gt; mov $256,%ecx&lt;br /&gt;rp_sidt:&lt;br /&gt; movl %eax,(%edi)&lt;br /&gt; movl %edx,4(%edi)&lt;br /&gt; addl $8,%edi&lt;br /&gt; dec %ecx&lt;br /&gt; jne rp_sidt&lt;br /&gt; lidt lidt_opcode&lt;br /&gt; ret&lt;br /&gt;&lt;br /&gt;# in: %eax - logic addr; %ebx = base addr ; &lt;br /&gt;# %ecx - table addr; %edi - descriptors offset.&lt;br /&gt;set_base:&lt;br /&gt; addl %ebx, %eax&lt;br /&gt; addl %ecx, %edi&lt;br /&gt; movw %ax, 2(%edi)&lt;br /&gt; rorl $16, %eax&lt;br /&gt; movb %al, 4(%edi)&lt;br /&gt; movb %ah, 7(%edi)&lt;br /&gt; rorl $16, %eax&lt;br /&gt; ret&lt;br /&gt;&lt;br /&gt;write_char:&lt;br /&gt; push %gs&lt;br /&gt; pushl %ebx&lt;br /&gt; pushl %eax&lt;br /&gt; mov $0x18, %ebx&lt;br /&gt; mov %bx, %gs&lt;br /&gt; movl scr_loc, %ebx&lt;br /&gt; shl $1, %ebx&lt;br /&gt; movb %al, %gs:(%ebx)&lt;br /&gt; shr $1, %ebx&lt;br /&gt; incl %ebx&lt;br /&gt; cmpl $2000, %ebx&lt;br /&gt; jb 1f&lt;br /&gt; movl $0, %ebx&lt;br /&gt;1: movl %ebx, scr_loc &lt;br /&gt; popl %eax&lt;br /&gt; popl %ebx&lt;br /&gt; pop %gs&lt;br /&gt; ret&lt;br /&gt;&lt;br /&gt;/***********************************************/&lt;br /&gt;/* This is the default interrupt &amp;quot;handler&amp;quot; :-) */&lt;br /&gt;.align 2&lt;br /&gt;ignore_int:&lt;br /&gt; push %ds&lt;br /&gt; pushl %eax&lt;br /&gt; movl $0x10, %eax&lt;br /&gt; mov %ax, %ds&lt;br /&gt; movb $0x20, %al&lt;br /&gt; outb %al, $0x20&lt;br /&gt; movl $67, %eax            /* print 'C' */&lt;br /&gt; call write_char&lt;br /&gt; popl %eax&lt;br /&gt; pop %ds&lt;br /&gt; iret&lt;br /&gt;&lt;br /&gt;/* Timer interrupt handler */ &lt;br /&gt;.align 2&lt;br /&gt;timer_interrupt:&lt;br /&gt; push %ds&lt;br /&gt; pushl %edx&lt;br /&gt; pushl %ecx&lt;br /&gt; pushl %ebx&lt;br /&gt; pushl %eax&lt;br /&gt; movl $0x10, %eax&lt;br /&gt; mov %ax, %ds&lt;br /&gt; movb $0x20, %al&lt;br /&gt; outb %al, $0x20&lt;br /&gt; movl $1, %eax&lt;br /&gt; cmpl %eax, current&lt;br /&gt; je 1f&lt;br /&gt; movl %eax, current&lt;br /&gt; ljmp $TSS1_SEL, $0&lt;br /&gt; jmp 2f&lt;br /&gt;1: movl $0, current&lt;br /&gt; ljmp $TSS0_SEL, $0&lt;br /&gt;2: popl %eax&lt;br /&gt; popl %ebx&lt;br /&gt; popl %ecx&lt;br /&gt; popl %edx&lt;br /&gt; pop %ds&lt;br /&gt; iret&lt;br /&gt;//注意上面這邊的ljmp是真的會jmp過去另外一個task。假設被timer中斷的是task1，重點&lt;br /&gt;//在於當ljmp執行當下，要記得的被儲存的ss,sp是kernel的且cs ip是指向ljmp的下一行&lt;br /&gt;//以task1來說是"2: popl %eax"。所以可以當作被儲存的是task1被中斷在kernel &lt;br /&gt;//mode的狀態，整個被搬到TSS segment descriptor，之後回來就是"2: popl %eax"&lt;br /&gt;/* system call handler */&lt;br /&gt;.align 2&lt;br /&gt;system_interrupt:&lt;br /&gt; push %ds&lt;br /&gt; pushl %edx&lt;br /&gt; pushl %ecx&lt;br /&gt; pushl %ebx&lt;br /&gt; pushl %eax&lt;br /&gt; movl $0x10, %edx&lt;br /&gt; mov %dx, %ds&lt;br /&gt; call write_char&lt;br /&gt; popl %eax&lt;br /&gt; popl %ebx&lt;br /&gt; popl %ecx&lt;br /&gt; popl %edx&lt;br /&gt; pop %ds&lt;br /&gt; iret&lt;br /&gt;&lt;br /&gt;/*********************************************/&lt;br /&gt;current:.long 0&lt;br /&gt;scr_loc:.long 0&lt;br /&gt;&lt;br /&gt;.align 2&lt;br /&gt;.word 0&lt;br /&gt;lidt_opcode:&lt;br /&gt; .word 256*8-1  # idt contains 256 entries&lt;br /&gt; .long idt + KRN_BASE # This will be rewrite by code. &lt;br /&gt;.align 2&lt;br /&gt;.word 0&lt;br /&gt;lgdt_opcode:&lt;br /&gt; .word (end_gdt-gdt)-1 # so does gdt &lt;br /&gt; .long gdt + KRN_BASE # This will be rewrite by code.&lt;br /&gt;&lt;br /&gt; .align 2&lt;br /&gt;idt: .fill 256,8,0  # idt is uninitialized&lt;br /&gt;&lt;br /&gt;gdt: .quad 0x0000000000000000 /* NULL descriptor */&lt;br /&gt; .quad 0x00c09a00000007ff /* 8Mb 0x08, base = 0x0000 */&lt;br /&gt; .quad 0x00c09200000007ff /* 8Mb 0x10 */&lt;br /&gt; .quad 0x00c0920b80000002 /* screen 0x18 - for display */&lt;br /&gt;&lt;br /&gt; .quad 0x0000e90000000068 # TSS0 descr 0x20&lt;br /&gt; .quad 0x0000e20000000040 # LDT0 descr 0x28&lt;br /&gt; .quad 0x0000e90000000068 # TSS1 descr 0x30&lt;br /&gt; .quad 0x0000e20000000040 # LDT1 descr 0x38&lt;br /&gt;end_gdt:&lt;br /&gt; .fill 128,4,0&lt;br /&gt;stack_ptr:&lt;br /&gt; .long stack_ptr&lt;br /&gt; .word 0x10&lt;br /&gt;&lt;br /&gt;/*************************************/&lt;br /&gt;.align 2&lt;br /&gt;ldt0: .quad 0x0000000000000000&lt;br /&gt; .quad 0x00c0fa00000003ff # 0x0f, base = 0x10000&lt;br /&gt; .quad 0x00c0f200000003ff # 0x17&lt;br /&gt;tss0:&lt;br /&gt; .long 0    /* back link */&lt;br /&gt; .long stack0_krn_ptr, 0x10 /* esp0, ss0 */&lt;br /&gt; .long 0, 0   /* esp1, ss1 */&lt;br /&gt; .long 0, 0   /* esp2, ss2 */&lt;br /&gt; .long 0    /* cr3 */&lt;br /&gt; .long task0   /* eip */&lt;br /&gt; .long 0x200   /* eflags */&lt;br /&gt; .long 0, 0, 0, 0  /* eax, ecx, edx, ebx */&lt;br /&gt; .long stack0_ptr, 0, 0, 0 /* esp, ebp, esi, edi */&lt;br /&gt; .long 0x17,0x0f,0x17,0x17,0x17,0x17 /* es, cs, ss, ds, fs, gs */&lt;br /&gt; .long LDT0_SEL   /* ldt */&lt;br /&gt; .long 0x8000000   /* trace bitmap */&lt;br /&gt;&lt;br /&gt; .fill 128,4,0&lt;br /&gt;stack0_krn_ptr:&lt;br /&gt; .long 0&lt;br /&gt;&lt;br /&gt;/************************************/&lt;br /&gt;.align 2&lt;br /&gt;ldt1: .quad 0x0000000000000000&lt;br /&gt; .quad 0x00c0fa00000003ff # 0x0f, base = 0x10000&lt;br /&gt; .quad 0x00c0f200000003ff # 0x17&lt;br /&gt;tss1:&lt;br /&gt; .long 0    /* back link */&lt;br /&gt; .long stack1_krn_ptr, 0x10 /* esp0, ss0 */&lt;br /&gt; .long 0, 0   /* esp1, ss1 */&lt;br /&gt; .long 0, 0   /* esp2, ss2 */&lt;br /&gt; .long 0    /* cr3 */&lt;br /&gt; .long task1   /* eip */&lt;br /&gt; .long 0x200   /* eflags */&lt;br /&gt; .long 0, 0, 0, 0  /* eax, ecx, edx, ebx */&lt;br /&gt; .long stack1_ptr, 0, 0, 0 /* esp, ebp, esi, edi */&lt;br /&gt; .long 0x17,0x0f,0x17,0x17,0x17,0x17 /* es, cs, ss, ds, fs, gs */&lt;br /&gt; .long LDT1_SEL   /* ldt */&lt;br /&gt; .long 0x8000000   /* trace bitmap */&lt;br /&gt;&lt;br /&gt; .fill 128,4,0&lt;br /&gt;stack1_krn_ptr:&lt;br /&gt; .long 0&lt;br /&gt;&lt;br /&gt;/************************************/&lt;br /&gt;task0:&lt;br /&gt; movl $0x17, %eax          /*這邊之所以要換掉ds是因為之後的stack0_ptr*/&lt;br /&gt; movw %ax, %ds             /*相對位置是用ldt裡面的第二個entry，所存的*/&lt;br /&gt;                           /*base address為基準*/&lt;br /&gt; mov $65, %al              /*65就是0x41所以 print 'A' */&lt;br /&gt; int $0x80&lt;br /&gt; movl $0x08ffffff, %ecx&lt;br /&gt;//因為task0的ecx的loop值大概只有task1的一半，所以&lt;br /&gt;//印出A的數量大概會是B的兩倍&lt;br /&gt;1: loop 1b&lt;br /&gt; jmp task0 &lt;br /&gt;&lt;br /&gt; .fill 128,4,0&lt;br /&gt;stack0_ptr:&lt;br /&gt;//stack0的userspace stack所在位置。&lt;br /&gt; .long 0&lt;br /&gt;&lt;br /&gt;task1:&lt;br /&gt; movl $0x17, %eax&lt;br /&gt; movw %ax, %ds&lt;br /&gt; mov $66, %al              /* 0x42所以print 'B' */&lt;br /&gt; int $0x80&lt;br /&gt; movl $0x0fffffff, %ecx&lt;br /&gt;1: loop 1b&lt;br /&gt; jmp task1&lt;br /&gt;&lt;br /&gt; .fill 128,4,0 &lt;br /&gt;stack1_ptr:&lt;br /&gt;//上面是task1的user space stack所在的位置。&lt;br /&gt; .long 0&lt;br /&gt;&lt;br /&gt;/*** end ***/&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;可以看出主要的組成就是上面這五隻檔案:&lt;br /&gt;Makefile, gavin_x86_boot.ld, gavin_x86_dos.ld, boot.S, head.S&lt;br /&gt;&lt;br /&gt;剛開始做實驗的時候會覺得很奇怪，為什麼按下鍵盤只會出現一個C(也就是ignore_int)，&lt;br /&gt;&lt;br /&gt;後來發現因為keyboard interrupt要回去重新清除flag。下完io以後才能再繼續收到interrupt。&lt;br /&gt;&lt;br /&gt;在這個實驗的過程，可以多多利用objdump xxx.elf(xxx.o) -d -M addr(16)32,data(16)32。如果已經&lt;br /&gt;&lt;br /&gt;build成binary可以用hexedit。若是不知道如何使用=&gt;man hexedit。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-527476968391571966?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/527476968391571966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=527476968391571966' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/527476968391571966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/527476968391571966'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/10/timer-interruptprocesscontext-switchab.html' title='利用timer interrupt讓兩個Process做context switch一個印出A一個印出B'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_r6LKRJP8V4w/St7Qk92NkoI/AAAAAAAAASE/qhy3_eywoCI/s72-c/bootimg.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-2519070126980141117</id><published>2009-10-05T20:23:00.000-07:00</published><updated>2009-10-06T00:22:36.041-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>JSP JFreeChart 圖表使用</title><content type='html'>最近剛好有朋友找我幫忙敎她們如何使用JFreeChart，在這邊做個紀錄。&lt;br /&gt;&lt;br /&gt;第一個步驟：&lt;br /&gt;&lt;br /&gt;先到http://sourceforge.net/projects/jfreechart/files/下載Platform為Windows的&lt;br /&gt;&lt;a class="dload { url: 'http://downloads.sourceforge.net/project/jfreechart/1.%20JFreeChart/1.0.13/jfreechart-1.0.13.zip' }" href="http://sourceforge.net/projects/jfreechart/files/1.%20JFreeChart/1.0.13/jfreechart-1.0.13.zip/download" title="/1. JFreeChart/1.0.13/jfreechart-1.0.13.zip:  released on Apr 20 2009"&gt;jfreechart-1.0.13.zip&lt;/a&gt;檔。&lt;br /&gt;&lt;br /&gt;把它解壓縮開來後，到jfreechart-1.0.13\lib底下把jfreechart-1.0.13.jar &amp;amp; jcommon-1.0.16.jar這兩隻檔案放到webapps\ROOT\WEB_INF\lib裡面。(如果WEB_INF底下沒有lib資料夾，就自己建一個，webapps下面每個資料夾都可以有自己的WEB_INF資料夾，WEB_INF下面可以有web.xml, classes, lib。這三個都是可有可無的。web.xml如果不存在，Tomcat會以預設的暫代。classes用來放servlet的class file。lib放會用到的jar檔，當web application執行時servlet container會自動將底下的所有JAR/zip加到系統classpath變數中，所以放在這底下的JAR不用設定classpath)&lt;br /&gt;&lt;br /&gt;第二個步驟：&lt;br /&gt;&lt;br /&gt;找到webapps\ROOT\WEB_INF\web.xml。&lt;br /&gt;把它修改成這樣如下。&lt;br /&gt;&lt;pre class="prettyprint lang-xhtml"&gt;&lt;br /&gt;&amp;lt;web-app xmlns="http://java.sun.com/xml/ns/javaee"&lt;br /&gt;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt;xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&lt;br /&gt;version="2.5"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;display-name&amp;gt;Welcome to Tomcat&amp;lt;/display-name&amp;gt;&lt;br /&gt;&amp;lt;description&amp;gt;&lt;br /&gt;Welcome to Tomcat&lt;br /&gt;&amp;lt;/description&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;servlet&amp;gt;&lt;br /&gt;&amp;lt;servlet-name&amp;gt;DisplayChart&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;&amp;lt;servlet-class&amp;gt;org.jfree.chart.servlet.DisplayChart&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;&amp;lt;/servlet&amp;gt;&lt;br /&gt;&amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;&amp;lt;servlet-name&amp;gt;DisplayChart&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;&amp;lt;url-pattern&amp;gt;/servlet/DisplayChart&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;&amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/web-app&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;眼尖的人可以發現，其實就加了這段而已：&lt;br /&gt;&lt;pre class="prettyprint lang-xhtml"&gt;&lt;br /&gt;&amp;lt;servlet&amp;gt;&lt;br /&gt;&amp;lt;servlet-name&amp;gt;DisplayChart&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;&amp;lt;servlet-class&amp;gt;org.jfree.chart.servlet.DisplayChart&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;&amp;lt;/servlet&amp;gt;&lt;br /&gt;&amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;&amp;lt;servlet-name&amp;gt;DisplayChart&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;&amp;lt;url-pattern&amp;gt;/servlet/DisplayChart&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;&amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;重起Tomcat，並且把下面這段jspline3d.jsp擺到webapps\ROOT底下&lt;br /&gt;&lt;pre class="prettyprint lang-js"&gt;&lt;br /&gt;&amp;lt;%@page contentType="text/html" pageEncoding="UTF-8"%&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&lt;br /&gt;"http://www.w3.org/TR/html4/loose.dtd"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;%@ page  import ="org.jfree.data.category.*"%&amp;gt;&lt;br /&gt;&amp;lt;%@ page  import="java.awt.*" %&amp;gt;&lt;br /&gt;&amp;lt;%@ page  import="java.io.*" %&amp;gt;&lt;br /&gt;&amp;lt;%@ page  import="org.jfree.chart.*" %&amp;gt;&lt;br /&gt;&amp;lt;%@ page  import="org.jfree.chart.servlet.ServletUtilities" %&amp;gt;&lt;br /&gt;&amp;lt;%@ page  import="org.jfree.chart.entity.*" %&amp;gt;&lt;br /&gt;&amp;lt;%@ page  import ="org.jfree.data.general.*"%&amp;gt;&lt;br /&gt;&amp;lt;%@ page  import ="org.jfree.chart.JFreeChart"%&amp;gt;&lt;br /&gt;&amp;lt;%@ page  import ="org.jfree.chart.plot.PlotOrientation" %&amp;gt;&lt;br /&gt;&amp;lt;%&lt;br /&gt;      DefaultCategoryDataset data = new DefaultCategoryDataset();&lt;br /&gt;String[] series = {"USA", "China", "Taiwan"};&lt;br /&gt;String[] category = {"2005", "2006", "2007", "2008"};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;data.addValue(300, series[0], category[0]);&lt;br /&gt;data.addValue(500, series[0], category[1]);&lt;br /&gt;data.addValue(400, series[0], category[2]);&lt;br /&gt;data.addValue(400, series[0], category[3]);&lt;br /&gt;data.addValue(200, series[1], category[0]);&lt;br /&gt;data.addValue(600, series[1], category[1]);&lt;br /&gt;data.addValue(200, series[1], category[2]);&lt;br /&gt;data.addValue(200, series[1], category[3]);&lt;br /&gt;data.addValue(100, series[2], category[0]);&lt;br /&gt;data.addValue(150, series[2], category[1]);&lt;br /&gt;data.addValue(700, series[2], category[2]);&lt;br /&gt;data.addValue(700, series[2], category[3]);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;JFreeChart chart =&lt;br /&gt;ChartFactory.createLineChart3D("Input",&lt;br /&gt;                               "Annual",&lt;br /&gt;                               "value",&lt;br /&gt;                               data,&lt;br /&gt;                               PlotOrientation.VERTICAL,&lt;br /&gt;                               true,&lt;br /&gt;                               true,&lt;br /&gt;                               false);&lt;br /&gt;&lt;br /&gt;          final ChartRenderingInfo info = new&lt;br /&gt;        ChartRenderingInfo(new StandardEntityCollection());&lt;br /&gt;&lt;br /&gt;          String fname = ServletUtilities.saveChartAsJPEG(chart, 600, 400, info, session);&lt;br /&gt;PrintWriter pw = new PrintWriter(out);&lt;br /&gt;ChartUtilities.writeImageMap(pw, fname, info, false);&lt;br /&gt;pw.flush();&lt;br /&gt;String chartURL = request.getContextPath() + "/servlet/DisplayChart?filename=" + fname;&lt;br /&gt;%&amp;gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;  &amp;lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&amp;gt;&lt;br /&gt;  &amp;lt;title&amp;gt;JSP Page&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;IMG SRC="&amp;lt;%= chartURL %&amp;gt;" WIDTH="600" HEIGHT="400"&lt;br /&gt;BORDER="0" USEMAP="#&amp;lt;%= fname %&amp;gt;"&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;在瀏覽器輸入http://localhost:8080/jspline3d.jsp&lt;br /&gt;就可以看到下面這個圖片：&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_r6LKRJP8V4w/Ssq_JXCOYUI/AAAAAAAAAQU/63RGM98x8vw/s1600-h/line3d.JPG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 262px;" src="http://4.bp.blogspot.com/_r6LKRJP8V4w/Ssq_JXCOYUI/AAAAAAAAAQU/63RGM98x8vw/s400/line3d.JPG" alt="" id="BLOGGER_PHOTO_ID_5389330071625294146" border="0" /&gt;&lt;/a&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;br /&gt;&lt;br /&gt;餅狀圖的jsppiechart.jsp code如下：&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyclass lang-js"&gt;&lt;br /&gt;&amp;lt;%@page contentType="text/html" pageEncoding="UTF-8"%&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&lt;br /&gt;"http://www.w3.org/TR/html4/loose.dtd"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;%@ page  import="java.awt.*" %&amp;gt;&lt;br /&gt;&amp;lt;%@ page  import="java.io.*" %&amp;gt;&lt;br /&gt;&amp;lt;%@ page  import="org.jfree.chart.*" %&amp;gt;&lt;br /&gt;&amp;lt;%@ page  import="org.jfree.chart.servlet.ServletUtilities" %&amp;gt;&lt;br /&gt;&amp;lt;%@ page  import="org.jfree.chart.entity.*" %&amp;gt;&lt;br /&gt;&amp;lt;%@ page  import ="org.jfree.data.general.*"%&amp;gt;&lt;br /&gt;&amp;lt;%&lt;br /&gt;      final DefaultPieDataset data = new DefaultPieDataset();&lt;br /&gt;      data.setValue("First", new Double(43.2));&lt;br /&gt;      data.setValue("Two", new Double(10.0));&lt;br /&gt;      data.setValue("Three", new Double(27.5));&lt;br /&gt;      data.setValue("Four", new Double(17.5));&lt;br /&gt;      data.setValue("Five", new Double(11.0));&lt;br /&gt;      data.setValue("Six", new Double(19.4));&lt;br /&gt;&lt;br /&gt;      JFreeChart chart = ChartFactory.createPieChart&lt;br /&gt;      ("Pie Chart ", data, true, true, false);&lt;br /&gt;&lt;br /&gt;          final ChartRenderingInfo info = new&lt;br /&gt;        ChartRenderingInfo(new StandardEntityCollection());&lt;br /&gt;&lt;br /&gt;          String fname = ServletUtilities.saveChartAsJPEG(chart, 600, 400, info, session);&lt;br /&gt;PrintWriter pw = new PrintWriter(out);&lt;br /&gt;ChartUtilities.writeImageMap(pw, fname, info, false);&lt;br /&gt;pw.flush();&lt;br /&gt;String chartURL = request.getContextPath() + "/servlet/DisplayChart?filename=" + fname;&lt;br /&gt;%&amp;gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;  &amp;lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&amp;gt;&lt;br /&gt;  &amp;lt;title&amp;gt;JSP Page&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;IMG SRC="&amp;lt;%= chartURL %&amp;gt;" WIDTH="600" HEIGHT="400"&lt;br /&gt;BORDER="0" USEMAP="#&amp;lt;%= fname %&amp;gt;"&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;在瀏覽器端輸入http://localhost:8080/jsppiechart.jsp&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_r6LKRJP8V4w/SsrA_vnA18I/AAAAAAAAAQc/6XFGAZumdVQ/s1600-h/piechart.JPG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 275px;" src="http://3.bp.blogspot.com/_r6LKRJP8V4w/SsrA_vnA18I/AAAAAAAAAQc/6XFGAZumdVQ/s400/piechart.JPG" alt="" id="BLOGGER_PHOTO_ID_5389332105446610882" border="0" /&gt;&lt;/a&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;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;參考：&lt;br /&gt;&lt;a href="http://www.roseindia.net/tutorialsearch/?t=jsp%20%20%20jfreechart"&gt;這個有一堆範例還有source code&lt;/a&gt;&lt;br /&gt;&lt;a href="http://web.caidiy.com/plate/web/papermsg.jsp?UI=jerrywei&amp;amp;PI=4276"&gt;&lt;span class="titlename"&gt;JFreeChart(JSP)學生學習評量曲線圖範例&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.csie.ntnu.edu.tw/%7Eswanky/jfreechart/BarChart.htm"&gt;Hello Bar Chart Tutorial&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.lslnet.com/linux/dosc1/53/linux-358788.htm"&gt;&lt;b&gt;使用JFreechart制作图表的过程详解&lt;/b&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-2519070126980141117?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/2519070126980141117/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=2519070126980141117' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/2519070126980141117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/2519070126980141117'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/10/jsp-jfreechart.html' title='JSP JFreeChart 圖表使用'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_r6LKRJP8V4w/Ssq_JXCOYUI/AAAAAAAAAQU/63RGM98x8vw/s72-c/line3d.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-1418744039719817369</id><published>2009-09-14T20:23:00.000-07:00</published><updated>2009-09-14T20:52:08.862-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='健力運動'/><title type='text'>我追求的夢想</title><content type='html'>從接觸這個運動以來，我對力量深深著迷。&lt;br /&gt;&lt;br /&gt;看著自己的力量不斷的進步，好像擁有一種魔力，從前舉不起來的重量，&lt;br /&gt;&lt;br /&gt;現在對我來說輕而一舉，這就是力量帶給我的誘惑。&lt;br /&gt;&lt;br /&gt;力量和健美在訓練上所帶來的痛苦是不同的。&lt;br /&gt;&lt;br /&gt;力量比較偏向於冒險犯難的精神，假設你的蹲舉1RM是在210kg，今天蹲舉架前面擺上這個重量，&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;br /&gt;慢慢的，知道我要力量，練法也朝向力量的方面轉變。健美訓練方式，漸漸的從我的訓練裡消失。&lt;br /&gt;&lt;br /&gt;我知道，不使用藥物，像平凡如我這樣的條件，訓練也沒有走在世界的尖端，&lt;br /&gt;&lt;br /&gt;不可能達到怪物般的等級。&lt;br /&gt;&lt;br /&gt;但心裡還是給自己設下一個目標，希望至少體重85kg可以空蹲250kg，只綁腰帶。&lt;br /&gt;&lt;br /&gt;臥推可以170kg停頓。&lt;br /&gt;&lt;br /&gt;硬舉可以280kg。&lt;br /&gt;&lt;br /&gt;total = 700kg。&lt;br /&gt;&lt;br /&gt;這是我的夢想。&lt;br /&gt;&lt;br /&gt;雖然，和世界上的高手有不短的距離。但在這項運動上面，算是我對自己的一個交代。&lt;br /&gt;&lt;br /&gt;希望在30歲以前可以達到這樣的水平。&lt;br /&gt;&lt;br /&gt;這樣我的人生又少了一項遺憾。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-1418744039719817369?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/1418744039719817369/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=1418744039719817369' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/1418744039719817369'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/1418744039719817369'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/09/blog-post.html' title='我追求的夢想'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-2401417083428373664</id><published>2009-09-14T19:28:00.000-07:00</published><updated>2009-09-14T22:42:17.602-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><title type='text'>在Windows下面使用vim+ctags+trinity</title><content type='html'>因為vim非常的好用，導致我在windows上面trace也想要用vim。&lt;br /&gt;但是之前一直沒有好好search該怎麼在windows上面用ctags &amp;amp; trinity。&lt;br /&gt;&lt;br /&gt;剛剛做了一下search:&lt;br /&gt;&lt;br /&gt;先到&lt;a href="http://ctags.sourceforge.net/"&gt;http://ctags.sourceforge.net/&lt;/a&gt;下載&lt;br /&gt;&lt;br /&gt;Source and binary for Windows 98/NT/2000/XP，&lt;a href="http://prdownloads.sourceforge.net/ctags/ctags58.zip"&gt;ctags58.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;解開以後裡面有source code，還有一隻ctags.exe。&lt;br /&gt;&lt;br /&gt;把這支ctags.exe放到C:\Windows\system32，這樣就可以不用設PATH。&lt;br /&gt;&lt;br /&gt;之後就可以在開始-&gt;執行-&gt;cmd，你想要建立tags的source code資料夾底下直接用"ctags -R"。&lt;br /&gt;&lt;br /&gt;windows vim的vimrc放在C:\Program Files\Vim\_vimrc。&lt;br /&gt;&lt;br /&gt;之後使用trinity就可以把設定寫在上面的路徑。&lt;br /&gt;&lt;br /&gt;相對應的xxx.vim該放在C:\Program Files\Vim\vim72\plugin。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;參考鍵結:&lt;a href="http://hi.baidu.com/zengzhaonong/blog/item/67c4b2344a4132b0d1a2d32f.html"&gt;gvim+ctags in windows&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-2401417083428373664?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/2401417083428373664/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=2401417083428373664' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/2401417083428373664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/2401417083428373664'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/09/windowsvimctagstrinity.html' title='在Windows下面使用vim+ctags+trinity'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-8332203418466761303</id><published>2009-08-16T05:41:00.000-07:00</published><updated>2009-08-16T17:31:04.449-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='健力運動'/><title type='text'>今天2009/8/16的健力比賽</title><content type='html'>一早來到安樂路431號這個在兩年前我曾經來比單項臥推的地方。&lt;br /&gt;&lt;br /&gt;一切場景是多麼的令人熟悉，只不過人事已非，現在的隊友不是昔日台南健力協會。&lt;br /&gt;&lt;br /&gt;回台北後，想要積極找人訓練，藉由rock介紹。我認識了佳佑。&lt;br /&gt;&lt;br /&gt;雖然吃素，但擁有非常好的天份，我把自己的經驗傳授給他。讓他少走了很多的冤枉路。&lt;br /&gt;&lt;br /&gt;從2007年九月多到現在練了將近兩年，今天體重106kg。&lt;br /&gt;&lt;br /&gt;蹲舉230   臥推170   硬舉275 空身總合675。 預估上裝備可以多個100，國內應該有一定的水準。&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;今天書豪的成績  蹲180  臥115  硬210。&lt;br /&gt;&lt;br /&gt;文進是在台北健身房認識的朋友，也是非常的隨合，據說從前是個拳擊手。&lt;br /&gt;&lt;br /&gt;上半身非常的強壯。在一兩個月前，我找他一起拼三項，他練力量沒多久。&lt;br /&gt;&lt;br /&gt;今天他的成績蹲170 180有起來，但不知道為什麼被判失敗。  臥155   硬190&lt;br /&gt;&lt;br /&gt;草哥已經快要五十歲了，他自己也說了，剛認識我的時候他130都拉不起來。&lt;br /&gt;&lt;br /&gt;草哥是一個很愛好力量的人。非常的有潛力。也有老大哥的風範。&lt;br /&gt;&lt;br /&gt;由於昨天沒有提醒他今天九點才到，讓他七點半就在那邊等了。我做領隊沒做好照顧大家的工作，&lt;br /&gt;&lt;br /&gt;真是很不好意思。&lt;br /&gt;&lt;br /&gt;今天他蹲145   臥120   硬160  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;最後，我自己今天蹲舉180，很輕，感覺拿來做七八下沒問題，&lt;br /&gt;&lt;br /&gt;因為肩膀之前脫臼的關係還沒有好，不敢蹲太重，以免受傷。&lt;br /&gt;&lt;br /&gt;臥推140，有點沉，其實和現在的實力也差不多，這兩年都沒好好練臥推，應該沒什好說。&lt;br /&gt;&lt;br /&gt;硬舉250，260拉了兩次都拉不到位，小腿一直抽筋，令我比較失望。&lt;br /&gt;&lt;br /&gt;最後我們得到了團體的亞軍，Westside Barbell in Taiwan的各位，辛苦大家了，明年我們再來洗恥。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-8332203418466761303?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/8332203418466761303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=8332203418466761303' title='233 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/8332203418466761303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/8332203418466761303'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/08/2009816.html' title='今天2009/8/16的健力比賽'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>233</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-5650340502758536538</id><published>2009-08-16T04:54:00.000-07:00</published><updated>2009-08-16T17:36:29.944-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='生活'/><title type='text'>關於這次8/8的Morako颱風</title><content type='html'>看到這次颱風帶來慘烈的災害，家破人亡，讓人感到非常的難過。&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;"Should Taiwan not hoping more prepared for this weather's coming??"&lt;br /&gt;馬英九總統：&lt;br /&gt;"No,this area, this is the first time in many years"&lt;br /&gt;"this is why,&lt;span style="color: rgb(255, 0, 0);"&gt; they&lt;/span&gt; are, &lt;span style="color: rgb(255, 0, 0);"&gt;they&lt;/span&gt; were not fully prepared."&lt;br /&gt;"if &lt;span style="color: rgb(255, 0, 0);"&gt;they&lt;/span&gt; were, &lt;span style="color: rgb(255, 0, 0);"&gt;they&lt;/span&gt; should have been evacuated much earlier."&lt;br /&gt;"Just because &lt;span style="color: rgb(255, 0, 0);"&gt;they&lt;/span&gt; stayed in where &lt;span style="color: rgb(255, 0, 0);"&gt;they&lt;/span&gt; lived."&lt;br /&gt;"but You see, &lt;span style="color: rgb(255, 0, 0);"&gt;they&lt;/span&gt; didn't, &lt;span style="color: rgb(255, 0, 0);"&gt;they&lt;/span&gt; didn't realize how serious the disaster was."&lt;br /&gt;&lt;br /&gt;我實在是很不想要，而且很討厭提到政治。&lt;br /&gt;&lt;br /&gt;但，我只想說"馬英九，你好樣的！"&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/R0hD61xpuFU&amp;amp;hl=zh_TW&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/R0hD61xpuFU&amp;amp;hl=zh_TW&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-5650340502758536538?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/5650340502758536538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=5650340502758536538' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/5650340502758536538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/5650340502758536538'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/08/88morako.html' title='關於這次8/8的Morako颱風'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-3210704763076113964</id><published>2009-07-31T02:19:00.000-07:00</published><updated>2009-07-31T02:51:39.009-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='健力運動'/><title type='text'>硬舉之神 Konstantin Konstantinovs</title><content type='html'>最近看到了一個硬舉神KK。&lt;br /&gt;&lt;br /&gt;他的raw deadlift 937lbs(不用腰帶喔！)&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/wh-ikyBAQr8&amp;hl=zh_TW&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/wh-ikyBAQr8&amp;hl=zh_TW&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;Andy Bolton也才935lbs他自己在bodybuilding.com下面那篇專訪說的。而且重點是KK才122kg。Andy Bolton生於1970, 1, 22。KK 1978年生的。&lt;br /&gt;看來不管是年紀還是體重，KK都大有贏面。&lt;br /&gt;&lt;br /&gt;看來KK不但是硬舉強，單槓也很強&lt;br /&gt;55 pull ups&lt;br&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/boLl8rGhJvE&amp;hl=zh_TW&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/boLl8rGhJvE&amp;hl=zh_TW&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;60kg pull 4 reps&lt;br&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/Rvv7f8O62Sw&amp;hl=zh_TW&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/Rvv7f8O62Sw&amp;hl=zh_TW&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;250kg raw bench press , close grip(這還是人嗎?臥推也很強ㄟ)&lt;br&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/b9qca-qK6UE&amp;hl=zh_TW&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/b9qca-qK6UE&amp;hl=zh_TW&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;330kg Squat raw(還好蹲舉只有330kg，人還是有弱點的。)&lt;br&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/M-c1KjqBObI&amp;hl=zh_TW&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/M-c1KjqBObI&amp;hl=zh_TW&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;br /&gt;bodybuilding.com有一篇&lt;a href="http://forum.bodybuilding.com/showthread.php?t=5190993"&gt;討論串&lt;/a&gt;提到他的專訪。內容如下：&lt;br /&gt;Background&lt;br /&gt;&lt;br /&gt;He was born in 1978 in the small town of Liepaya in Latvia. Parents were normal people with no background in sports.&lt;br /&gt;&lt;br /&gt;Started in sports at the age of six with gymnastics, and later spent a few years doing wrestling and judo. By 11 he was already quite strong and could do 42 chin-ups.&lt;br /&gt;&lt;br /&gt;At 15 he began lifting weights at the gym, initially doing bodybuilding training, but always lifted with the intention of getting stronger. Was already 6ft tall, 160lbs, and deadlifting 475.&lt;br /&gt;&lt;br /&gt;At 17 he started training as a powerlifter, getting most of his training and nutrition information from magazines.&lt;br /&gt;&lt;br /&gt;Started competing in 1997 and went on to set over 100 Latvian records. He is the national champion in all 3 power lifts and has the biggest total.&lt;br /&gt;&lt;br /&gt;In 2002 as a junior he lifted a total of 2210lbs, a world and European record at the time, and he also set a junior WR with a 860lb (360kg) deadlift.&lt;br /&gt;&lt;br /&gt;Later that year he recorded 2295lb total in Helsinki (WPC) setting a world and European record in the bench press with 596lbs.&lt;br /&gt;&lt;br /&gt;In 2003 in the world championships (GPC) in Austria he was the overall champion setting two world records in the deadlift: 884 followed by 897lbs.&lt;br /&gt;&lt;br /&gt;In 2004 won the GPC "World cup" in Slovakia in the 275 class.&lt;br /&gt;&lt;br /&gt;In 2005 he totaled 2317 in the IPF and went on to set a WR deadlifting 906 (411kg, no suit) in the 275 class, beating a record held since 1982 by 1kg.&lt;br /&gt;&lt;br /&gt;In 2006 he focused exclusively on the deadlift and at the Latvian nationals (WPC-IPF) pulled 948 @ 275 to break his 2005 WR by 19kg (this time in a Metal DL suit) after tokens in the squat and bench press.&lt;br /&gt;&lt;br /&gt;His main goal is to beat Andy Bolton's world record (which at the time of the interview was 971).&lt;br /&gt;&lt;br /&gt;Training&lt;br /&gt;&lt;br /&gt;He has recently given a lot more attention to rest and recovery which he believes is extremely important at his level so he trains more intuitively. He trains the deadlift 2x every 9-12 days, but it all depends on how he's feeling, so if he's feeling slightly fatigued he prefers to rest another day or two before deadlifting again.&lt;br /&gt;&lt;br /&gt;His main assistance exercise is pulling off 3-4" blocks (8-10cm).&lt;br /&gt;&lt;br /&gt;The overall volume of his deadlift training is very high, going up to 20 sets.&lt;br /&gt;&lt;br /&gt;He splits his deadlift workouts in half with 20-30 minutes rest between them. Rest times on work sets are typically 3-5 minutes.&lt;br /&gt;&lt;br /&gt;He trains without straps or a belt.&lt;br /&gt;&lt;br /&gt;From a recent training session:&lt;br /&gt;&lt;br /&gt;Deadlifts from the floor&lt;br /&gt;&lt;br /&gt;260 x 5&lt;br /&gt;350 x 5&lt;br /&gt;440 x 3&lt;br /&gt;530 x 1&lt;br /&gt;620 x 1&lt;br /&gt;705 x 1&lt;br /&gt;795 x 1&lt;br /&gt;860 x 4&lt;br /&gt;&lt;br /&gt;Rest 30 minutes&lt;br /&gt;&lt;br /&gt;Pulling off blocks&lt;br /&gt;&lt;br /&gt;375 x 5&lt;br /&gt;485 x 5&lt;br /&gt;660 x 1&lt;br /&gt;750 x 5&lt;br /&gt;815 x 5&lt;br /&gt;&lt;br /&gt;Hyperextensions on a 45 deg. bench with 60kg (132lbs) for 2 sets of 20 reps&lt;br /&gt;&lt;br /&gt;Reverse hyperextensions with 50-70kg (110-155lbs) for 2 sets of 15-20 reps&lt;br /&gt;&lt;br /&gt;Biceps: 2 x 20&lt;br /&gt;&lt;br /&gt;Presses: 6 x 15-25&lt;br /&gt;&lt;br /&gt;Speed work:&lt;br /&gt;&lt;br /&gt;5 x 5 Oly squats with knee wraps&lt;br /&gt;&lt;br /&gt;8-10 single speed pulls from the floor with bands that add 130kg of tension to the lockout. He increments his speed work by 5kg (11lbs) each workout. His last speed pull session involved 240kg for 10 singles with 130kg of band tension.&lt;br /&gt;&lt;br /&gt;Technique&lt;br /&gt;&lt;br /&gt;He explains that while he pulls with a rounded back, it is only his upper back (from the chest up) that is rounded and it stays this way throughout the entire lift. It allows him to lift the maximum amount of weight for his proportions. He said he deadlifted with a straight back and more leg drive years ago but it would not allow him to lift more than 340kg (750).&lt;br /&gt;&lt;br /&gt;The biggest influence on his deadlift training has been Ano Turtiainen of Finland, who has given him a lot of advice on his form.&lt;br /&gt;&lt;br /&gt;Early on he took his deadlift from 340kg (750) to 390kg (860) in 7 months without increasing his body weight with his technique and training based on US methods, and reached 407kg (895) at a body weight of 118kg. This is where progress stalled and he had to look at other methods.&lt;br /&gt;&lt;br /&gt;He now uses a combination of speed work and higher volume training with 75-90% of his max, assistance exercises, and "Westside" training methods. His current training methods have allowed him to take his deadlift to 430kg (948).&lt;br /&gt;&lt;br /&gt;At his last competition he did not know how much he could lift but having since analyzed his performance he believes it is not his limit. He wants to go to the United States in 2007 to break the world record.&lt;br /&gt;&lt;br /&gt;Training secrets&lt;br /&gt;&lt;br /&gt;He explains that intra-abdominal pressure is very important and a belt should be used sparingly. He only uses it lifting maximum weights. He doesn't feel a belt adds anything to his deadlift. He feels sumo lifters benefit more from a belt and that for conventional deadlifters it's only necessary for stability and a little assistance at the start of the lift.&lt;br /&gt;&lt;br /&gt;He doesn't use straps in training and doesn't have any problems pulling weight off the floor. In the rack he's pulled 500kg (1100lbs) and held onto it for 8 seconds.&lt;br /&gt;&lt;br /&gt;The psychological side of lifting is of great importance to him. Before record attempts, he gets into a state of extreme mental excitation. To lift maximal weights he lifts quickly and aggressively. He puts fear out of his mind. There is no thinking of limits or barriers.&lt;br /&gt;&lt;br /&gt;Recently he has excluded powerlifting squats from his training and only squats Olympic style which he feels is better for developing the legs and hip muscles. He also trains the posterior chain with other exercises.&lt;br /&gt;&lt;br /&gt;Plans for the future&lt;br /&gt;&lt;br /&gt;To break the world record in the deadlift he knows he must specialize in it but he would like to eventually return to being competitive in all three lifts and put up a big total.&lt;br /&gt;&lt;br /&gt;He loves the sport of powerlifting and is not in it for money or glory. It is a "way of life." It gives him strength, confidence, develops character, willpower, all qualities that are necessary in everyday life.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-3210704763076113964?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/3210704763076113964/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=3210704763076113964' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/3210704763076113964'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/3210704763076113964'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/07/konstantin-konstantinovs.html' title='硬舉之神 Konstantin Konstantinovs'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-5301491975555338437</id><published>2009-06-22T23:33:00.000-07:00</published><updated>2009-06-22T23:44:56.755-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>C standard以及詳細解譯的文件</title><content type='html'>今天在網路上閒晃，發現了這個不錯的網站&lt;a href="http://c0x.coding-guidelines.com/index.html"&gt;C0X: searching and table of contents&lt;/a&gt;&lt;br /&gt;裡面的內容主要是針對c的standard做詳細的解析。&lt;br /&gt;&lt;br /&gt;作為一個software developer在發生compiling or linking error的當下，若是搞不清楚&lt;br /&gt;問題為何，應該就要先對spec做搜尋才對。有時候google的資料也不一定是對的。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf"&gt;WG14/N1256&lt;/a&gt; 這個是C standard的連結。&lt;!-- href="http://www.cwic-solutions.co.uk/docs/cbook1_1.pdf"&gt;"The New --&gt; &lt;a href="http://www.coding-guidelines.com/cbook/cbook1_1.pdf"&gt;"The New C Standard"&lt;/a&gt;裡面對C standard的每句話下&lt;br /&gt;詳細的註解。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-5301491975555338437?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/5301491975555338437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=5301491975555338437' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/5301491975555338437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/5301491975555338437'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/06/c-standard.html' title='C standard以及詳細解譯的文件'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-3694657632621115879</id><published>2009-06-22T01:56:00.000-07:00</published><updated>2009-06-22T02:16:29.132-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><title type='text'>用vimgrep做到搜尋現在游標下面的字所有出現點</title><content type='html'>map代表在所有的mode下面都可以運行這些指令，包括insert, visual, normal, command。&lt;br /&gt;在normal模式輸入viwy則會反白現在游標下面的字，不管在字的哪個位置都可以。&lt;br /&gt;因為&amp;lt;&amp;gt;在bash底下代表其他的意思，所以要用\。&lt;br /&gt;&amp;lt;C-R&amp;gt;"代表取得用cdxyr所存在x暫存器內的值。&lt;br /&gt;＊＊/*.[ch]代表遞迴搜尋當下所有目錄的c檔和h檔。這邊只能在進入vim時先用cd進入要搜尋&lt;br /&gt;的directory。&lt;br /&gt;&lt;br /&gt;我用三個快捷鍵：ctrl + f（搜尋結果）, ctrl + j（下一個）, ctrl + k（前一個）。&lt;br /&gt;當按下ctrl + f後可以先用":clist"觀看搜尋的結果。&lt;br /&gt;map &amp;lt;C-F&amp;gt;viwy:vimgrep /\&amp;lt;"\&amp;gt;/ **/*.[ch]&lt;br /&gt;map &amp;lt;C-J&amp;gt;:cn&lt;br /&gt;map &amp;lt;C-K&amp;gt;:cp&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;參考：&lt;br /&gt;&lt;br /&gt;&lt;a href="http://greenisland.csie.nctu.edu.tw/wp/2007/02/06/959/"&gt;不是打 vi 的廣告， vim 選擇模式下的熱鍵( Key mapping )&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://fourdollars.blogspot.com/2008/06/help-new-vimgrep.html"&gt;FourDollars Blog&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-3694657632621115879?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/3694657632621115879/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=3694657632621115879' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/3694657632621115879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/3694657632621115879'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/06/vimgrep.html' title='用vimgrep做到搜尋現在游標下面的字所有出現點'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-4780050659051685268</id><published>2009-06-08T21:48:00.000-07:00</published><updated>2009-07-31T02:11:30.147-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux kernel'/><title type='text'>Multi-Point Touch Panel Driver</title><content type='html'>之前曾經做個一個假的模擬multi-touch gesture的demo。這次做的就是真的了，何謂假的multi-touch呢？採用只會回報單點的touch controller，去實驗各種不同的手勢，然後做個一百個人，一個人假設有一百筆的採樣。之後用統計學去分類各種不同的手勢的點電壓變化。藉此做出模倣實際multi-touch真的會送出兩點的這種行為。但，實際上，這種方法無法還原真正的兩點。只能觀察出不同gesture所具有不同的電壓變化。就是只能有multi-touch而不能有multi-point的應用。&lt;br /&gt;&lt;br /&gt;先給出multi-point一張完整的架構圖&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_r6LKRJP8V4w/SnFdAbgXvkI/AAAAAAAAANY/0eHCriRB7PQ/s1600-h/real+multi.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5364170893139885634" style="FLOAT: left; MARGIN: 0pt 10px 10px 0pt; WIDTH: 388px; CURSOR: pointer; HEIGHT: 292px" alt="" src="http://4.bp.blogspot.com/_r6LKRJP8V4w/SnFdAbgXvkI/AAAAAAAAANY/0eHCriRB7PQ/s400/real+multi.JPG" border="0" /&gt;&lt;/a&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;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;完整的source code如下：&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint lang-c"&gt;&lt;br /&gt;/******************************************************************************&lt;br /&gt;&lt;br /&gt;* AsusTsUsb.c  --  Driver for Multi-Touch USB Touchscreens&lt;br /&gt;&lt;br /&gt;*&lt;br /&gt;&lt;br /&gt;* This program is free software; you can redistribute it and/or&lt;br /&gt;&lt;br /&gt;* modify it under the terms of the GNU General Public License as&lt;br /&gt;&lt;br /&gt;* published by the Free Software Foundation; either version 2 of the&lt;br /&gt;&lt;br /&gt;* License, or (at your option) any later version.&lt;br /&gt;&lt;br /&gt;*&lt;br /&gt;&lt;br /&gt;* This program is distributed in the hope that it will be useful, but&lt;br /&gt;&lt;br /&gt;* WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;&lt;br /&gt;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU&lt;br /&gt;&lt;br /&gt;* General Public License for more details.&lt;br /&gt;&lt;br /&gt;*&lt;br /&gt;&lt;br /&gt;* You should have received a copy of the GNU General Public License&lt;br /&gt;&lt;br /&gt;* along with this program; if not, write to the Free Software&lt;br /&gt;&lt;br /&gt;* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.&lt;br /&gt;&lt;br /&gt;*&lt;br /&gt;&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;linux/device.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;linux/hid.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;linux/module.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;linux/usb.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;linux/usb/input.h&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#define DRIVER_VERSION "v0.1"&lt;br /&gt;&lt;br /&gt;#define DRIVER_AUTHOR "Gavin Guo, mimi0213kimo@gmail.com"&lt;br /&gt;&lt;br /&gt;#define DRIVER_DESC "Asus USB Multi-Touch Touch Panel driver"&lt;br /&gt;&lt;br /&gt;#define DRIVER_LICENSE "GPL"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;MODULE_AUTHOR(DRIVER_AUTHOR);&lt;br /&gt;&lt;br /&gt;MODULE_DESCRIPTION(DRIVER_DESC);&lt;br /&gt;&lt;br /&gt;MODULE_LICENSE(DRIVER_LICENSE);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#define USB_VENDOR_ID_ASUS 0x0486&lt;br /&gt;&lt;br /&gt;#define USB_DEVICE_ID_ASUS 0x0185&lt;br /&gt;&lt;br /&gt;#define VAIO_RDESC_CONSTANT 0x0001&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;static int swap_xy;&lt;br /&gt;&lt;br /&gt;module_param(swap_xy, bool, 0644);&lt;br /&gt;&lt;br /&gt;MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped.");&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;struct asus_mt_usb {&lt;br /&gt;&lt;br /&gt;      unsigned char *data;&lt;br /&gt;&lt;br /&gt;      struct input_dev *input1, *input2;&lt;br /&gt;&lt;br /&gt;      struct asmt_device_info *type;&lt;br /&gt;&lt;br /&gt;      struct usb_device *udev;&lt;br /&gt;&lt;br /&gt;      dma_addr_t data_dma;&lt;br /&gt;&lt;br /&gt;      struct urb *urb;&lt;br /&gt;&lt;br /&gt;      char name[128];&lt;br /&gt;&lt;br /&gt;      char phys0[64];&lt;br /&gt;&lt;br /&gt;      char phys1[64];&lt;br /&gt;&lt;br /&gt;      int x1, y1;&lt;br /&gt;&lt;br /&gt;      int x2, y2;&lt;br /&gt;&lt;br /&gt;      int touch1, touch2, press;&lt;br /&gt;&lt;br /&gt;      int p2;&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct asmt_device_info {&lt;br /&gt;&lt;br /&gt;      int min_xc, max_xc;&lt;br /&gt;&lt;br /&gt;      int min_yc, max_yc;&lt;br /&gt;&lt;br /&gt;      int min_press, max_press;&lt;br /&gt;&lt;br /&gt;      int rept_size;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      void (*process_pkt) (struct asus_mt_usb *asmt, unsigned char *pkt, int len);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      /*&lt;br /&gt;&lt;br /&gt;       * used to get the packet len. possible return values:&lt;br /&gt;&lt;br /&gt;       * &amp;gt; 0: packet len&lt;br /&gt;&lt;br /&gt;       * = 0: skip one byte&lt;br /&gt;&lt;br /&gt;       * &amp;lt; 0: -return value more bytes needed&lt;br /&gt;&lt;br /&gt;       */&lt;br /&gt;&lt;br /&gt;      int  (*get_pkt_len) (unsigned char *pkt, int len);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      int  (*read_data)   (struct asus_mt_usb *asmt, unsigned char *pkt);&lt;br /&gt;&lt;br /&gt;      int  (*init)        (struct asus_mt_usb *asmt);&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;static int asus_read_data(struct asus_mt_usb *dev, unsigned char *pkt)&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;      /*&lt;br /&gt;&lt;br /&gt;      if (!(pkt[0] &amp;amp; 0x80)  ((pkt[1]  pkt[2]  pkt[3]) &amp;amp; 0x80))&lt;br /&gt;&lt;br /&gt;             return 0;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      dev-&amp;gt;x = ((pkt[0] &amp;amp; 0x1F) &amp;lt;&amp;lt; 7)  (pkt[2] &amp;amp; 0x7F);&lt;br /&gt;&lt;br /&gt;      dev-&amp;gt;y = ((pkt[1] &amp;amp; 0x1F) &amp;lt;&amp;lt; 7)  (pkt[3] &amp;amp; 0x7F);&lt;br /&gt;&lt;br /&gt;      dev-&amp;gt;touch = pkt[0] &amp;amp; 0x20;&lt;br /&gt;&lt;br /&gt;      */&lt;br /&gt;&lt;br /&gt;      dev-&amp;gt;x1 = ((pkt[4] &amp;amp; 0x0F) &amp;lt;&amp;lt; 8)  (pkt[3] &amp;amp; 0xFF);&lt;br /&gt;&lt;br /&gt;      dev-&amp;gt;y1 = ((pkt[6] &amp;amp; 0x0F) &amp;lt;&amp;lt; 8)  (pkt[5] &amp;amp; 0xFF);&lt;br /&gt;&lt;br /&gt;      dev-&amp;gt;touch1 = pkt[1] &amp;amp; 0x03;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      dev-&amp;gt;p2 = pkt[13] &amp;amp; 0x02;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      if(dev-&amp;gt;p2) {&lt;br /&gt;&lt;br /&gt;             dev-&amp;gt;x2 = ((pkt[10] &amp;amp; 0x0F) &amp;lt;&amp;lt; 8)  (pkt[9] &amp;amp; 0xFF);&lt;br /&gt;&lt;br /&gt;             dev-&amp;gt;y2 = ((pkt[12] &amp;amp; 0x0F) &amp;lt;&amp;lt; 8)  (pkt[11] &amp;amp; 0xFF);&lt;br /&gt;&lt;br /&gt;             dev-&amp;gt;touch2 = pkt[7] &amp;amp; 0x03;&lt;br /&gt;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      return 1;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;static struct asmt_device_info type = {&lt;br /&gt;&lt;br /&gt;             .min_xc  = 0x0,&lt;br /&gt;&lt;br /&gt;             .max_xc  = 0x0fff,&lt;br /&gt;&lt;br /&gt;             .min_yc  = 0x0,&lt;br /&gt;&lt;br /&gt;             .max_yc  = 0x0fff,&lt;br /&gt;&lt;br /&gt;             .rept_size = 8,&lt;br /&gt;&lt;br /&gt;             .read_data = asus_read_data,&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;static void usbtouch_process_pkt(struct asus_mt_usb *asmt,&lt;br /&gt;&lt;br /&gt;                                 unsigned char *pkt, int len)&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;      struct asmt_device_info *type = asmt-&amp;gt;type;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      if (!type-&amp;gt;read_data(asmt, pkt))&lt;br /&gt;&lt;br /&gt;                   return;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      input_report_key(asmt-&amp;gt;input1, BTN_TOUCH, asmt-&amp;gt;touch1);&lt;br /&gt;&lt;br /&gt;      input_report_key(asmt-&amp;gt;input2, BTN_TOUCH, asmt-&amp;gt;touch2);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      if (swap_xy) {&lt;br /&gt;&lt;br /&gt;             input_report_abs(asmt-&amp;gt;input1, ABS_X, asmt-&amp;gt;y1);&lt;br /&gt;&lt;br /&gt;             input_report_abs(asmt-&amp;gt;input1, ABS_Y, asmt-&amp;gt;x1);&lt;br /&gt;&lt;br /&gt;             input_report_abs(asmt-&amp;gt;input2, ABS_X, asmt-&amp;gt;y2);&lt;br /&gt;&lt;br /&gt;             input_report_abs(asmt-&amp;gt;input2, ABS_Y, asmt-&amp;gt;x2);&lt;br /&gt;&lt;br /&gt;      } else {&lt;br /&gt;&lt;br /&gt;             input_report_abs(asmt-&amp;gt;input1, ABS_X, asmt-&amp;gt;x1);&lt;br /&gt;&lt;br /&gt;             input_report_abs(asmt-&amp;gt;input1, ABS_Y, asmt-&amp;gt;y1);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;             if(asmt-&amp;gt;p2) {&lt;br /&gt;&lt;br /&gt;                   input_report_abs(asmt-&amp;gt;input2, ABS_X, asmt-&amp;gt;x2);&lt;br /&gt;&lt;br /&gt;                   input_report_abs(asmt-&amp;gt;input2, ABS_Y, asmt-&amp;gt;y2);&lt;br /&gt;&lt;br /&gt;             }&lt;br /&gt;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      /*&lt;br /&gt;&lt;br /&gt;       * if (type-&amp;gt;max_press)&lt;br /&gt;&lt;br /&gt;       *&lt;br /&gt;&lt;br /&gt;       * input_report_abs input_report_abs(asmt-&amp;gt;input, ABS_PRESSURE, asmt-&amp;gt;press);&lt;br /&gt;&lt;br /&gt;       */&lt;br /&gt;&lt;br /&gt;      input_sync(asmt-&amp;gt;input1);&lt;br /&gt;&lt;br /&gt;      if(asmt-&amp;gt;p2)&lt;br /&gt;&lt;br /&gt;             input_sync(asmt-&amp;gt;input2);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#define USB_REQ_SET_REPORT 0x09&lt;br /&gt;&lt;br /&gt;static int usb_set_report_feature(struct usb_interface *intf, unsigned char type,&lt;br /&gt;&lt;br /&gt;                    unsigned char id, void *buf, int size)&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;      return usb_control_msg(interface_to_usbdev(intf),&lt;br /&gt;&lt;br /&gt;                         usb_sndctrlpipe(interface_to_usbdev(intf), 0),&lt;br /&gt;&lt;br /&gt;                         USB_REQ_SET_REPORT,&lt;br /&gt;&lt;br /&gt;                         USB_TYPE_CLASS  USB_RECIP_INTERFACE,&lt;br /&gt;&lt;br /&gt;                         (type &amp;lt;&amp;lt; 8) + id,&lt;br /&gt;&lt;br /&gt;                         intf-&amp;gt;cur_altsetting-&amp;gt;desc.bInterfaceNumber, buf,&lt;br /&gt;&lt;br /&gt;                         size, HZ);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;static void asus_mt_irq(struct urb *urb)&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;      //printk("%s: that's ok\n", __FUNCTION__ );&lt;br /&gt;&lt;br /&gt;      struct asus_mt_usb *asmt = urb-&amp;gt;context;&lt;br /&gt;&lt;br /&gt;      //struct usbhid_device *usbhid = hid-&amp;gt;driver_data;&lt;br /&gt;&lt;br /&gt;      int retval;&lt;br /&gt;&lt;br /&gt;      unsigned char* data = asmt-&amp;gt;data;&lt;br /&gt;&lt;br /&gt;      switch (urb-&amp;gt;status) {&lt;br /&gt;&lt;br /&gt;      case 0:&lt;br /&gt;&lt;br /&gt;             // success&lt;br /&gt;&lt;br /&gt;             break;&lt;br /&gt;&lt;br /&gt;      case -ETIME:&lt;br /&gt;&lt;br /&gt;             // this urb is timing out&lt;br /&gt;&lt;br /&gt;             dbg("%s - urb timed out - was the device unplugged?",&lt;br /&gt;&lt;br /&gt;                __FUNCTION__);&lt;br /&gt;&lt;br /&gt;             return;&lt;br /&gt;&lt;br /&gt;      case -ECONNRESET:&lt;br /&gt;&lt;br /&gt;      case -ENOENT:&lt;br /&gt;&lt;br /&gt;      case -ESHUTDOWN:&lt;br /&gt;&lt;br /&gt;             return;&lt;br /&gt;&lt;br /&gt;      default:&lt;br /&gt;&lt;br /&gt;             goto resubmit;&lt;br /&gt;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      printk("data = %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", data[0],\&lt;br /&gt;&lt;br /&gt;                   data[1],data[2],data[3],\&lt;br /&gt;&lt;br /&gt;                   data[4],data[5],data[6],data[7],data[8],data[9],data[10],data[11],data[12],data[13]);&lt;br /&gt;&lt;br /&gt;      //printk("%s:urb-&amp;gt;actual_length = %d\n", __FUNCTION__, urb-&amp;gt;actual_length );&lt;br /&gt;&lt;br /&gt;      asmt-&amp;gt;type-&amp;gt;process_pkt(asmt, asmt-&amp;gt;data, urb-&amp;gt;actual_length);&lt;br /&gt;&lt;br /&gt;      resubmit:&lt;br /&gt;&lt;br /&gt;      retval = usb_submit_urb(urb, GFP_ATOMIC);&lt;br /&gt;&lt;br /&gt;      if (retval)&lt;br /&gt;&lt;br /&gt;             err("%s - usb_submit_urb failed with result: %d",&lt;br /&gt;&lt;br /&gt;                __FUNCTION__, retval);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;static int asus_probe(struct usb_interface *intf, const struct usb_device_id *id)&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;      printk("%s\n", __FUNCTION__);&lt;br /&gt;&lt;br /&gt;      struct usb_host_interface *interface = intf-&amp;gt;cur_altsetting;&lt;br /&gt;&lt;br /&gt;      struct usb_device *dev = interface_to_usbdev(intf);&lt;br /&gt;&lt;br /&gt;      struct input_dev *input_dev1, *input_dev2;&lt;br /&gt;&lt;br /&gt;      int n = 0, insize = 14;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      struct asus_mt_usb *asmt = kzalloc(sizeof(struct asus_mt_usb), GFP_KERNEL);&lt;br /&gt;&lt;br /&gt;      asmt-&amp;gt;type = &amp;amp;type;&lt;br /&gt;&lt;br /&gt;      asmt-&amp;gt;udev = dev;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      if (dev-&amp;gt;manufacturer)&lt;br /&gt;&lt;br /&gt;             strlcpy(asmt-&amp;gt;name, dev-&amp;gt;manufacturer, sizeof(asmt-&amp;gt;name));&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      if (dev-&amp;gt;product) {&lt;br /&gt;&lt;br /&gt;             if (dev-&amp;gt;manufacturer)&lt;br /&gt;&lt;br /&gt;                   strlcat(asmt-&amp;gt;name, " ", sizeof(asmt-&amp;gt;name));&lt;br /&gt;&lt;br /&gt;             strlcat(asmt-&amp;gt;name, dev-&amp;gt;product, sizeof(asmt-&amp;gt;name));&lt;br /&gt;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      if (!strlen(asmt-&amp;gt;name))&lt;br /&gt;&lt;br /&gt;             snprintf(asmt-&amp;gt;name, sizeof(asmt-&amp;gt;name),&lt;br /&gt;&lt;br /&gt;                   "USB Touchscreen %04x:%04x",&lt;br /&gt;&lt;br /&gt;                   le16_to_cpu(dev-&amp;gt;descriptor.idVendor),&lt;br /&gt;&lt;br /&gt;                   le16_to_cpu(dev-&amp;gt;descriptor.idProduct));&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      usb_make_path(dev, asmt-&amp;gt;phys0, sizeof(asmt-&amp;gt;phys0));&lt;br /&gt;&lt;br /&gt;      strlcat(asmt-&amp;gt;phys0, "/input0", sizeof(asmt-&amp;gt;phys0));&lt;br /&gt;&lt;br /&gt;      usb_make_path(dev, asmt-&amp;gt;phys1, sizeof(asmt-&amp;gt;phys1));&lt;br /&gt;&lt;br /&gt;      strlcat(asmt-&amp;gt;phys1, "/input1", sizeof(asmt-&amp;gt;phys1));&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      if (!asmt-&amp;gt;type-&amp;gt;process_pkt) {&lt;br /&gt;&lt;br /&gt;             printk("process_pkt is null\n");&lt;br /&gt;&lt;br /&gt;             asmt-&amp;gt;type-&amp;gt;process_pkt = usbtouch_process_pkt;&lt;br /&gt;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      usb_set_intfdata(intf, asmt);&lt;br /&gt;&lt;br /&gt;      input_dev1 = input_allocate_device();&lt;br /&gt;&lt;br /&gt;      input_dev2 = input_allocate_device();&lt;br /&gt;&lt;br /&gt;      input_dev1-&amp;gt;name = asmt-&amp;gt;name;&lt;br /&gt;&lt;br /&gt;      input_dev2-&amp;gt;name = asmt-&amp;gt;name;&lt;br /&gt;&lt;br /&gt;      usb_to_input_id(dev, &amp;amp;input_dev1-&amp;gt;id);&lt;br /&gt;&lt;br /&gt;      usb_to_input_id(dev, &amp;amp;input_dev2-&amp;gt;id);&lt;br /&gt;&lt;br /&gt;      asmt-&amp;gt;input1 = input_dev1;&lt;br /&gt;&lt;br /&gt;      asmt-&amp;gt;input2 = input_dev2;&lt;br /&gt;&lt;br /&gt;      if(!asmt  !input_dev1  !input_dev2) {&lt;br /&gt;&lt;br /&gt;             printk("Memory is not enough\n");&lt;br /&gt;&lt;br /&gt;             goto fail1;&lt;br /&gt;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      input_dev1-&amp;gt;dev.parent = &amp;amp;intf-&amp;gt;dev;&lt;br /&gt;&lt;br /&gt;      input_set_drvdata(input_dev1, asmt);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      input_dev1-&amp;gt;evbit[0] = BIT_MASK(EV_KEY)  BIT_MASK(EV_ABS);&lt;br /&gt;&lt;br /&gt;      input_dev1-&amp;gt;keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);&lt;br /&gt;&lt;br /&gt;      input_set_abs_params(input_dev1, ABS_X, asmt-&amp;gt;type-&amp;gt;min_xc, asmt-&amp;gt;type-&amp;gt;max_xc, 0, 0);&lt;br /&gt;&lt;br /&gt;      input_set_abs_params(input_dev1, ABS_Y, asmt-&amp;gt;type-&amp;gt;min_yc, asmt-&amp;gt;type-&amp;gt;max_yc, 0, 0);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      input_dev2-&amp;gt;dev.parent = &amp;amp;intf-&amp;gt;dev;&lt;br /&gt;&lt;br /&gt;      input_set_drvdata(input_dev2, asmt);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      input_dev2-&amp;gt;evbit[0] = BIT_MASK(EV_KEY)  BIT_MASK(EV_ABS);&lt;br /&gt;&lt;br /&gt;      input_dev2-&amp;gt;keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);&lt;br /&gt;&lt;br /&gt;      input_set_abs_params(input_dev2, ABS_X, asmt-&amp;gt;type-&amp;gt;min_xc, asmt-&amp;gt;type-&amp;gt;max_xc, 0, 0);&lt;br /&gt;&lt;br /&gt;      input_set_abs_params(input_dev2, ABS_Y, asmt-&amp;gt;type-&amp;gt;min_yc, asmt-&amp;gt;type-&amp;gt;max_yc, 0, 0);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      asmt-&amp;gt;data = usb_buffer_alloc(dev, insize, GFP_KERNEL,&lt;br /&gt;&lt;br /&gt;                   &amp;amp;asmt-&amp;gt;data_dma);&lt;br /&gt;&lt;br /&gt;      if(!asmt-&amp;gt;data) {&lt;br /&gt;&lt;br /&gt;             printk("asmt-&amp;gt;data allocating fail");&lt;br /&gt;&lt;br /&gt;             goto fail;&lt;br /&gt;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      for (n = 0; n &amp;lt; interface-&amp;gt;desc.bNumEndpoints; n++) {&lt;br /&gt;&lt;br /&gt;             struct usb_endpoint_descriptor *endpoint;&lt;br /&gt;&lt;br /&gt;             int pipe;&lt;br /&gt;&lt;br /&gt;             int interval;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;             endpoint = &amp;amp;interface-&amp;gt;endpoint[n].desc;&lt;br /&gt;&lt;br /&gt;             if (!usb_endpoint_xfer_int(endpoint))&lt;br /&gt;&lt;br /&gt;                   continue;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;             interval = endpoint-&amp;gt;bInterval;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;             if (usb_endpoint_dir_in(endpoint)) {&lt;br /&gt;&lt;br /&gt;                   if (asmt-&amp;gt;urb)&lt;br /&gt;&lt;br /&gt;                         continue;&lt;br /&gt;&lt;br /&gt;                   if (!(asmt-&amp;gt;urb = usb_alloc_urb(0, GFP_KERNEL)))&lt;br /&gt;&lt;br /&gt;                         goto fail;&lt;br /&gt;&lt;br /&gt;                   pipe = usb_rcvintpipe(dev, endpoint-&amp;gt;bEndpointAddress);&lt;br /&gt;&lt;br /&gt;                   //insize = usb_maxpacket(dev, pipe, usb_pipeout(pipe));&lt;br /&gt;&lt;br /&gt;                   usb_fill_int_urb(asmt-&amp;gt;urb, dev, pipe, asmt-&amp;gt;data,&lt;br /&gt;&lt;br /&gt;                               insize, asus_mt_irq, asmt, interval);&lt;br /&gt;&lt;br /&gt;                   asmt-&amp;gt;urb-&amp;gt;transfer_dma = asmt-&amp;gt;data_dma;&lt;br /&gt;&lt;br /&gt;                   asmt-&amp;gt;urb-&amp;gt;transfer_flags = URB_NO_TRANSFER_DMA_MAP;&lt;br /&gt;&lt;br /&gt;             }&lt;br /&gt;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      char *buf = kmalloc(8, GFP_KERNEL); /* 8 bytes are enough for both products */&lt;br /&gt;&lt;br /&gt;      buf[0] = 0x07;&lt;br /&gt;&lt;br /&gt;      buf[1] = 0x02;&lt;br /&gt;&lt;br /&gt;      if(usb_set_report_feature(intf, 2, 7, buf, 8))&lt;br /&gt;&lt;br /&gt;             printk("set report true\n");&lt;br /&gt;&lt;br /&gt;      else&lt;br /&gt;&lt;br /&gt;             printk("set report false\n");&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      if (usb_submit_urb(asmt-&amp;gt;urb, GFP_ATOMIC)) {&lt;br /&gt;&lt;br /&gt;             printk("usb submit urb error\n");&lt;br /&gt;&lt;br /&gt;             return -EIO;&lt;br /&gt;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      input_register_device(asmt-&amp;gt;input1);&lt;br /&gt;&lt;br /&gt;      input_register_device(asmt-&amp;gt;input2);&lt;br /&gt;&lt;br /&gt;      return 0;&lt;br /&gt;&lt;br /&gt;fail:&lt;br /&gt;&lt;br /&gt;      usb_free_urb(asmt-&amp;gt;urb);&lt;br /&gt;&lt;br /&gt;      asmt-&amp;gt;urb = NULL;&lt;br /&gt;&lt;br /&gt;      usb_buffer_free(dev, insize, asmt-&amp;gt;data, asmt-&amp;gt;data_dma);&lt;br /&gt;&lt;br /&gt;fail1:&lt;br /&gt;&lt;br /&gt;      input_free_device(input_dev1);&lt;br /&gt;&lt;br /&gt;      input_free_device(input_dev2);&lt;br /&gt;&lt;br /&gt;      kfree(asmt);&lt;br /&gt;&lt;br /&gt;      return 1;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;static void asus_disconnect(struct usb_interface *intf)&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;      struct asus_mt_usb *asmt = usb_get_intfdata(intf);&lt;br /&gt;&lt;br /&gt;      usb_set_intfdata(intf, NULL);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      if (asmt) {&lt;br /&gt;&lt;br /&gt;             input_unregister_device(asmt-&amp;gt;input2);&lt;br /&gt;&lt;br /&gt;             input_unregister_device(asmt-&amp;gt;input1);&lt;br /&gt;&lt;br /&gt;             usb_kill_urb(asmt-&amp;gt;urb);&lt;br /&gt;&lt;br /&gt;             //input_unregister_device(asmt-&amp;gt;input);&lt;br /&gt;&lt;br /&gt;             usb_free_urb(asmt-&amp;gt;urb);&lt;br /&gt;&lt;br /&gt;             usb_buffer_free(interface_to_usbdev(intf), 14,&lt;br /&gt;&lt;br /&gt;                         asmt-&amp;gt;data, asmt-&amp;gt;data_dma);&lt;br /&gt;&lt;br /&gt;             kfree(asmt);&lt;br /&gt;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;static const struct usb_device_id asus_devices[] = {&lt;br /&gt;&lt;br /&gt;      { USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS) },&lt;br /&gt;&lt;br /&gt;      { }&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;MODULE_DEVICE_TABLE(usb, asus_devices);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;static struct usb_driver asus_driver = {&lt;br /&gt;&lt;br /&gt;      .name = "asus",&lt;br /&gt;&lt;br /&gt;      .probe = asus_probe,&lt;br /&gt;&lt;br /&gt;      .disconnect = asus_disconnect,&lt;br /&gt;&lt;br /&gt;      .id_table = asus_devices,&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;static int asus_init(void)&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;      printk("asus_init\n");&lt;br /&gt;&lt;br /&gt;      return usb_register(&amp;amp;asus_driver);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;static void asus_exit(void)&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;      printk("asus_exit\n");&lt;br /&gt;&lt;br /&gt;      usb_deregister(&amp;amp;asus_driver);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;module_init(asus_init);&lt;br /&gt;&lt;br /&gt;module_exit(asus_exit);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;先敘述一下流程，點從firmware丟上來，首先經過UHCI再來hub driver。&lt;br /&gt;經過hub後會判斷是否為hid device若是則會經過hid parser，因為我們的device為hid device，所已預設一定會經過hid parser。經由hid parser去parse也就算了，問題是此時的hid parser還沒有成熟到可以parse這個multi-touch hid的digitizer封包。也因為這樣，所以usb kernel裡頭有一個ignore list，可以把device的vendor id &amp;amp; device id放到這個list內。這樣在mapping的時候，就不會map到hid parser driver。&lt;br /&gt;&lt;br /&gt;很有趣的是，當map到hid parser，還會在做一次mapping，這次就是mapping到hid bus。hid bus上面也有一個blacklist。你要加到他的blacklist才不會map到他預設的driver。&lt;br /&gt;&lt;br /&gt;嗯嗯，等到match到我們的driver，會先進入probe，然後create兩個input device並且掛上call back function。這兩個input device會match到evdev handler。&lt;br /&gt;&lt;br /&gt;要支援multi-point，在firmware方面是用set report的方式把multi-point的功能打開，不然預設他只會送出一個點。為了要找怎麼下command給touch panel controller，trace了一下FW的source code發現應該是用set report的方式;所以我便到了kernel的根目錄底下做搜尋&lt;span style="COLOR: rgb(51,51,255)"&gt;grep -r "set" ./drivers/usb/ grep report&lt;/span&gt;。&lt;br /&gt;&lt;br /&gt;發現了這個.c檔可以做參考./drivers/usb/misc/iowarrior.c。進去裡面看了以後發覺還真的是不錯。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint lang-c"&gt;&lt;br /&gt;#define GET_TIMEOUT 5&lt;br /&gt;#define USB_REQ_GET_REPORT  0x01&lt;br /&gt;//#if 0&lt;br /&gt;static int usb_get_report(struct usb_device *dev,&lt;br /&gt;         struct usb_host_interface *inter, unsigned char type,&lt;br /&gt;         unsigned char id, void *buf, int size)&lt;br /&gt;{&lt;br /&gt;return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),&lt;br /&gt;              USB_REQ_GET_REPORT,&lt;br /&gt;              USB_DIR_IN  USB_TYPE_CLASS&lt;br /&gt;              USB_RECIP_INTERFACE, (type &amp;lt;&amp;lt; 8) + id,&lt;br /&gt;              inter-&amp;gt;desc.bInterfaceNumber, buf, size,&lt;br /&gt;              GET_TIMEOUT*HZ);&lt;br /&gt;}&lt;br /&gt;//#endif&lt;br /&gt;&lt;br /&gt;#define USB_REQ_SET_REPORT 0x09&lt;br /&gt;&lt;br /&gt;static int usb_set_report(struct usb_interface *intf, unsigned char type,&lt;br /&gt;         unsigned char id, void *buf, int size)&lt;br /&gt;{&lt;br /&gt;return usb_control_msg(interface_to_usbdev(intf),&lt;br /&gt;              usb_sndctrlpipe(interface_to_usbdev(intf), 0),&lt;br /&gt;              USB_REQ_SET_REPORT,&lt;br /&gt;              USB_TYPE_CLASS  USB_RECIP_INTERFACE,&lt;br /&gt;              (type &amp;lt;&amp;lt; 8) + id,&lt;br /&gt;              intf-&amp;gt;cur_altsetting-&amp;gt;desc.bInterfaceNumber, buf,&lt;br /&gt;              size, HZ);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;我可以用到usb_set_report這個function。後來測了一下type和id有沒有填沒有差，因為FW不會去檢查這兩個欄位。所以code可以像下面這樣子寫：&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint lang-c"&gt;&lt;br /&gt;char *buf = kmalloc(8, GFP_KERNEL);&lt;br /&gt;buf[0] = 7;&lt;br /&gt;buf[1] = 2;&lt;br /&gt;usb_set_report(intf, 0, 0, buf, 8);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;其實這支driver沒有甚麼比較難的地方，大概就是這樣。其他的code自己看一看就知道是為什麼了。&lt;br /&gt;只是剛開始要無中生有，需要去trace相關的source code找出我們需要的部分，比較難。&lt;br /&gt;&lt;br /&gt;真的要掛上這支driver要在X window起來以前，所以要到/etc/inittab裡頭，把run level改成3。&lt;br /&gt;開機就會先進入command mode，然後再sudo insmod hid-asusmt.ko。如此，就可以趕在X window起來之前把driver上起來。&lt;br /&gt;&lt;br /&gt;然後還要記得的是加入xorg.conf到/etc/X11/xorg.conf，如果你不知道xorg.conf裡頭的/dev/input/evdevxx。不知道要設多少，可以去cat /proc/bus/input/devices查詢，也可以順便看看，driver有沒有上好這個devices。若是driver沒有上，這邊就沒有input devices的資訊。&lt;br /&gt;&lt;pre class="prettyprint lang-c"&gt;&lt;br /&gt;Section &amp;quot;ServerLayout&amp;quot;&lt;br /&gt;&lt;br /&gt;      Identifier     &amp;quot;X.org Configured&amp;quot;&lt;br /&gt;&lt;br /&gt;      Screen      0  &amp;quot;Screen0&amp;quot; 0 0&lt;br /&gt;&lt;br /&gt;      InputDevice    &amp;quot;Mouse0&amp;quot; &amp;quot;CorePointer&amp;quot;&lt;br /&gt;&lt;br /&gt;      InputDevice    &amp;quot;Keyboard0&amp;quot; &amp;quot;CoreKeyboard&amp;quot;&lt;br /&gt;&lt;br /&gt;      InputDevice    &amp;quot;Test0&amp;quot;&lt;br /&gt;&lt;br /&gt;      InputDevice    &amp;quot;Test1&amp;quot;&lt;br /&gt;&lt;br /&gt;EndSection &lt;br /&gt;&lt;br /&gt;Section &amp;quot;Files&amp;quot;&lt;br /&gt;&lt;br /&gt;      ModulePath   &amp;quot;/usr/lib/xorg/modules&amp;quot;&lt;br /&gt;&lt;br /&gt;      FontPath     &amp;quot;catalogue:/etc/X11/fontpath.d&amp;quot;&lt;br /&gt;&lt;br /&gt;      FontPath     &amp;quot;built-ins&amp;quot;&lt;br /&gt;&lt;br /&gt;EndSection &lt;br /&gt;&lt;br /&gt;Section &amp;quot;Module&amp;quot;&lt;br /&gt;&lt;br /&gt;      Load  &amp;quot;extmod&amp;quot;&lt;br /&gt;&lt;br /&gt;      Load  &amp;quot;dbe&amp;quot;&lt;br /&gt;&lt;br /&gt;      Load  &amp;quot;glx&amp;quot;&lt;br /&gt;&lt;br /&gt;      Load  &amp;quot;dri2&amp;quot;&lt;br /&gt;&lt;br /&gt;      Load  &amp;quot;dri&amp;quot;&lt;br /&gt;&lt;br /&gt;EndSection &lt;br /&gt;&lt;br /&gt;Section &amp;quot;InputDevice&amp;quot;&lt;br /&gt;&lt;br /&gt;      Identifier  &amp;quot;Keyboard0&amp;quot;&lt;br /&gt;&lt;br /&gt;      Driver      &amp;quot;kbd&amp;quot;&lt;br /&gt;&lt;br /&gt;EndSection &lt;br /&gt;&lt;br /&gt;Section &amp;quot;InputDevice&amp;quot;&lt;br /&gt;&lt;br /&gt;      Identifier  &amp;quot;Mouse0&amp;quot;&lt;br /&gt;&lt;br /&gt;      Driver      &amp;quot;mouse&amp;quot;&lt;br /&gt;&lt;br /&gt;      Option     &amp;quot;Protocol&amp;quot; &amp;quot;auto&amp;quot;&lt;br /&gt;&lt;br /&gt;      Option     &amp;quot;Device&amp;quot; &amp;quot;/dev/input/mice&amp;quot;&lt;br /&gt;&lt;br /&gt;      Option     &amp;quot;ZAxisMapping&amp;quot; &amp;quot;4 5 6 7&amp;quot;&lt;br /&gt;&lt;br /&gt;EndSection &lt;br /&gt;&lt;br /&gt;Section &amp;quot;InputDevice&amp;quot;&lt;br /&gt;&lt;br /&gt;      Identifier  &amp;quot;Test0&amp;quot;&lt;br /&gt;&lt;br /&gt;      Driver      &amp;quot;evdev&amp;quot;&lt;br /&gt;&lt;br /&gt;      Option      &amp;quot;Device&amp;quot;           &amp;quot;/dev/input/event8&amp;quot;&lt;br /&gt;&lt;br /&gt;EndSection &lt;br /&gt;&lt;br /&gt;Section &amp;quot;InputDevice&amp;quot;&lt;br /&gt;&lt;br /&gt;      Identifier  &amp;quot;Test1&amp;quot;&lt;br /&gt;&lt;br /&gt;      Driver      &amp;quot;evdev&amp;quot;&lt;br /&gt;&lt;br /&gt;      Option      &amp;quot;Device&amp;quot;           &amp;quot;/dev/input/event9&amp;quot;&lt;br /&gt;&lt;br /&gt;EndSection &lt;br /&gt;&lt;br /&gt;Section &amp;quot;Monitor&amp;quot;&lt;br /&gt;&lt;br /&gt;      Identifier   &amp;quot;Monitor0&amp;quot;&lt;br /&gt;&lt;br /&gt;      VendorName   &amp;quot;Monitor Vendor&amp;quot;&lt;br /&gt;&lt;br /&gt;      ModelName    &amp;quot;Monitor Model&amp;quot;&lt;br /&gt;&lt;br /&gt;EndSection &lt;br /&gt;&lt;br /&gt;Section &amp;quot;Device&amp;quot;&lt;br /&gt;&lt;br /&gt;        ### Available Driver options are:-&lt;br /&gt;&lt;br /&gt;        ### Values: &amp;lt;i&amp;gt;: integer, &amp;lt;f&amp;gt;: float, &amp;lt;bool&amp;gt;: &amp;quot;True&amp;quot;/&amp;quot;False&amp;quot;,&lt;br /&gt;&lt;br /&gt;        ### &amp;lt;string&amp;gt;: &amp;quot;String&amp;quot;, &amp;lt;freq&amp;gt;: &amp;quot;&amp;lt;f&amp;gt; Hz/kHz/MHz&amp;quot;&lt;br /&gt;&lt;br /&gt;        ### [arg]: arg optional&lt;br /&gt;&lt;br /&gt;        #Option     &amp;quot;NoAccel&amp;quot;             # [&amp;lt;bool&amp;gt;]&lt;br /&gt;&lt;br /&gt;        #Option     &amp;quot;SWcursor&amp;quot;            # [&amp;lt;bool&amp;gt;]&lt;br /&gt;&lt;br /&gt;        #Option     &amp;quot;ColorKey&amp;quot;            # &amp;lt;i&amp;gt;&lt;br /&gt;&lt;br /&gt;        #Option     &amp;quot;CacheLines&amp;quot;          # &amp;lt;i&amp;gt;&lt;br /&gt;&lt;br /&gt;        #Option     &amp;quot;Dac6Bit&amp;quot;             # [&amp;lt;bool&amp;gt;]&lt;br /&gt;&lt;br /&gt;        #Option     &amp;quot;DRI&amp;quot;                 # [&amp;lt;bool&amp;gt;]&lt;br /&gt;&lt;br /&gt;        #Option     &amp;quot;NoDDC&amp;quot;               # [&amp;lt;bool&amp;gt;]&lt;br /&gt;&lt;br /&gt;        #Option     &amp;quot;ShowCache&amp;quot;           # [&amp;lt;bool&amp;gt;]&lt;br /&gt;&lt;br /&gt;        #Option     &amp;quot;XvMCSurfaces&amp;quot;        # &amp;lt;i&amp;gt;&lt;br /&gt;&lt;br /&gt;        #Option     &amp;quot;PageFlip&amp;quot;            # [&amp;lt;bool&amp;gt;]&lt;br /&gt;&lt;br /&gt;      Identifier  &amp;quot;Card0&amp;quot;&lt;br /&gt;&lt;br /&gt;      Driver      &amp;quot;intel&amp;quot;&lt;br /&gt;&lt;br /&gt;      VendorName  &amp;quot;Intel Corporation&amp;quot;&lt;br /&gt;&lt;br /&gt;      BoardName   &amp;quot;Mobile 945GME Express Integrated Graphics Controller&amp;quot;&lt;br /&gt;&lt;br /&gt;      BusID       &amp;quot;PCI:0:2:0&amp;quot;&lt;br /&gt;&lt;br /&gt;EndSection &lt;br /&gt;&lt;br /&gt;Section &amp;quot;Screen&amp;quot;&lt;br /&gt;&lt;br /&gt;      Identifier &amp;quot;Screen0&amp;quot;&lt;br /&gt;&lt;br /&gt;      Device     &amp;quot;Card0&amp;quot;&lt;br /&gt;&lt;br /&gt;      Monitor    &amp;quot;Monitor0&amp;quot;&lt;br /&gt;&lt;br /&gt;      SubSection &amp;quot;Display&amp;quot;&lt;br /&gt;&lt;br /&gt;             Viewport   0 0&lt;br /&gt;&lt;br /&gt;             Depth     1&lt;br /&gt;&lt;br /&gt;      EndSubSection&lt;br /&gt;&lt;br /&gt;      SubSection &amp;quot;Display&amp;quot;&lt;br /&gt;&lt;br /&gt;             Viewport   0 0&lt;br /&gt;&lt;br /&gt;             Depth     4&lt;br /&gt;&lt;br /&gt;      EndSubSection&lt;br /&gt;&lt;br /&gt;      SubSection &amp;quot;Display&amp;quot;&lt;br /&gt;&lt;br /&gt;             Viewport   0 0&lt;br /&gt;&lt;br /&gt;             Depth     8&lt;br /&gt;&lt;br /&gt;      EndSubSection&lt;br /&gt;&lt;br /&gt;      SubSection &amp;quot;Display&amp;quot;&lt;br /&gt;&lt;br /&gt;             Viewport   0 0&lt;br /&gt;&lt;br /&gt;             Depth     15&lt;br /&gt;&lt;br /&gt;      EndSubSection&lt;br /&gt;&lt;br /&gt;      SubSection &amp;quot;Display&amp;quot;&lt;br /&gt;&lt;br /&gt;             Viewport   0 0&lt;br /&gt;&lt;br /&gt;             Depth     16&lt;br /&gt;&lt;br /&gt;      EndSubSection&lt;br /&gt;&lt;br /&gt;      SubSection &amp;quot;Display&amp;quot;&lt;br /&gt;&lt;br /&gt;             Viewport   0 0&lt;br /&gt;&lt;br /&gt;             Depth     24&lt;br /&gt;&lt;br /&gt;      EndSubSection&lt;br /&gt;&lt;br /&gt;EndSection&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;執行/usr/bin/startx進入X window。&lt;br /&gt;若是還沒有安裝MPX得先遵循下面的步驟:&lt;br /&gt;This is readme for MPX enabling on Moblin.&lt;br /&gt;&lt;br /&gt;1 Install the latest Moblin image&lt;br /&gt;&lt;br /&gt;2 update the RPM packages in the attached .zip file by “rpm –Uvh xxxx.rpm”&lt;br /&gt;&lt;br /&gt;3 reboot&lt;br /&gt;&lt;br /&gt;4 plug the second USB mouse&lt;br /&gt;&lt;br /&gt;5 execute “xinput list”, then you could find the device id of newly plugged second USB mouse. In my system it’s “HID 413c:3010”&lt;br /&gt;&lt;br /&gt;6 execute “xinput –create-master “mouse2””&lt;br /&gt;&lt;br /&gt;7 execute “xinput –reattach “HID 413c:3010” “mouse2 pointer””&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Then you would find 2 pointers on the screen, which means MPX works J&lt;br /&gt;&lt;br /&gt;在我們的兩個node裡面第二個node的名稱叫做Test1，所以必須要把xinput -reattach之後的“HID 413c:3010”改成"Test1"，這樣就能夠使用兩個點了。如果要移除第二個點則xinput -remove-master "gavin pointer"。即可。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-4780050659051685268?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/4780050659051685268/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=4780050659051685268' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/4780050659051685268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/4780050659051685268'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/06/multi-point-touch-panel-driver.html' title='Multi-Point Touch Panel Driver'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_r6LKRJP8V4w/SnFdAbgXvkI/AAAAAAAAANY/0eHCriRB7PQ/s72-c/real+multi.JPG' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-906820423568241643</id><published>2009-05-26T00:41:00.000-07:00</published><updated>2009-05-26T01:35:28.046-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='生活'/><title type='text'>劉炯朗教授的演講</title><content type='html'>昨天和洋芋片到台大的文學院演講廳聽劉炯朗教授的演講。&lt;br /&gt;&lt;br /&gt;先前因為假日不知道要帶小孩到哪邊去逛逛，想想，大學校園是不錯的選擇，所以就到台大逛逛，當然也希望從小給他感染國內一流大學的氣氛，希望長大以後，也可以進入這麼優秀的學校就讀。而當我們在校內遊逛的同時，無意間看到劉炯朗教授的演講廣告旗幟，當下就起了很大的興趣。相信，有準備過資工研究所的人都知道C. L. Liu這號人物。因為其中一本離散數學的參考書目就是出自於這位大師之手。&lt;br /&gt;&lt;br /&gt;後來又上網查了一下演講的相關訊息，發現，對校外開放的160個名額，竟然已經額滿。&lt;br /&gt;&lt;br /&gt;又google了一下劉炯朗這三個字，發現原來是他的名氣真的太大了。&lt;br /&gt;&lt;br /&gt;成大畢業，MIT碩士，MIT博士。十年MIT副教授，26年UIUC教授，還有當過UIUC助理副校長，清大校長.........&lt;br /&gt;&lt;br /&gt;在晚上快要6:50分的時候，依約到台大的正門口集合，因為臨時要找裝訂的影印店，所以遲了一下，最後匆匆忙的把要裝定的書丟到台大正門口對面馬路的萬里影印店。又匆匆的衝向文學院演講廳。嗯，進到演講廳後人比我們想像的還要少許多，本來是想說可能要做到階梯上面聽了。&lt;br /&gt;&lt;br /&gt;一開始，劉教授說了他一上大學時是成大工學院，畢業時因為八月要改名成功大學的緣故，所以，他們那屆大家集體延畢，哈哈。因此，他開了個玩笑說只要有人說他是成大工學院畢業的，就是他的學長，如果是成功大學畢業的就是他的學弟。接著，劉教授開始他的學思歷程演講，他說到要講他的七十幾年來的學思歷程，他不知道如何說起，乾脆說他這三個禮拜的學思歷程好了，其實他鋪了一個很長的梗。因為劉教授說，從2005年10月開始，他在台灣的新竹IC之音廣播電台，主持「我愛談天你愛笑」廣播節目，內容多數和科技、教育、文學等領域比較接近。同名節目於2009年4月3日起在台北NEWS 98電台每週五上午10:30播出半小時。劉教授想告訴我們他為了準備這些節目的內容，他做了什麼。中間，介紹了很多古文，我記得的包括，莊子的大劈棺，魚樂之辯，王羲之的蘭亭集序，最後到周杰倫作曲和方文山作詞的蘭亭序。&lt;br /&gt;&lt;br /&gt;這其中，我看到了一位智者如何在他生命的晚年，還不斷的在努力學習，這種活力著實的撼動著我的內心。從這場演講裡，我感覺到劉教授的知識不止來自於早期的努力，連周杰倫的歌曲，他也是在這三個禮拜才學的，當然，他提及了幾首周杰倫的其他歌曲，像我這樣不聽流行音樂的年輕人，當然非常的汗顏。他對這些歌曲的熟晰度，也可以顯示了，他求知的廣泛，和深入。&lt;br /&gt;&lt;br /&gt;除此之外，劉教授，也鼓勵在場的聽眾，不要畫地自限，要有廣泛的興趣。順從自己的喜好，多多培養專業以外的興趣，感受這世界的美妙，像他說的，有時候看到一樣東西覺得非常的有趣，會有相見恨晚的感慨，為何年紀那麼大了，他才接觸到。&lt;br /&gt;&lt;br /&gt;在演講結束後的問答時間，我也舉手發了個問題，因為之前看了許多環保議題的影片，如從空中看地球，讓我聯想到了資訊產業對於地球生態所帶來的影響，這個議題，因為和我所從事的工作常常有衝突的情形，所以矛盾在我心中停留了許久。主要是想要了解，背景出自於eecs的劉教授，對於資訊產業對地球所帶來的環境影響有什麼看法？&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;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-906820423568241643?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/906820423568241643/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=906820423568241643' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/906820423568241643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/906820423568241643'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/05/blog-post.html' title='劉炯朗教授的演講'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-1656266094815075779</id><published>2009-05-26T00:23:00.000-07:00</published><updated>2009-05-26T21:52:01.305-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux kernel'/><title type='text'>linux kernel: invalid module format</title><content type='html'>問題是這樣的，我現在做的工作是要在新的netbook上面寫driver，而在trace code的過程需要在kernel內加些debug message，所以要重新build kernel。有賴於netbook cpu performance的考量，所以編譯kernel的工作我在pc上面做掉，然後再把編譯好的kernel用隨身碟copy到netbook上面。&lt;br /&gt;&lt;br /&gt;後來覺得copy來copy去的太麻煩了，所以今天在編譯module的時候，我就在netbook上面編譯，因為懶的把pc上面我已經修改過的kernel tar起來，所以，直接拿linux kernel 2.6.29沒有修改過的kernel來和我的driver做編譯link。當module編好後，進行insmod xxx.ko時竟然出現了invalid module format的錯誤訊息，當下馬上傻眼。想想我是用同樣的kernel版本，但為何會出錯呢？&lt;br /&gt;&lt;br /&gt;debug了半天，結果發現，我在insmod的時候，當下netbook所運行的kernel是pc上面我已經修改的版本，而和我編譯driver的時候所連結的kernel是pure的沒有修改過的，&lt;span style="color: rgb(153, 153, 153);"&gt;這兩個kernel雖然版號是相同的，但是因為內容被我加了幾行printk，所以在insmod的時候會出現invalid module format的訊息。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 153, 153);"&gt;這個有趣的問題點出了我錯誤的觀念，insmod的時候系統判斷的不止是版號而已，kernel會判斷你compile時link的kernel和現在運行的kernel原始碼是否完全一致。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;20090527&lt;br /&gt;今天又把這個問題研究了一下，發現有幾個嚴重的觀念錯誤，上面用灰色表示觀念不正確的句子。&lt;br /&gt;&lt;br /&gt;剛剛用dmesg view了一下發現&lt;br /&gt;&lt;br /&gt;hid_asusmt: version magic '2.6.29-netbook SMP preempt mod_unload PENTIUM ' should be '2.6.29-netbook SMP mod_unload PENTIUM'&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 153, 153);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;這個很直觀的一定是我現在driver編譯時link的kernel是有開啟preempt的功能，而舊版的沒有被更改過的kernel是non-preemptive。所以我又去查了一下kernel source底下的.config，搜尋PREEMPT，結果CONFIG_PREEMPT_VOLUNTARY=y，然後再去make menuconfig看看到底是哪裡把這個選項給勾了起來。&lt;br /&gt;&lt;br /&gt;Processor type and features --&gt; Preemption Model (Preemptible Kernel (Low-Latency Desktop)) --&gt; Voluntary Kernel Preemption (Desktop)&lt;br /&gt;&lt;br /&gt;終於抓到這隻大虫了，哈哈。又看到了其他兩個選項:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 153, 153);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;No Forced Preemption (Server)&lt;br /&gt;Preemptive Kernel (Low-Latency Desktop)&lt;br /&gt;&lt;br /&gt;所以剛剛和我靠腰的就是要把Preemptive Kernel勾起來，難怪我現在用桌面那麼不順，原來就是沒有勾起Preemptive Kernel。&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 153, 153);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;看到這裡聯想起之前在看趙炯的linux kernel完全剖析裡有個片段是這樣的：&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_r6LKRJP8V4w/ShzDaGajzJI/AAAAAAAAAK4/J9IiO9Mohxw/s1600-h/nonpreempt.JPG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 365px;" src="http://2.bp.blogspot.com/_r6LKRJP8V4w/ShzDaGajzJI/AAAAAAAAAK4/J9IiO9Mohxw/s400/nonpreempt.JPG" alt="" id="BLOGGER_PHOTO_ID_5340358111320591506" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&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;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;這代表我們原來使用的kernel是不可被搶佔的，timer interrupt一進來他會先去檢查現在被interrupt的mode CPL是&lt;span style="color: rgb(255, 0, 0);"&gt;0&lt;/span&gt;或是&lt;span style="color: rgb(255, 0, 0);"&gt;3&lt;/span&gt;如果是3則會調用schuduler檢查是否需要reschedule，若是0則把counter加一，不做reschedule。如果是可搶佔的kernel，則會在kernel內就做reschedule。&lt;br /&gt;&lt;br /&gt;可以這樣想像，如果一支process，call了int 0x80做read的動作，當read到一半時，hardware interrupt進來，之後如果kernel是preemptive，則有可能這時候就做context switch，若是non-preemptive則只會把jiffies加一。&lt;br /&gt;&lt;br /&gt;當然在user mode也有&lt;span style="color: rgb(255, 0, 0);"&gt;preemptive&lt;/span&gt;與&lt;span style="color: rgb(255, 0, 0);"&gt;non-preemptive&lt;/span&gt;，一般我們使用的多工是preemptive，像round-robin之類的。若是non-preemptive可能適用在real time OS，一般來說是一個一個process run，除非有priority比較大的process進來，才會把現在priority較低的process置換掉。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-1656266094815075779?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/1656266094815075779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=1656266094815075779' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/1656266094815075779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/1656266094815075779'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/05/linux-kernel-invalid-module-format.html' title='linux kernel: invalid module format'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_r6LKRJP8V4w/ShzDaGajzJI/AAAAAAAAAK4/J9IiO9Mohxw/s72-c/nonpreempt.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-9111792704495404894</id><published>2009-04-22T04:35:00.000-07:00</published><updated>2009-05-06T00:37:14.510-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux kernel'/><title type='text'>Multi-Touch Demo on T91 with Intel fantastic Moblin</title><content type='html'>因為老闆的要求，所以要在新的moblin上面porting multi-touch的幾種Gesture。&lt;br /&gt;由於是demo的緣故所以用ioctl pollling的方式，沒有實做新的input event並且用送event的方式實踐。下面是這個實做的diagram。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_r6LKRJP8V4w/SfUqr7giJsI/AAAAAAAAAJw/KfsF2gbawMk/s1600-h/traditional+touch.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 299px;" src="http://1.bp.blogspot.com/_r6LKRJP8V4w/SfUqr7giJsI/AAAAAAAAAJw/KfsF2gbawMk/s400/traditional+touch.JPG" alt="" id="BLOGGER_PHOTO_ID_5329212668259739330" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;首先談談panel的構造，我們使用的是傳統的四線式單點touch panel，使用自己做的硬體電路模擬實際的多點情形。Controller裡FW送上來的data是長這樣:&lt;br /&gt;&lt;pre class="prettyprint lang-cpp"&gt;&lt;br /&gt;           g_MouseReport[0]    = 1;&lt;br /&gt;           g_MouseReport[1]    = (g_uZ1 &amp;amp;amp; 0xFF);          &lt;br /&gt;           g_MouseReport[2]     = (g_uZ1 &amp;gt;&amp;gt; 8) &amp;amp;amp; 0x0F;&lt;br /&gt;           g_MouseReport[3]    = 0;&lt;br /&gt;&lt;br /&gt;           g_MouseReport[4]    = (g_uX1 &amp;amp;amp; 0xFF);          &lt;br /&gt;           g_MouseReport[5]     = (g_uX1 &amp;gt;&amp;gt; 8) &amp;amp;amp; 0x0F;      &lt;br /&gt;           g_MouseReport[6]    = (g_uY1 &amp;amp;amp; 0xFF);          &lt;br /&gt;           g_MouseReport[7]     = (g_uY1 &amp;gt;&amp;gt; 8) &amp;amp;amp; 0x0F;&lt;br /&gt; &lt;br /&gt;           g_MouseReport[8]    = 1;&lt;br /&gt;           g_MouseReport[9]    = (g_uZ2 &amp;amp;amp; 0xFF);&lt;br /&gt;           g_MouseReport[10]     = (g_uZ2 &amp;gt;&amp;gt; 8) &amp;amp;amp; 0x0F;&lt;br /&gt;           g_MouseReport[11]    = 1;&lt;br /&gt;           g_MouseReport[12]    = (g_uX2 &amp;amp;amp; 0xFF);&lt;br /&gt;           g_MouseReport[13]     = (g_uX2 &amp;gt;&amp;gt; 8) &amp;amp;amp; 0x0F | 0x10;      &lt;br /&gt;           g_MouseReport[14]    = (g_uY2 &amp;amp;amp; 0xFF);          &lt;br /&gt;           g_MouseReport[15]     = (g_uY2 &amp;gt;&amp;gt; 8) &amp;amp;amp; 0x0F | 0x10;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;會收到兩個report為一筆資料，一個report data有八個bytes，兩組report data可以合成一組七個bytes的資料，以利上面的演算法做計算。g_MouseReport陣列的單位是byte，第零個和第八個代表的是資料的結束或者是開始，如果是1代表還有資料在傳送，若是零則代表一筆gesture資料的結束。每筆report data的第四個byte也就是3和11所代表的意義是兩筆data的前後順序，如果是0代表第一筆，1代表第二筆，因此可以由這個值來區分前後。其他的bytes分別封裝了X1,Y1,Z1,X2,Y2,Z2。Z代表壓力的大小，這些座標值的精準度為12 bits，知道這個就可以看懂，上面的code為何要這麼寫。&lt;br /&gt;&lt;br /&gt;洋洋灑灑的寫了一堆，重點是我們要如何拿到這些data？首先，要trace USB hub，在drivers/usb/core/hub.c裡面，看了以後你就知道，東西是如何從下面的UHCI, EHCI傳送資料上來，之後在hub_port_connect_change會幫一個新的device做註冊，使用usb_new_device這個function。再接著，你會看到一個device進來後會先mapping到一支generic_driver，這是每個usb device的必經之路，這支driver，會對usb device做descriptor的詢問動作，然後得到device的基本資料，再拿這些資訊去對所有usb bus上面的interface driver做mapping。這就是一個usb device進來以後是如何能在系統裡正常運作的過程。&lt;br /&gt;&lt;br /&gt;很可愛的是，我們這邊的Device宣告為hid device，但，傳送上來的資料卻和report descriptor裡面宣告的資料是不符合的，我們自己傳送兩筆8 bytes的report descriptor資料，裡面也宣告為x軸或者是y軸，但是都是需要上面所提到的算法，做重新的組合，因此，我們的HID deviced不能經過HID protocol，不然parse出來的資料會亂七八糟。就是為了要解決這個問題，而且時間又不太充裕的情況下，我想了兩個方法，第一個是去看makefile，想辦法在hid driver被註冊前，先註冊我們的Driver，同時也用Vendor ID and Device ID做比對的項目，這樣，我們的Driver就會提早被device認到，也就不會走到HID protocol這個死胡同裡。但是這樣的缺點是要build in，而且在開發的過程極其麻煩，每次改code要確定能不能work就要整個kernel重build，然後再重開機，實在是太耗時間了。第二個方法，我在usb bus的match函式裡頭，加入了判斷的式子:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint lang-cpp"&gt;&lt;br /&gt;int usb_match_one_id(...) {&lt;br /&gt;...&lt;br /&gt;if(dev=&amp;gt;descriptor.idVendor == 0x0486 &amp;amp;&amp;amp; dev-&amp;gt;descriptor.idProduct == 0x0180)&lt;br /&gt;intf-&amp;gt;desc.bInterfaceClass = 0;&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;這判斷式的用意就是要把我們device的HID標籤拿掉，讓他不會進入HID protocol。但，缺點是，USB protocol被我更動了，這樣，open source community那群人應該不會饒了我吧！其實，好像也沒那麼嚴重，我只是要demo而已，所以最後就這樣做下去了。測試看看，果不期然，這樣我的touch panel就不會被HID給抓走。而在我driver還沒掛上的時候自己埋的printk，dmesg顯示沒有被mapping的現象。&lt;br /&gt;&lt;br /&gt;現在HID這邊已經解決了，接下來就是要撰寫自己的USB driver。&lt;br /&gt;恩，我就在Driver資料夾底下的input和usb/input裡面晃呀晃，後來看到drivers/usb/input底下找到了一支Vojtech Pavlik大師(你如果常常看code可以發現input底下的code很多都出自於他的手)寫的usbmouse.c驅動，他裡面就是為了支援boot device的，而不用為了要支援mouse和keyboard而大費周章的把HID protocol掛上。所以自己寫了隻code去parse boot device。正好，大師的作品可以派上用場。所以我就把他短短兩百多行的Code trace一下，不久寫出自己的第一隻usb driver。也是我的第一隻driver。&lt;br /&gt;&lt;br /&gt;首先看看我的Makefile:&lt;br /&gt;他是長這樣&lt;br /&gt;&lt;pre class="prettyprint sh"&gt;&lt;br /&gt;obj-m += asusmt.o&lt;br /&gt;KDIR=/home/bboy/linux-2.6.28&lt;br /&gt;PWD=$(shell pwd)&lt;br /&gt;&lt;br /&gt;KVERSION = $(shell uname -r)&lt;br /&gt;&lt;br /&gt;all:&lt;br /&gt;#cp ../linux-source-2.6.21.4-eeepc/drivers/usb/input/asusmt.c ./&lt;br /&gt;make -C $(KDIR) M=$(PWD) clean&lt;br /&gt;make -C $(KDIR) M=$(PWD) modules&lt;br /&gt;#下面先移除asusmt舊的module&lt;br /&gt;sudo rmmod asusmt&lt;br /&gt;#這邊在插入asusmt.ko新編譯好的module&lt;br /&gt;sudo insmod asusmt.ko&lt;br /&gt;&lt;br /&gt;clean:&lt;br /&gt;make -C $(KDIR) M=$(PWD) clean&lt;br /&gt;&lt;br /&gt;install:&lt;br /&gt;make -C $(KDIR) M=$(PWD) modules_install&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;妳可以把Makefile寫成這樣KDIR是你放kernel source code的地方，如果Driver安裝在不同的kernel上，則需要根據不同的kernel source重新編譯。&lt;br /&gt;&lt;br /&gt;接著我貼上USB driver端所有的程式碼:&lt;br /&gt;trace這段code可以從init開始看，insmod後就會執行init，rmmod的時候會執行exit。device拔除後會執行disconnect，還有重要的是probe，當driver和device mapping成功後，第一個執行的function就是probe，裡面包含了/dev/asus_mt的創建，還有urb的初始化，和urb的submit，都在這裡面。最後就是irq那個urb的callback function。當有data進來的時候就會從irq那隻把urb丟進來。&lt;br /&gt;&lt;pre class="prettyprint lang-cpp"&gt;&lt;br /&gt;/******************************************************************************&lt;br /&gt;* AsusTsUsb.c  --  Driver for Multi-Touch USB Touchscreens&lt;br /&gt;*&lt;br /&gt;* This program is free software; you can redistribute it and/or&lt;br /&gt;* modify it under the terms of the GNU General Public License as&lt;br /&gt;* published by the Free Software Foundation; either version 2 of the&lt;br /&gt;* License, or (at your option) any later version.&lt;br /&gt;*&lt;br /&gt;* This program is distributed in the hope that it will be useful, but&lt;br /&gt;* WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU&lt;br /&gt;* 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., 675 Mass Ave, Cambridge, MA 02139, USA.&lt;br /&gt;*&lt;br /&gt;*/&lt;br /&gt;#include &amp;lt;linux/kernel.h&amp;gt;&lt;br /&gt;#include &amp;lt;linux/slab.h&amp;gt;&lt;br /&gt;#include &amp;lt;linux/module.h&amp;gt;&lt;br /&gt;#include &amp;lt;linux/init.h&amp;gt;&lt;br /&gt;//上面這四行後來把他們comment掉其實也沒事，不知道那邊會用到，我也是直接從&lt;br /&gt;//Vojtech Pavlik的code copy過來的。&lt;br /&gt;#include &amp;lt;linux/usb/input.h&amp;gt;&lt;br /&gt;#include &amp;lt;linux/hid.h&amp;gt;&lt;br /&gt;#include &amp;lt;asm/uaccess.h&amp;gt;&lt;br /&gt;&lt;br /&gt;//這邊就照著他們的標準寫一些基本的information。&lt;br /&gt;#define DRIVER_VERSION "v0.1"&lt;br /&gt;#define DRIVER_AUTHOR "Gavin Guo, mimi0213kimo@gmail.com"&lt;br /&gt;#define DRIVER_DESC "Asus USB Multi-Touch Touch Panel driver"&lt;br /&gt;#define DRIVER_LICENSE "GPL"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;MODULE_AUTHOR(DRIVER_AUTHOR);&lt;br /&gt;MODULE_DESCRIPTION(DRIVER_DESC);&lt;br /&gt;MODULE_LICENSE(DRIVER_LICENSE);&lt;br /&gt;&lt;br /&gt;//asus_mt是用在註冊node時所使用的字串&lt;br /&gt;#define ASUS_MT_STRING "asus_mt"&lt;br /&gt;//點進來的時候我是用100個大小的queue去存他&lt;br /&gt;#define MAXQUEUE 100&lt;br /&gt;//兩個8個bytes的data，最後會parse成7個bytes的data往上傳。&lt;br /&gt;#define DATANUM 7&lt;br /&gt;//parse好的資料暫時存放在axies_data array&lt;br /&gt;u32 axies_data[DATANUM];&lt;br /&gt;//存放動態get到的major number。&lt;br /&gt;static int asus_mt_major;&lt;br /&gt;//註冊class時要用到的point。&lt;br /&gt;static struct class *asus_mt_class;&lt;br /&gt;//queue的head和tail，head用來新增data到queue，tail用來拿出data。&lt;br /&gt;static int head = 0, tail = 0;&lt;br /&gt;//ready用來判斷是否queue內已有資料進來。&lt;br /&gt;static int ready = 0;&lt;br /&gt;//當我們實作等待資料的架構時，要先宣告一個wait。&lt;br /&gt;wait_queue_head_t wait;&lt;br /&gt;//這個就是我們存放資料的queue&lt;br /&gt;typedef struct DataQueue {&lt;br /&gt;u32 axies_data[DATANUM];&lt;br /&gt;}DataQueue;&lt;br /&gt;&lt;br /&gt;DataQueue queue[MAXQUEUE];&lt;br /&gt;//DECLARE_MUTEX(cosem);&lt;br /&gt;/*&lt;br /&gt;axies_data[0] = button&lt;br /&gt;axies_data[1] = Z1&lt;br /&gt;axies_data[2] = X1&lt;br /&gt;axies_data[3] = Y1&lt;br /&gt;axies_data[4] = Z2&lt;br /&gt;axies_data[5] = X2&lt;br /&gt;axies_data[6] = Y2&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;struct AsTouch_usb {&lt;br /&gt;unsigned char *data;&lt;br /&gt;dma_addr_t data_dma;&lt;br /&gt;struct urb *irq;&lt;br /&gt;struct usb_device *udev;&lt;br /&gt;struct input_dev *input;&lt;br /&gt;char name[128];&lt;br /&gt;char phys[64];&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;//這個struct存放的是要比較的項目，其中flag代表的是要比較的項目，&lt;br /&gt;//flag下面是要比較的實際內容，其中USB_DEVICE_ID_MATCH_DEVICE代表要比較idVendor與&lt;br /&gt;//idProduct，而實際的內容存放在下面。之所以除了vendor id和device id外還要比較&lt;br /&gt;//SUBCLASS_BOOT和MOUSE是因為目前這個device上面有兩種interface，一個是mouse另一個&lt;br /&gt;//是keyboard，mouse是模擬成我們的touch panel，keyboard用不到，但為了防止keyboard&lt;br /&gt;//亂送資料，所以多加幾個mapping的項目，使之只能mapping到mouse。這樣driver就不會接&lt;br /&gt;//收到keyboard送出來的report descriptor。&lt;br /&gt;static struct usb_device_id AsusTsUsb_devices[] = {&lt;br /&gt;{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE |&lt;br /&gt;USB_DEVICE_ID_MATCH_INT_SUBCLASS |&lt;br /&gt;USB_DEVICE_ID_MATCH_INT_PROTOCOL,&lt;br /&gt;.idVendor = 0x0486,&lt;br /&gt;.idProduct = 0x0180,&lt;br /&gt;.bInterfaceSubClass = USB_INTERFACE_SUBCLASS_BOOT,&lt;br /&gt;.bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE&lt;br /&gt;},&lt;br /&gt;{ }&lt;br /&gt;};&lt;br /&gt;//insert_queue用來新增資料到queue&lt;br /&gt;static int insert_queue()&lt;br /&gt;{&lt;br /&gt;if ( (head + 1) == tail ) {&lt;br /&gt;printk("DataQueue is full, some data is losed\n");&lt;br /&gt;/* Push tail to 1 step forward, prevent tail from reading new coming data */&lt;br /&gt;//tail++;&lt;br /&gt;return -1;&lt;br /&gt;}else {&lt;br /&gt;head = (head + 1) % MAXQUEUE;&lt;br /&gt;int i = 0;&lt;br /&gt;for( ; i &amp;lt; DATANUM; i++ ){&lt;br /&gt;queue[head].axies_data[i] = axies_data[i];&lt;br /&gt;}&lt;br /&gt;printk("insert queue[%d].axies_data %04x %04x %04x %04x %04x %04x %04x\n", head,&lt;br /&gt;  queue[head].axies_data[0],queue[head].axies_data[1],queue[head].axies_data[2],&lt;br /&gt;queue[head].axies_data[3],queue[head].axies_data[4],queue[head].axies_data[5],&lt;br /&gt;queue[head].axies_data[6]);&lt;br /&gt;}&lt;br /&gt;return 0;&lt;br /&gt;}&lt;br /&gt;//用來從queue copy資料到user space&lt;br /&gt;static int delete_queue(unsigned long arg)&lt;br /&gt;{&lt;br /&gt;if(head == tail) {&lt;br /&gt;goto empty;&lt;br /&gt;} else {&lt;br /&gt;tail = (tail + 1) % MAXQUEUE;&lt;br /&gt;&lt;br /&gt;printk("delete queue[%d].axies_data %04x %04x %04x %04x %04x %04x %04x\n", tail,&lt;br /&gt;  queue[tail].axies_data[0],queue[tail].axies_data[1],queue[tail].axies_data[2],&lt;br /&gt;queue[tail].axies_data[3],queue[tail].axies_data[4],queue[tail].axies_data[5],&lt;br /&gt;queue[tail].axies_data[6]);&lt;br /&gt;if(copy_to_user((unsigned int *)arg, queue[tail].axies_data, sizeof(u32)*7 )) {&lt;br /&gt;printk("error copy_to_user\n");&lt;br /&gt;return -EFAULT;&lt;br /&gt;}&lt;br /&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;empty:&lt;br /&gt;printk("New data have not been coming yet..\n");&lt;br /&gt;return -1;&lt;br /&gt;}&lt;br /&gt;//ioctl function可以從user space接收cmd，並且依據command做必要的行為，&lt;br /&gt;//arg是從user space傳下來的引數，可以傳一個整數下來，或者是傳一個指標下來。&lt;br /&gt;static int asus_mt_ioctl(struct inode *inode, struct file *file,&lt;br /&gt;                           unsigned int cmd, unsigned long arg)&lt;br /&gt;{&lt;br /&gt;ready = 0;&lt;br /&gt;//wait_event_interruptible(wait, ready);&lt;br /&gt;printk("asus_mt...ioctl\n");&lt;br /&gt;//printk("cmd = %d\n", cmd);&lt;br /&gt;//cli();&lt;br /&gt;//if(down_interruptible(&amp;amp;cosem))&lt;br /&gt;// return -ERESTARTSYS;&lt;br /&gt;switch(cmd){&lt;br /&gt;&lt;br /&gt;case 0:&lt;br /&gt;printk("delete queue\n");&lt;br /&gt;delete_queue(arg);&lt;br /&gt;break;&lt;br /&gt;case 1:&lt;br /&gt;printk("query if queue has data\n");&lt;br /&gt;if(head == tail)&lt;br /&gt;*(unsigned int*)arg = (unsigned int)0;&lt;br /&gt;else&lt;br /&gt;*(unsigned int*)arg = (unsigned int)1;&lt;br /&gt;break;&lt;br /&gt;//default:&lt;br /&gt;// return -EFAULTr&lt;br /&gt;}&lt;br /&gt;//up(&amp;amp;cosem);&lt;br /&gt;//sti();&lt;br /&gt;printk("reading success asus_mt_ioctl\n");&lt;br /&gt;return 0;&lt;br /&gt;}&lt;br /&gt;//open在這邊沒有實做&lt;br /&gt;static int asus_mt_open(struct inode *inode, struct file *file)&lt;br /&gt;{&lt;br /&gt;/*struct AsTouch_usb *dev;&lt;br /&gt;&lt;br /&gt;dev = container_of(inode-&amp;gt;i_cdev, struct AsTouch_usb, cdev);&lt;br /&gt;&lt;br /&gt;file-&amp;gt;private_data = dev;&lt;br /&gt;*/&lt;br /&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//release也是沒有實做&lt;br /&gt;static int asus_mt_release(struct inode *inode, struct file *file)&lt;br /&gt;{}&lt;br /&gt;//我們如果要實做檔案的operation就是實做在這個struct裡&lt;br /&gt;static struct file_operations asus_mt_fops = {&lt;br /&gt;     .owner = THIS_MODULE,&lt;br /&gt;     .ioctl = asus_mt_ioctl,&lt;br /&gt;     .open = asus_mt_open,&lt;br /&gt;     .release = asus_mt_release,&lt;br /&gt;};&lt;br /&gt;//當我們實做urb時，就要把下面這個irq call back函式填入urb的complete function欄位，&lt;br /&gt;//接著呼叫usb_submit_urb後，若是有report data進來，就會透過這個function把urb丟進來，&lt;br /&gt;//資料就在下面AsTouch-&amp;gt;data這個欄位。&lt;br /&gt;static void AsusTsUsb_irq(struct urb *urb)&lt;br /&gt;{&lt;br /&gt;printk("%s: that's ok\n", __FUNCTION__ );&lt;br /&gt;struct AsTouch_usb *AsTouch = urb-&amp;gt;context;&lt;br /&gt;int retval;&lt;br /&gt;unsigned char* data = AsTouch-&amp;gt;data;&lt;br /&gt;//下面這邊做的就是一些很routine的判斷。&lt;br /&gt;switch (urb-&amp;gt;status) {&lt;br /&gt;case 0:&lt;br /&gt;// success&lt;br /&gt;break;&lt;br /&gt;case -ETIME:&lt;br /&gt;// this urb is timing out&lt;br /&gt;dbg("%s - urb timed out - was the device unplugged?",&lt;br /&gt;   __FUNCTION__);&lt;br /&gt;return;&lt;br /&gt;case -ECONNRESET:&lt;br /&gt;case -ENOENT:&lt;br /&gt;case -ESHUTDOWN:&lt;br /&gt;return;&lt;br /&gt;default:&lt;br /&gt;goto resubmit;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*if( !(data[3] | 0x00) ) {&lt;br /&gt;if(down_interruptible(&amp;amp;cosem))&lt;br /&gt;return -ERESTARTSYS;&lt;br /&gt;}*/&lt;br /&gt;//這邊要把資料還原&lt;br /&gt;if( !(data[3] | 0x00) ) {&lt;br /&gt;//printk("data[3] == 0x00\n");&lt;br /&gt;axies_data[0] = data[0];&lt;br /&gt;/* Initialize Z1 */&lt;br /&gt;axies_data[1] = ( data[2] &amp;lt;&amp;lt; 8 ) | data[1];&lt;br /&gt;/* Initialize X1 */&lt;br /&gt;axies_data[2] = ( data[5] &amp;lt;&amp;lt; 8 ) | data[4];&lt;br /&gt;/* Initialize Y1 */&lt;br /&gt;axies_data[3] = ( data[7] &amp;lt;&amp;lt; 8 ) | data[6];&lt;br /&gt;}&lt;br /&gt;else {&lt;br /&gt;//printk("data[3] == 0x01\n");&lt;br /&gt;/* Initialize Z2*/&lt;br /&gt;axies_data[4] = ( data[2] &amp;lt;&amp;lt; 8 ) | data[1];&lt;br /&gt;/* Initialize X2 */&lt;br /&gt;axies_data[5] = ( data[5] &amp;lt;&amp;lt; 8 ) &amp;amp; 0x0fff | data[4];&lt;br /&gt;/* Initialize Y2 */&lt;br /&gt;axies_data[6] = ( data[7] &amp;lt;&amp;lt; 8 ) &amp;amp; 0x0fff | data[6];&lt;br /&gt;&lt;br /&gt;//printk("axies_data = On=%04x z1=%04x x1=%04x y1=%04x z2=%04x x2=%04x y2=%04x \n", axies_data[0],\&lt;br /&gt; axies_data[1],axies_data[2],axies_data[3],\&lt;br /&gt; axies_data[4],axies_data[5],axies_data[6]);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;if( data[3] | 0x00 ) {&lt;br /&gt;// if(down_interruptible(&amp;amp;cosem))&lt;br /&gt;//  return -ERESTARTSYS;&lt;br /&gt;insert_queue();&lt;br /&gt;ready = ready + 1;&lt;br /&gt;//wake_up_interruptible(&amp;amp;wait);&lt;br /&gt;// up(&amp;amp;cosem);&lt;br /&gt;//int rep = 0;&lt;br /&gt;/*&lt;br /&gt;for( ; rep &amp;lt; 7; rep++ ) {&lt;br /&gt;axies_data[rep] &amp;amp;= 0x00000000;&lt;br /&gt;}&lt;br /&gt;*/&lt;br /&gt;}&lt;br /&gt;//printk("%s:urb-&amp;gt;actual_length = %d\n", __FUNCTION__, urb-&amp;gt;actual_length );&lt;br /&gt;resubmit:&lt;br /&gt;retval = usb_submit_urb(urb, GFP_ATOMIC);&lt;br /&gt;if (retval)&lt;br /&gt;err("%s - usb_submit_urb failed with result: %d",&lt;br /&gt;   __FUNCTION__, retval);&lt;br /&gt;}&lt;br /&gt;//open這個function其實也用不到，你看裡面的code就知道，&lt;br /&gt;//原本預設上是等user space來open我們的device才會submit urb，&lt;br /&gt;//但，這邊為了debug方便，在probe的時候就submit urb了。&lt;br /&gt;//所以代表，只要device和driver兩個有mapping起來就會submit urb，&lt;br /&gt;//預設上是不能這樣做，會造成系統資源的浪費，irq一直進來。&lt;br /&gt;//一直處理一些用不到的資料。&lt;br /&gt;static int AsusTsUsb_open(struct input_dev *input)&lt;br /&gt;{&lt;br /&gt;printk("%s: that's ok\n", __FUNCTION__ );&lt;br /&gt;/*&lt;br /&gt;struct AsTouch_usb *AsTouch = input-&amp;gt;private;&lt;br /&gt;&lt;br /&gt;AsTouch-&amp;gt;irq-&amp;gt;dev = AsTouch-&amp;gt;udev;&lt;br /&gt;&lt;br /&gt;if (usb_submit_urb(AsTouch-&amp;gt;irq, GFP_ATOMIC))&lt;br /&gt;return -EIO;&lt;br /&gt;&lt;br /&gt;return 0;&lt;br /&gt;*/&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void AsusTsUsb_close(struct input_dev *input)&lt;br /&gt;{&lt;br /&gt;//struct AsTouch_usb *AsTouch = input-&amp;gt;private;&lt;br /&gt;&lt;br /&gt;//usb_kill_urb(AsTouch-&amp;gt;irq);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static int AsusTsUsb_probe(struct usb_interface *intf, const struct usb_device_id *id)&lt;br /&gt;{&lt;br /&gt;//probe就是重頭戲了，雖然下面都是每個usb interface driver要做的routine工作。&lt;br /&gt;int ret = 0;&lt;br /&gt;struct device *temp_class;&lt;br /&gt;printk("%s: that's ok\n", __FUNCTION__ );&lt;br /&gt;struct usb_device *dev = interface_to_usbdev(intf);&lt;br /&gt;struct usb_host_interface *interface;&lt;br /&gt;struct usb_endpoint_descriptor *endpoint;&lt;br /&gt;struct AsTouch_usb *astouch;&lt;br /&gt;int pipe, maxp;&lt;br /&gt;//init_waitqueue_head(&amp;amp;wait);&lt;br /&gt;//register_chrdev做的就是向系統申請一個major number並且命名為ASUS_MT_STRING，&lt;br /&gt;//同時把asus_mt_fops送進去，這樣我們的ioctl就可以被user space存取了。&lt;br /&gt;//但記得這邊還不會在/dev底下出現asus_mt，要經過class_create和device_create後&lt;br /&gt;//node才會跑出來。對這邊如果有問題可以參考ldd ch3的那個char driver。&lt;br /&gt;asus_mt_major = register_chrdev(0, ASUS_MT_STRING,&lt;br /&gt;&amp;amp;asus_mt_fops);&lt;br /&gt;&lt;br /&gt;if( asus_mt_major &amp;lt; 0 )&lt;br /&gt;{&lt;br /&gt;printk("Unable to get a major for asus multi-touch driver!\n");&lt;br /&gt;return asus_mt_major;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;asus_mt_class = class_create(THIS_MODULE, ASUS_MT_STRING);&lt;br /&gt;  &lt;br /&gt;if (IS_ERR(asus_mt_class)) {&lt;br /&gt;             printk(KERN_ERR "Error creating Asus Multi-Touch class.\n");&lt;br /&gt;             ret = PTR_ERR(asus_mt_class);&lt;br /&gt;             goto err_out1;&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;temp_class = device_create(asus_mt_class, NULL,&lt;br /&gt;                                MKDEV(asus_mt_major, 0),&lt;br /&gt;                                NULL, ASUS_MT_STRING);&lt;br /&gt;  &lt;br /&gt;if (IS_ERR(temp_class)) {&lt;br /&gt;             printk(KERN_ERR "Error creating Asus Multi-Touch class device.\n");&lt;br /&gt;             ret = PTR_ERR(temp_class);&lt;br /&gt;             goto err_out2;&lt;br /&gt;     }&lt;br /&gt;interface = intf-&amp;gt;cur_altsetting;&lt;br /&gt;&lt;br /&gt;if (interface-&amp;gt;desc.bNumEndpoints != 1)&lt;br /&gt;return -ENODEV;&lt;br /&gt;&lt;br /&gt;endpoint = &amp;amp;interface-&amp;gt;endpoint[0].desc;&lt;br /&gt;if (!usb_endpoint_is_int_in(endpoint))&lt;br /&gt;return -ENODEV;&lt;br /&gt;&lt;br /&gt;pipe = usb_rcvintpipe(dev, endpoint-&amp;gt;bEndpointAddress);&lt;br /&gt;maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));&lt;br /&gt;&lt;br /&gt;astouch = kzalloc(sizeof(struct AsTouch_usb), GFP_KERNEL);&lt;br /&gt;astouch-&amp;gt;data = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &amp;amp;astouch-&amp;gt;data_dma);&lt;br /&gt;if (!astouch-&amp;gt;data)&lt;br /&gt;goto fail;&lt;br /&gt;&lt;br /&gt;astouch-&amp;gt;irq = usb_alloc_urb(0, GFP_KERNEL);&lt;br /&gt;if (!astouch-&amp;gt;irq)&lt;br /&gt;goto fail;&lt;br /&gt;&lt;br /&gt;astouch-&amp;gt;udev = dev;&lt;br /&gt;&lt;br /&gt;if (dev-&amp;gt;manufacturer)&lt;br /&gt;strlcpy(astouch-&amp;gt;name, dev-&amp;gt;manufacturer, sizeof(astouch-&amp;gt;name));&lt;br /&gt;&lt;br /&gt;if (dev-&amp;gt;product) {&lt;br /&gt;if (dev-&amp;gt;manufacturer)&lt;br /&gt;strlcat(astouch-&amp;gt;name, " ", sizeof(astouch-&amp;gt;name));&lt;br /&gt;strlcat(astouch-&amp;gt;name, dev-&amp;gt;product, sizeof(astouch-&amp;gt;name));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (!strlen(astouch-&amp;gt;name))&lt;br /&gt;snprintf(astouch-&amp;gt;name, sizeof(astouch-&amp;gt;name),&lt;br /&gt; "ASUS USB Multi-Touch Mouse %04x:%04x",&lt;br /&gt; le16_to_cpu(dev-&amp;gt;descriptor.idVendor),&lt;br /&gt; le16_to_cpu(dev-&amp;gt;descriptor.idProduct));&lt;br /&gt;&lt;br /&gt;usb_make_path(dev, astouch-&amp;gt;phys, sizeof(astouch-&amp;gt;phys));&lt;br /&gt;strlcat(astouch-&amp;gt;phys, "/input0", sizeof(astouch-&amp;gt;phys));&lt;br /&gt;//看到了吧，這邊的AsusTsUsb_irq就是那個要被填到complete function的callback function&lt;br /&gt;usb_fill_int_urb(astouch-&amp;gt;irq, dev, pipe, astouch-&amp;gt;data,&lt;br /&gt; (maxp &amp;gt; 8 ? 8 : maxp),&lt;br /&gt; AsusTsUsb_irq, astouch, endpoint-&amp;gt;bInterval);&lt;br /&gt;astouch-&amp;gt;irq-&amp;gt;transfer_dma = astouch-&amp;gt;data_dma;&lt;br /&gt;astouch-&amp;gt;irq-&amp;gt;transfer_flags |= URB_NO_TRANSFER_DMA_MAP;&lt;br /&gt;usb_set_intfdata(intf, astouch);&lt;br /&gt;//在這之前就把urb的資料根據傳進來的interface作好，然後接下來把urb submit出去，&lt;br /&gt;//就可以等著接收report data。&lt;br /&gt;astouch-&amp;gt;irq-&amp;gt;dev = astouch-&amp;gt;udev;&lt;br /&gt;if (usb_submit_urb(astouch-&amp;gt;irq, GFP_ATOMIC))&lt;br /&gt;return -EIO;&lt;br /&gt;&lt;br /&gt;return 0;&lt;br /&gt;&lt;br /&gt;err_out2:&lt;br /&gt;     class_destroy(asus_mt_class);&lt;br /&gt;err_out1:&lt;br /&gt;     unregister_chrdev(asus_mt_major, ASUS_MT_STRING);&lt;br /&gt;     return ret;&lt;br /&gt;&lt;br /&gt;fail: usb_buffer_free(dev, 8, astouch-&amp;gt;data, astouch-&amp;gt;data_dma);&lt;br /&gt;kfree(astouch);&lt;br /&gt;return -ENOMEM;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;//這邊的disconnect裡面做的不外呼把/dev底下的asus_mt節點給摧毀掉，還有把urb給kill掉。&lt;br /&gt;//但何時會執行disconnect?? 原來是在usb device設備被拔除的時候，你可以試試看把usb&lt;br /&gt;//touch panel的線拔除，此時/dev/asus_mt也會跟著不見。也就不能在對/dev/asus_mt做&lt;br /&gt;//read, write了。&lt;br /&gt;static void AsusTsUsb_disconnect(struct usb_interface *intf)&lt;br /&gt;{&lt;br /&gt;struct AsTouch_usb *AsTouch = usb_get_intfdata(intf);&lt;br /&gt;printk("%s\n", __FUNCTION__ );&lt;br /&gt;device_destroy(asus_mt_class, MKDEV(asus_mt_major, 0));&lt;br /&gt;     class_destroy(asus_mt_class);&lt;br /&gt;     unregister_chrdev(asus_mt_major, ASUS_MT_STRING);&lt;br /&gt;usb_set_intfdata(intf, NULL);&lt;br /&gt;if (AsTouch) {&lt;br /&gt;usb_kill_urb(AsTouch-&amp;gt;irq);&lt;br /&gt;//input_unregister_device(AsTouch-&amp;gt;input);&lt;br /&gt;usb_free_urb(AsTouch-&amp;gt;irq);&lt;br /&gt;usb_buffer_free(interface_to_usbdev(intf), 8,&lt;br /&gt; AsTouch-&amp;gt;data, AsTouch-&amp;gt;data_dma);&lt;br /&gt;kfree(AsTouch);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;MODULE_DEVICE_TABLE(usb, AsusTsUsb_devices);&lt;br /&gt;&lt;br /&gt;static struct usb_driver AsusTsUsb_driver = {&lt;br /&gt;.name  = "AsusTsUsb",&lt;br /&gt;.probe  = AsusTsUsb_probe,&lt;br /&gt;.disconnect = AsusTsUsb_disconnect,&lt;br /&gt;.id_table = AsusTsUsb_devices,&lt;br /&gt;};&lt;br /&gt;//一開始driver被insert時就從這邊run起。&lt;br /&gt;static int __init AsusTsUsb_init(void)&lt;br /&gt;{&lt;br /&gt;printk("%s - called", __FUNCTION__);&lt;br /&gt;return usb_register(&amp;amp;AsusTsUsb_driver);&lt;br /&gt;}&lt;br /&gt;//rmmod時就會從這邊run完結束，所以剛剛在disconnect裡的node銷毀，不能放在這邊run，&lt;br /&gt;//要不然如果拔掉usb touch panel則/dev/asus_mt還會存在，若是user space程式對&lt;br /&gt;//他做ioctl問題就大了。&lt;br /&gt;static void __exit AsusTsUsb_exit(void)&lt;br /&gt;{&lt;br /&gt;printk("%s - called", __FUNCTION__);&lt;br /&gt;usb_deregister(&amp;amp;AsusTsUsb_driver);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;module_init(AsusTsUsb_init);&lt;br /&gt;module_exit(AsusTsUsb_exit);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;恩，接著看ap層要怎麼寫，這是從clutter ap擷取出來的一段code。&lt;br /&gt;&lt;pre class="prettyprint lang-cpp"&gt;&lt;br /&gt;g_signal_connect (timeline, "new-frame", G_CALLBACK (GestureRecognition), actor);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;這裡面的GestureRecognition就是clutter的callback function，他可以設定callback的timer，時間長短。這裏為什麼要放在call back裡面做我們的讀取function呢?如果你在gui的其他地方做自己的while loop去讀取ioctl，會造成gui掛掉不會更新的情形，因為gui本身也是一組while loop，你不能在gui的讀取while loop結束後，或者是還沒結束前就進入你的while loop，這樣都會造成gui沒辦法更新的現象，因為程式都一直在你的wile loop裡邊run。所以要把while loop內的東西，放到timer的call back函式裡頭做。而原本ioctl裡邊用的wait_event_interruptible也不能用，因為，他讀不到資料就會去睡覺，這樣你的gui要等到有資料進來才會更新。沒資料進來，若是切到別的視窗再回來，就會畫面一片空白，因為沒有資料來醒她。&lt;br /&gt;&lt;br /&gt;所以這邊ioctl cmd=1就代表詢問有無資料，如果head==tail則代表queue為空，所以return 0;GestureRecognition收到後就會結束，若是head!=tail則回傳1，while loop接著下cmd=0一直讀，直到queue data被讀完為止。所以signal call back的速度可以不用設的太快，因為這邊是low speed device，如果這邊是high speed device，就要設快點，要不然不久queue就滿了，資料就truncate掉。當然queue的大小也會決定資料的準確率，但是需要越完整的資料，就需要更大的queue。&lt;br /&gt;&lt;br /&gt;嗯嗯，接下來看GestureRecognition是怎麼寫的：&lt;br /&gt;&lt;pre class="prettyprint lang-cpp"&gt;&lt;br /&gt;void GestureRecognition(ClutterTimeline *timeline,&lt;br /&gt;                gint frame_num,&lt;br /&gt;                gpointer data)&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;  int fd = open("/dev/asus_mt", O_RDONLY);&lt;br /&gt;printf("Enter GestureRecognition\n");&lt;br /&gt;&lt;br /&gt;CHiddenWindow PacketProcess;&lt;br /&gt;&lt;br /&gt;static unsigned int array[7];&lt;br /&gt;if( fd == -1 )&lt;br /&gt;{&lt;br /&gt;printf("read file error\n");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int i;&lt;br /&gt;for( i = 0 ; i &amp;lt; 7 ; i++ )&lt;br /&gt;{&lt;br /&gt;array[i] = 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;unsigned int check = 0;&lt;br /&gt;     //確定queue有data在開始抓&lt;br /&gt;while((ioctl(fd,1,&amp;amp;check) != -1) &amp;amp;&amp;amp; check == 1) {&lt;br /&gt;             //開始把data從queue裡一個個讀進array&lt;br /&gt;if (ioctl(fd,0,array) == -1) {&lt;br /&gt;printf("read ioctl array error\n");&lt;br /&gt;}else {&lt;br /&gt;//下面這邊就是去做gesture的判斷，裡面用了一堆統計的方法&lt;br /&gt;             //這邊就不列出來了&lt;br /&gt;PacketProcess.Indicate(array);&lt;br /&gt;PacketProcess.MonitorThread();&lt;br /&gt;  &lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;close(fd);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;記得在用open file和ioctl之前要先include下面的.h：&lt;br /&gt;#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;#include &amp;lt;sys/ioctl.h&amp;gt;&lt;br /&gt;&lt;br /&gt;下面再給一張完整的結構圖：&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_r6LKRJP8V4w/Sfe-lqwo88I/AAAAAAAAAKA/TWiRi0zxlf4/s1600-h/readScenario.JPG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 298px;" src="http://4.bp.blogspot.com/_r6LKRJP8V4w/Sfe-lqwo88I/AAAAAAAAAKA/TWiRi0zxlf4/s400/readScenario.JPG" alt="" id="BLOGGER_PHOTO_ID_5329938238359008194" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-9111792704495404894?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/9111792704495404894/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=9111792704495404894' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/9111792704495404894'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/9111792704495404894'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/04/multi-touch-demo-on-t91-with-intel.html' title='Multi-Touch Demo on T91 with Intel fantastic Moblin'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_r6LKRJP8V4w/SfUqr7giJsI/AAAAAAAAAJw/KfsF2gbawMk/s72-c/traditional+touch.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-7879301993024569760</id><published>2009-03-25T00:36:00.000-07:00</published><updated>2009-03-25T01:22:01.063-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><title type='text'>linux ubuntu下面解析度設定的問題</title><content type='html'>今天早上一開機發現login畫面歪了一邊不大對。&lt;br /&gt;&lt;br /&gt;登入後，Xwindow的桌面也是歪了 一邊，用LCD的自動調整也沒有用。當下覺得是resolution的問題。&lt;br /&gt;&lt;br /&gt;在系統-&gt;偏好設定-&gt;螢幕解析度找到了設定的地方。&lt;br /&gt;&lt;br /&gt;很奇怪的是他的解析度只支援到800X600。設了/etx/X11/xorg.conf裡面的SUBSECTION Display&lt;br /&gt;&lt;br /&gt;Mode "1024x768"也沒有用。我就拿了一顆放在旁邊沒用的17吋螢幕來試試看。線接好以後重開&lt;br /&gt;&lt;br /&gt;機，1024x768竟然就跑出來了。當下直接接上原本的螢幕，結果是可以work的。聽同事說，螢幕&lt;br /&gt;&lt;br /&gt;有兩條I square C的線，可以獲得一些相關的資訊，得知螢幕的所支援的解析度還有vendor ID之類的。&lt;br /&gt;&lt;br /&gt;同時也有可能是driver上錯的緣故。所以一般VGA compatible的顯卡只支援到800x600。&lt;br /&gt;&lt;br /&gt;重開機後，他還是只抓到800x600，到最後我懶的弄了，就直接把解析度調成800x600。&lt;br /&gt;&lt;br /&gt;雖然問題沒有解決，在這個過程裡也學到了點東西，像：&lt;a href="http://www.ubuntu-tw.org/modules/newbb/viewtopic.php?viewmode=compact&amp;amp;topic_id=10382&amp;amp;forum=2"&gt;開機時到進入Xwindow的解析度是可以&lt;br /&gt;&lt;br /&gt;換的&lt;/a&gt;，其實就是把/boot/grub/menu.lst裡頭vmlinux那行加上vga=xxx，裡面也提到了&lt;a href="http://wiki.ubuntu.org.cn/index.php?title=UbuntuHelp:ChangeTTYResolution&amp;amp;variant=zh-hant"&gt;vga的值要&lt;br /&gt;&lt;br /&gt;怎麼設定&lt;/a&gt;。如果不小心設掛了，螢幕會告訴你超出頻率，這時候只要開機時按F9進入boot menu&lt;br /&gt;&lt;br /&gt;去拿掉vga=xxx就可以了。再來就是Xwindow設掛了以後，會沒辦法login進去，要在login時的選&lt;br /&gt;&lt;br /&gt;項裏把作業階段改成終端機安全模式，進入這裡面會有彩色的console，在shell底下打/usr/bin&lt;br /&gt;&lt;br /&gt;/gnome-display-properties，就可以叫出修改解析度的gui。還有在開機的時候按F9除了一般開&lt;br /&gt;&lt;br /&gt;機的選項，Ubuntu會提供另一個recovery的entry，這個entry提供了Xwindow的Fix, fdisk等的功&lt;br /&gt;&lt;br /&gt;能。&lt;br /&gt;&lt;br /&gt;參考:&lt;br /&gt;&lt;a href="http://www.ubuntu-tw.org/modules/newbb/viewtopic.php?topic_id=676"&gt;如何新增螢幕解析度&lt;/a&gt;&lt;br /&gt;&lt;a href="http://210.240.134.50/xoopx/modules/tadbook2/view.php?book_sn=5&amp;amp;bdsn=357"&gt;Xwindow顯示卡重新設定&lt;/a&gt;&lt;br /&gt;&lt;a href="http://phorum.vbird.org/viewtopic.php?t=27157"&gt;有關CRT的顯示頻率問題&lt;/a&gt;&lt;br /&gt;&lt;a href="http://210.240.134.50/xoopx/modules/tadbook2/view.php?book_sn=4&amp;amp;bdsn=181&amp;amp;op=fullscreen"&gt;Xwindow設定&lt;/a&gt;&lt;br /&gt;&lt;a href="http://xtiming.sourceforge.net/cgi-bin/xtiming.pl"&gt;XFree86 Modeline Generator&lt;/a&gt;  這個可以用來產生xorg.conf裡，Monitor所需要的modeline資訊，只需要輸入解析度和頻率就可以算出Modeline。&lt;br /&gt;&lt;a href="http://www.itkhl.com/Article/server/itkhl-21192.html"&gt;超出顯示頻率範圍&lt;/a&gt;&lt;br /&gt;&lt;a href="http://linux.vbird.org/linux_basic/0590xwindow.php#xserver_monitor"&gt;鳥哥私房菜之Xwindow簡易設定介紹&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.5dlinux.com/article/1/2007/linux_2797.html"&gt;進入Linux桌面屏幕偏移的解決&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ubuntu-tw.org/"&gt;Ubuntu正體中文站&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-7879301993024569760?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/7879301993024569760/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=7879301993024569760' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/7879301993024569760'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/7879301993024569760'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/03/linux-ubuntu.html' title='linux ubuntu下面解析度設定的問題'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-6682738439190158579</id><published>2009-03-11T08:28:00.000-07:00</published><updated>2009-05-06T00:38:38.232-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='生活'/><title type='text'>moblin course</title><content type='html'>今天是moblin training的第一天。&lt;br /&gt;&lt;br /&gt;早上大概介紹了一下要怎麼用MIC2 build image。還有扯了一下Sreadahead。&lt;br /&gt;&lt;br /&gt;和用boot chart以及boot graph分析開機時，各個module所花費的時間。&lt;br /&gt;&lt;br /&gt;還有如何更改grub boot menu開機選項，加入init=xxxx，然後就可以印出module花費時間。&lt;br /&gt;&lt;br /&gt;下午就是我比較感興趣的議題。&lt;br /&gt;&lt;br /&gt;包括了x86的ISA，其中介紹了幾個比較有趣的指令，至於詳細的指令名稱我記不住。&lt;br /&gt;&lt;br /&gt;只記得他的功能。如計算某個register內為一的bit的個數，&lt;br /&gt;&lt;br /&gt;這個我記得洋芋片之前在面試的時候，聯發科好像有問過，並且要求複雜度要最低。&lt;br /&gt;&lt;br /&gt;接著還有介紹spin lock的原理，據說是用compare and exchange指令所做到的，&lt;br /&gt;&lt;br /&gt;且只有compare and exchange指令才能做到atomic transaction，其他如:semaphore, down,...etc.&lt;br /&gt;&lt;br /&gt;的用法和他不一樣。還有一個fence，可讓資料的傳輸按照我們的意思，不會不按照順序傳。&lt;br /&gt;&lt;br /&gt;最後還講了MESI，Qi Wang還說如果要懂多核MESI非懂不可。&lt;br /&gt;&lt;br /&gt;結束了我還問了一下IRQ運作的詳細原理，Qi Wang還是不厭其煩詳細回答，真是不須此行。&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;a href="http://218.98.38.18/weijiyuanli/chapter2/c1-2-4-5.htm#"&gt;微型計算機原理之MESI協議&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://cst.mi.fu-berlin.de/teaching/SS05/19515-V/MESI-Protokoll-animation.mht"&gt;animation of the MESI protocol&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;用Qi Wang的說法蠻好理解的。&lt;span style="color: rgb(255, 0, 0);"&gt;MESI其實就是在做multiprocessor之間的coherency&lt;/span&gt;。&lt;br /&gt;&lt;br /&gt;假設有ABC三個processor，以A為例，有Read &amp;amp; Write兩種狀況。這兩種又分別有miss &amp;amp; hit&lt;br /&gt;&lt;br /&gt;兩種情形。如果是hit則要考量自己是Modified, Excluded, Shared三種情形。如果miss則也要考慮&lt;br /&gt;&lt;br /&gt;前面那三種情形，只是發生在別的處理器身上。因為A自己沒有data。總共就是2x2x3=12種情況。&lt;br /&gt;&lt;br /&gt;再根據情況下去看，當下需要做什麼樣的動作，才可以更新(或讀取)data而不影響到一致性的問題`。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-6682738439190158579?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/6682738439190158579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=6682738439190158579' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/6682738439190158579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/6682738439190158579'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/03/moblin-course.html' title='moblin course'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-3526566871249135088</id><published>2009-03-03T21:04:00.000-08:00</published><updated>2009-03-03T22:46:36.366-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='健康'/><title type='text'>尿液逆流(VUR,vesicoureteral reflux)的原理和治療</title><content type='html'>&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;span style="color: rgb(255, 0, 0);font-size:180%;" &gt;尿液逆流(VUR)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;以下是網路資料的整理，因為小孩子有這些問題，&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;天下父母心，&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;所以我做了一個survey，有需要的人可以看看。&lt;br /&gt;&lt;br /&gt;以下分為幾個重點:&lt;span style="color: rgb(255, 153, 0);"&gt;原理&lt;/span&gt;，&lt;span style="color: rgb(255, 153, 0);"&gt;分類&lt;/span&gt;，&lt;span style="color: rgb(255, 153, 0);"&gt;診斷方式&lt;/span&gt;，&lt;span style="color: rgb(255, 153, 0);"&gt;治療方式&lt;/span&gt;，&lt;span style="color: rgb(255, 153, 0);"&gt;症狀&lt;/span&gt;，&lt;span style="color: rgb(255, 153, 0);"&gt;照顧要點&lt;/span&gt;。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 153, 0);font-size:130%;" &gt;原理&lt;/span&gt;&lt;br /&gt;VUR的可分為原發性 (Primary) 及次發性 (secondary)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);font-family:arial;font-size:100%;"  &gt;原發&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;性逆流&lt;a href="http://homepage.vghtpe.gov.tw/%7Epeds/gu/vur3.htm"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;[1]&lt;/span&gt;&lt;/a&gt;:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);font-family:arial;font-size:100%;"  &gt;在了解膀胱輸尿管逆流之前，首先必須了解一個具備 健全的抗逆流之膀胱輸尿管系統。輸尿管進入膀胱以前之輸尿管肌層為螺旋走向肌肉纖維，負責輸尿管之蠕動及排尿勳作，進入膀胱部份的輸尿管肌層則屬於縱走肌 肉纖維，為配合輸尿管開口排尿動作，而縱走肌纖維收縮，此時膀胱內輸尿管長度隨之縮短，而輸尿管開口位置同時被拉往外側，而輸尿管口徑被橫向拉開而因此增 大以利尿液能順利運送至膀胱內。反之，在靜止狀態下，膀胱內輸尿管之縱走肌纖維呈放鬆狀態，長度變長，管徑變細，輸尿管開口位置又回復到內側，此時若膀胱 內所含之尿液容量及壓力亦足以使膀胱之表層粘膜壓迫輸尿管以防止尿液往上逆流。若因此一抗逆流系統所發生缺失造成之尿液逆流為原發性逆流。&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);font-family:arial;font-size:100%;"  &gt;次發性&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;逆流&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-size:100%;"&gt;&lt;a href="http://homepage.vghtpe.gov.tw/%7Epeds/gu/vur3.htm"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;[1]&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;：&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;次發性膀胱輸尿管逆流則常見神經性膀胱功能失常 (neurogenic bladder)、異位輸尿管 (ectopic ureter)、後尿道瓣膜 (posterior urethral valve)等。&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="color: rgb(255, 153, 0);"&gt;分類&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;p  style="color: rgb(0, 0, 0);font-family:arial;"&gt;&lt;span style="font-size:100%;"&gt;如下圖膀胱輸尿道迴流，可分為五級:&lt;a href="http://www.fever.com.tw/uti.htm"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;[4]&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;img style="width: 350px; height: 179px;" src="http://www.fever.com.tw/guref.jpg" width="350" height="179" /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p  style="color: rgb(0, 0, 0);font-family:arial;"&gt;&lt;span style="font-size:100%;"&gt;第一級迴流:  尿液只迴流到輸尿管，輸尿管未擴大。&lt;/span&gt;&lt;/p&gt; &lt;p  style="color: rgb(0, 0, 0);font-family:arial;"&gt;&lt;span style="font-size:100%;"&gt;第二級迴流:  尿液迴流到輸尿管、腎盂及腎盞，但仍然沒有管道擴大的現像。腎盞穹窿的形狀仍維持正常。 &lt;/span&gt;&lt;/p&gt; &lt;p  style="color: rgb(0, 0, 0);font-family:arial;"&gt;&lt;span style="font-size:100%;"&gt;第三級迴流: 迴流的尿液導致輸尿管、腎盂及腎盞的輕微擴大，腎盞穹窿角度輕微變鈍或是不變。&lt;/span&gt;&lt;/p&gt; &lt;p  style="color: rgb(0, 0, 0);font-family:arial;"&gt;&lt;span style="font-size:100%;"&gt;第四級迴流: 輸尿管中度擴大及扭曲，腎盂及腎盞中度的擴大，腎盞穹窿的銳角完全變鈍，但大部份的腎乳壓跡還存在。&lt;/span&gt;&lt;/p&gt; &lt;p  style="color: rgb(0, 0, 0);font-family:arial;"&gt;&lt;span style="font-size:100%;"&gt;第五度迴流: 輸尿管明顯擴大及扭曲，腎盂及腎盞也明顯擴大，大部份腎乳頭壓跡都已經完全的消失了。&lt;/span&gt;&lt;/p&gt;&lt;span style="color: rgb(255, 153, 0);font-family:arial;font-size:130%;"  &gt;診斷方式&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;a href="http://homepage.vghtpe.gov.tw/%7Epeds/gu/vur3.htm"&gt;[1]&lt;/a&gt;&lt;br /&gt;&lt;/span&gt; &lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);font-family:arial;" &gt;1. 膀胱攝影(VCUG)&lt;/span&gt;&lt;span style="font-family:arial;"&gt; &lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);font-family:arial;" &gt;2. 超音波&lt;/span&gt;&lt;span style="font-family:arial;"&gt; &lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);font-family:arial;" &gt;3. 核子醫學檢查(DMSA)&lt;/span&gt;&lt;span style="font-family:arial;"&gt; &lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);font-family:arial;" &gt;4. 靜脈尿路攝影(IVU)&lt;/span&gt;&lt;span style="font-family:arial;"&gt; &lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);font-family:arial;" &gt;5. 膀胱鏡&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);font-family:arial;" &gt;1. 膀胱攝影(VCUG)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;診斷 VUR 最重要的工具是 voiding cystourethrogram (VCUG)。這種放射線檢查是把顯影劑以導尿管注入膀胱，待病人排尿時照相，即可觀察逆流的情形。根據 VCUG之結果，可將VUR之嚴重度分為五級，級數越高，逆流越嚴重。VCUG 可安排在抗生素治療二至四週後，此時膀胱的發炎狀態已消退，檢查較安全，也較準確。VCUG也可診斷雙套集尿系統 (duplex system)、憩室等膀胱方面的異常。&lt;/span&gt;&lt;br /&gt;&lt;img style="font-family: arial;" src="http://homepage.vghtpe.gov.tw/%7Epeds/image/vur.jpg" /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;膀胱攝影顯示兩側逆流&lt;/span&gt;&lt;br /&gt;&lt;img style="font-family: arial;" src="http://homepage.vghtpe.gov.tw/%7Epeds/image/vur2.jpg" /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;嚴重度分為五級 &lt;/span&gt;&lt;p  style="font-family:arial;"&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;2. 超音波&lt;/span&gt;&lt;br /&gt;超音波檢查可發現水腎或輸尿管擴大，但逆流程度不嚴重者，超音波檢查結果可能是正常的。有經驗的操作者，或許可顯示逆流的現象，但超音波僅是很好的篩檢，並不是診斷VUR的理想工具。&lt;/p&gt;&lt;p  style="font-family:arial;"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;  3. 核子醫學檢查(DMSA)&lt;/span&gt;&lt;br /&gt;核子醫學檢查可分為幾方面。核醫膀胱造影是類似 VCUG 的檢查，其好處是放射劑量比傳統 VCUG低，但成像較不清楚，難以據此分級，也無法詳細觀察細微的異常。 Tc 99m-dimercaptosuccinic acid (DMSA) renal scan 可檢查出腎臟的疤痕，根據受損情形，可估計 VUR 對腎之長期影響，故 DSMA 是相當重要的。&lt;br /&gt;&lt;img src="http://homepage.vghtpe.gov.tw/%7Epeds/image/vur3.jpg" /&gt;&lt;br /&gt;核子醫學檢查顯示左腎受損 &lt;/p&gt;&lt;p  style="font-family:arial;"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;  4. 靜脈尿路攝影(IVU)&lt;/span&gt;&lt;br /&gt;靜脈尿路攝影 (intravenous urography，IVU)，又稱腎盂攝影，對診斷 VCUG 幫助不大。幼兒的 IVU 除了成像不清楚外，輻射劑量也必須考慮。在較大兒童，IVU 也可觀察腎的疤痕，其敏感度僅次於 DMSA。&lt;/p&gt;&lt;p  style="font-family:arial;"&gt;  &lt;span style="color: rgb(255, 0, 0);"&gt;5. 膀胱鏡&lt;/span&gt;&lt;br /&gt;可直接觀察輸尿管開口的外觀，評估VUR的程度。正常輸尿管開口的外觀像一眉新月，嚴重逆流者像高爾夫球洞。不過膀胱鏡檢查算是侵犯性的檢查，在兒童必須全身麻醉才能進行。&lt;/p&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 153, 0);font-family:arial;font-size:130%;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;span style="color: rgb(255, 153, 0);font-size:130%;" &gt;治療方式&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;&lt;br /&gt;內科療法(服用抗生素)&lt;/span&gt;&lt;a style="color: rgb(51, 51, 255);" href="http://www.mmh.org.tw/taitam/pedia/education/%E8%AA%8D%E8%AD%98%E8%86%80%E8%83%B1%E8%BC%B8%E5%B0%BF%E7%AE%A1%E9%80%86%E6%B5%81%E7%97%87.html"&gt;[3]&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:標楷體;font-size:100%;"  &gt;由於泌尿道感染會損傷腎臟, 造成腎結痂, 腎萎縮, 導致腎衰竭, 所以, 要避免泌尿道感染, 減少腎臟更進一步的損害. 兒童患者隨著年齡的增長, 膀胱輸尿管迴流症的級數會慢慢降低, 甚至在幾年後自動消失. 通常內科療法適用於第一,第二, 及第三級的迴流病人, 有時單側第四級迴流,且無反覆感染的病童也可以內科療法即可.&lt;br /&gt;&lt;br /&gt;由於白天排尿次數較頻繁, 細菌較不容易滋生, 在夜晚時, 尿液長時間留在膀胱, 細菌較易生長, 因此預防性的抗生素藥在睡前服用. 而使用的藥量是一般治療劑量的四分之一, 副作用非常小. 所以家長千萬不要怕麻煩或畏懼副作用, 而把藥物停掉.&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;span style="color: rgb(51, 204, 0);"&gt;&lt;br /&gt;&lt;br /&gt;外科療法(手術治療) 1.外科手術 2. 內視鏡藥物注射&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;原發性&lt;/span&gt;：&lt;br /&gt;膀胱內移植術&lt;a href="http://www.cgmh.com.tw/chldhos/intr/c4b60/index.htm#V"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;[2]&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;將下段輸尿管與膀胱分離&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:14;"&gt;&lt;span lang="EN-US"&gt;&lt;img style="width: 277px; height: 273px;" src="http://www.cgmh.com.tw/chldhos/intr/c4b60/index.files/image022.jpg" width="277" border="0" height="273" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;牽引輸尿管鑽入膀胱黏膜下層至對側新的開口&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:14;"&gt;&lt;span lang="EN-US"&gt;&lt;img style="width: 276px; height: 276px;" src="http://www.cgmh.com.tw/chldhos/intr/c4b60/index.files/image024.jpg" width="276" border="0" height="276" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;br /&gt;&lt;/span&gt;  &lt;p face="arial"&gt;&lt;a name="X"&gt;不必切開膀胱的抗尿液逆流手術〈膀胱外的肌肉修補術〉&lt;/a&gt;&lt;/p&gt;&lt;p style="font-family: arial;"&gt;&lt;a name="X"&gt;&lt;span  lang="EN-US" style="font-size:14;"&gt;&lt;img style="width: 316px; height: 337px;" src="http://www.cgmh.com.tw/chldhos/intr/c4b60/index.files/image031.jpg" width="316" border="0" height="337" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="font-family: arial;"&gt;&lt;a name="X"&gt;&lt;/a&gt;&lt;/p&gt;&lt;span  lang="EN-US" style="font-family:arial;"&gt;利用膀胱外的肌肉修補術延長輸尿管進入膀胱的黏膜下段以阻止尿液逆流&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:14;"   lang="EN-US"&gt;&lt;img style="width: 328px; height: 326px;" src="http://www.cgmh.com.tw/chldhos/intr/c4b60/index.files/image033.jpg" width="328" border="0" height="326" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;span style="color: rgb(255, 0, 0);"&gt;內視鏡&lt;/span&gt;&lt;br /&gt;原發性 內視鏡療法&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;a href="http://www.cgmh.com.tw/chldhos/intr/c4b60/index.htm#V"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;[2]&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;將特殊針頭刺入輸尿管下緣&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-family:arial;font-size:14;"  &gt;&lt;span lang="EN-US"&gt;&lt;img style="width: 265px; height: 230px;" src="http://www.cgmh.com.tw/chldhos/intr/c4b60/index.files/image027.jpg" width="265" border="0" height="230" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-family:arial;font-size:14;"  &gt;&lt;span style="font-size:100%;"&gt;經由此針注入玻尿酸形成凸起小丘&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;span lang="EN-US"&gt;&lt;img style="width: 264px; height: 229px;" src="http://www.cgmh.com.tw/chldhos/intr/c4b60/index.files/image029.jpg" width="264" border="0" height="229" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;span style="font-size:130%;"&gt;&lt;span style="color: rgb(255, 153, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;用deflux當作填充物&lt;a href="http://www.uroncku.org.tw/health/health_View.asp?Volumn_ID=370&amp;amp;NW_ID=1095&amp;amp;Keyword="&gt;[7]&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Deflux system是將Dextranomer小球溶進玻璃酸鈉(sodium hyaluronic acid)溶液中製成的聚合物，簡稱Dx/HA，其組成小球大小約80到250微米。Dx/HA同時具有可被生物體分解，不會引發過敏免疫反應以及沒有致 癌風險等優點，在實驗中也沒有發現遠端轉移到其他器官的現象，因此比起前述材料較為安全。注射Dx/HA治療的患者，經過平均五年的追蹤發現，治癒率可達 75%，而改善的比率也到達85%的效果。對不想開刀的膀胱輸尿管逆流的患者而言，也是治療時另一個不錯的選擇。&lt;br /&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;span style="font-size:130%;"&gt;&lt;span style="color: rgb(255, 153, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;症狀&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;span style="color: rgb(0, 0, 0);"&gt;小兒科醫師表示，尿道感染的嬰幼兒，3成到4成比例是因為尿道逆流，如果尿液沒有排出，回流到腎臟，會造成腎臟的傷害，由於嬰幼兒尿道感染只有發燒反應，常常會被誤以為是感冒，延誤治療。&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;span style="font-size:14;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;台北市立聯合醫院婦幼院區小兒科醫師黃心平表示，新生兒罹患泌尿道感染，並不會有成人的病狀，包括頻尿、血尿、解尿疼痛表現等，通常只會有發燒反應，而家 長發覺幼兒發燒，往往都是先送診所檢查，如果沒有發現是泌尿道感染，以感冒服用抗生素診斷，常常會造成後續檢查及治療的困難，而這已經浪費了不少時間造成 了腎臟的傷害。&lt;a href="http://blog.yam.com/healthall/article/12389485"&gt;[6]&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;span style="font-size:100%;"&gt;&lt;span style="color: rgb(255, 153, 0);"&gt;照顧要點&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);font-family:arial;" &gt;&lt;b&gt;尿路感染之嬰幼兒，日常照顧的要點&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;1.多喝水。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;2.避免碳酸飲料。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;3.補充可酸化尿液的果汁如:桔子汁、小紅梅汁等。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;4.注意清潔方式，以淋浴代替盆浴。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;5.勿用刺激性肥皂清潔會陰部。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;6.勤換尿布。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;7.預防便秘。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;8.勿憋尿。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;9.避穿著過緊或不吸汗衣物。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;10.遵醫囑按時服用預防性藥物及門診追蹤。&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;span style="color: rgb(51, 51, 255);"&gt;[5]&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 128, 128);font-family:arial;" &gt;&lt;span style="color: rgb(0, 0, 0);"&gt;如鼓勵病童不要憋尿，勤加解尿，甚至雙重解尿，避免便祕，可以減少解尿後餘尿的情形。養成良好會陰部的清潔，有尿布疹要馬上治療好，可以減少泌尿道感染的機會。避免吃會刺激膀胱的食物，如茶、咖啡、可樂、汽水、巧克力和柑橘類的食物。&lt;/span&gt;&lt;a href="http://www.fever.com.tw/uti.htm"&gt;[4]&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;參考：&lt;br /&gt;[1] &lt;a href="http://www.cgmh.com.tw/chldhos/intr/c4b60/index.htm#D"&gt;膀胱輸尿管逆流&lt;/a&gt;&lt;br /&gt;[2] &lt;a href="http://www.cgmh.com.tw/chldhos/intr/c4b60/index.htm#V"&gt;陳孝文醫師輸尿管逆流手術衛教圖片&lt;/a&gt;&lt;br /&gt;[3] &lt;a href="http://www.mmh.org.tw/taitam/pedia/education/%E8%AA%8D%E8%AD%98%E8%86%80%E8%83%B1%E8%BC%B8%E5%B0%BF%E7%AE%A1%E9%80%86%E6%B5%81%E7%97%87.html"&gt;認識膀胱輸尿管逆流症(馬偕蔡政道)&lt;/a&gt;&lt;br /&gt;[4] &lt;a href="http://www.fever.com.tw/uti.htm"&gt;小兒膀胱輸尿管回流 詹前俊醫師&lt;/a&gt;&lt;br /&gt;[5] &lt;a href="http://www1.cgh.org.tw/content/healthy/magazine/medi/01-05_12.htm"&gt;嬰幼兒尿路感染(楊昇層)&lt;/a&gt;&lt;br /&gt;[6] &lt;/span&gt;&lt;a style="font-family: arial;" href="http://blog.yam.com/healthall/article/12389485"&gt;新生兒發燒不一定感冒 有可能尿道感染&lt;/a&gt;&lt;br /&gt;[7] &lt;a href="http://www.uroncku.org.tw/health/health_View.asp?Volumn_ID=370&amp;amp;NW_ID=1095&amp;amp;Keyword="&gt;膀胱輸尿管逆流的治療 指導教師：成大醫學中心泌尿部 鄭鴻琳醫師&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-3526566871249135088?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/3526566871249135088/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=3526566871249135088' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/3526566871249135088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/3526566871249135088'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/03/vurvesicoureteral-reflux.html' title='尿液逆流(VUR,vesicoureteral reflux)的原理和治療'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-5413422053590944242</id><published>2009-03-02T00:01:00.000-08:00</published><updated>2009-03-02T01:06:00.120-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>在blogspot blogger貼上漂亮的程式碼</title><content type='html'>主要的參考網站如下:&lt;br /&gt;&lt;a href="http://google-code-prettify.googlecode.com/svn/trunk/README.html"&gt;http://google-code-prettify.googlecode.com/svn/trunk/README.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;先把prettify.css &amp;amp; prettify.js放在網路硬碟裡。如:sky drive。&lt;br /&gt;&lt;br /&gt;接著把以下的code放到版面配置-&amp;gt;修改html-&amp;gt;修改範本的&amp;lt;html&amp;gt;&amp;lt;/html&amp;gt;裡面(下面href &amp;amp; src後面的網址是來自&lt;a href="http://doublechiang.blogspot.com/2008/08/blogger.html"&gt;Double's thought&lt;/a&gt;)。&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&amp;lt;link href='http://double.myweb.hinet.net/web/prettify.css' rel='stylesheet' type='text/css'/&amp;gt;&lt;br /&gt;&amp;lt;script src='http://double.myweb.hinet.net/web/prettify.js' type='text/javascript'&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;接著把下面這段code放到.post-body前面。url(...)裡的URL也可以下載到自己的網路硬碟。&lt;br /&gt;並用自己的網址取代。&lt;br /&gt;&lt;pre class="prettyprint lang-js"&gt;.post pre {&lt;br /&gt;background: #F0F0F0 url(http://gordon168.tw/wp-content/themes/my-genkitheme/images/blogger-code.gif) repeat-y scroll left top;&lt;br /&gt;border: 1px solid #CCCCCC;&lt;br /&gt;color: #333333;&lt;br /&gt;display: block;&lt;br /&gt;font-family: Courier New;&lt;br /&gt;font-size: 10pt;&lt;br /&gt;line-height: 120%;&lt;br /&gt;margin: 5px 0 0 20px;&lt;br /&gt;max-height: 200px;&lt;br /&gt;overflow: auto;&lt;br /&gt;padding: 10px 10px 10px 21px;&lt;br /&gt;width: 90%;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;(我的template沒有.post-body所以是放在下面這段code的前面)&lt;br /&gt;&lt;pre class="prettyprint lang-js"&gt;&lt;br /&gt;body {&lt;br /&gt;background: $bgColor;&lt;br /&gt;margin: 0;&lt;br /&gt;padding: 0px;&lt;br /&gt;font: x-small Verdana, Arial;&lt;br /&gt;text-align: center;&lt;br /&gt;color: $textColor;&lt;br /&gt;font-size/* */:/**/small;&lt;br /&gt;font-size: /**/small;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;接著找到&amp;lt;body&amp;gt;並且改成如下&lt;br /&gt;&lt;pre class="pretty lang-html"&gt;&lt;br /&gt;&amp;lt;body onload='prettyPrint()'&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;最後當我們要新增一段程式碼的code，記得先把code貼到&lt;a href="http://www.opinionatedgeek.com/DotNet/Tools/HTMLEncode/Encode.aspx"&gt;html encoder&lt;/a&gt;做轉換。&lt;br /&gt;之後再把轉換後的程式按照修改html的格式用：&lt;br /&gt;&lt;pre class="prettyprint lang-html"&gt;&lt;br /&gt;&amp;lt;pre class="prettyprint lang-cpp"&amp;gt;.....&amp;lt;/pre&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;語法框起來。&lt;br /&gt;其實下面這樣也是可以，只是沒有顏色。&lt;br /&gt;&lt;pre class="prettyprint lang-html"&gt;&lt;br /&gt;&amp;lt;pre&amp;gt;...&amp;lt;/pre&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;其中lang-cpp的cpp可以用這些字"c", "cc", "cpp", "cs", "cyc", "java", "bsh", "csh", "sh", "cv", "py", "perl", "pl", "pm", "rb", "js", "html", "html", "xhtml", "xml", "xsl"取代。&lt;br /&gt;&lt;br /&gt;有時候如果想要行號的支援，&lt;a href="http://google-code-prettify.googlecode.com/svn/trunk/README.html"&gt;官方網站&lt;/a&gt;是這樣做:&lt;br /&gt;&lt;pre class="prettyprint lang-html"&gt;&lt;br /&gt;&amp;lt;pre class=prettyprint&amp;gt;&lt;br /&gt;&amp;lt;span class="nocode"&amp;gt;1:&amp;lt;/span&amp;gt; /* This is line 1 of my code&lt;br /&gt;&amp;lt;span class="nocode"&amp;gt;2:&amp;lt;/span&amp;gt;  * and here's line 2 */&lt;br /&gt;&amp;lt;span class="nocode"&amp;gt;3:&amp;lt;/span&amp;gt; print("I'm line number 3");&lt;br /&gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;其他參考網站:&lt;br /&gt;&lt;a href="http://elder38.blogspot.com/2008/10/javascript-code-prettifier-google-html.html"&gt;巫醫訓練所&lt;/a&gt;&lt;br /&gt;&lt;a href="http://doublechiang.blogspot.com/2008/08/blogger.html"&gt;Double's thought:如何在blogger裡內嵌程式碼&lt;/a&gt;&lt;br /&gt;&lt;a href="http://gordon168.tw/?p=200"&gt;高登工作室:在blogger文章裡內嵌程式碼&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-5413422053590944242?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/5413422053590944242/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=5413422053590944242' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/5413422053590944242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/5413422053590944242'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/03/blogspot.html' title='在blogspot blogger貼上漂亮的程式碼'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-4974341911407693667</id><published>2009-03-01T19:00:00.000-08:00</published><updated>2009-03-01T19:10:37.216-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><title type='text'>Ubuntu 網路設定</title><content type='html'>在GUI底下設定網路，因為沒有Root的權限，所以怎麼設每次重開都需要重設。&lt;br /&gt;&lt;br /&gt;所以要設定網路設定檔，如下步驟：&lt;br /&gt;&lt;br /&gt;sudo gvim /etc/network/interfaces&lt;br /&gt;auto lo                  # 啟用 lookback 設備。注意，請不要改動它！&lt;br /&gt;iface lo inet loopback   # 設定 lookback 設備。注意，也不要改動到它！&lt;br /&gt;&lt;br /&gt;auto eth0               # 啟用 eth0 網路卡，若您有其他網路卡，可以直接&lt;br /&gt;&lt;br /&gt;iface eth0 inet static          # 設定 eth0 這張網路卡為固定 ip&lt;br /&gt;  address 192.168.1.5       # 設定 IP 地址&lt;br /&gt;  netmask 255.255.255.0    # 設定子網路遮罩&lt;br /&gt;  gateway 192.168.1.1       # 設閘道器&lt;br /&gt;  network 192.168.1.0       # 設定網路代號，不一定要設定，可有可無！&lt;br /&gt;　　　　broadcast 192.168.1.255   # 設定廣播地址，不一定要設定，可有可無！&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;code&gt;# sudo vim /etc/resolv.conf&lt;br /&gt;# generated by NetworkManager, do not edit!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; nameserver 192.168.1.1 /*主要的dns*/&lt;br /&gt; nameserver 192.168.1.2 /*次要的dns*/&lt;/code&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;code&gt;# sudo /etc/init.d/networking restart&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/span&gt;sudo ifdown eth0  # 關閉 eth0 這個裝置&lt;br /&gt;sudo ifup   eth0  # 啟用 eth0 並從 interfaces 讀取設定檔&lt;br /&gt;&lt;br /&gt;參考:&lt;br /&gt;&lt;a href="http://joy715.blogspot.com/2007/09/ubuntu.html"&gt;喬伊的天空&lt;/a&gt;&lt;br /&gt;&lt;a href="http://jonnyubuntu.blogspot.com/2008/02/ubuntu-dns.html"&gt;凍仁的網路筆記&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-4974341911407693667?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/4974341911407693667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=4974341911407693667' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/4974341911407693667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/4974341911407693667'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/03/ubuntu.html' title='Ubuntu 網路設定'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-7452629869075032817</id><published>2009-02-26T01:20:00.000-08:00</published><updated>2009-04-28T00:01:28.451-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>busybox</title><content type='html'>busybox可以到http://www.busybox.net/download.html下載。&lt;br /&gt;&lt;br /&gt;下載下來以後直接tar jxf xxxx。&lt;br /&gt;&lt;br /&gt;接著，make menuconfig，儲存config之後。&lt;br /&gt;&lt;br /&gt;make install就可以在根目錄下面產生busybox執行檔。&lt;br /&gt;&lt;br /&gt;但是，放到google android上面沒辦法跑一直出現not found。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-7452629869075032817?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/7452629869075032817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=7452629869075032817' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/7452629869075032817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/7452629869075032817'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/02/busybox.html' title='busybox'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-8593919696637256973</id><published>2009-02-25T18:31:00.000-08:00</published><updated>2009-04-28T00:00:32.412-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux kernel'/><title type='text'>EeePC 2.6.21.4 Xandros kernel在gcc(Ubuntu 4.3.2-1ubuntu11）下編譯問題</title><content type='html'>一開始如果你直接make他會告訴你scripts/mod/sumversion.c的get_src_version裡頭的PATH_MAX沒有定義。&lt;br /&gt;&lt;br /&gt;因為我有裝ctags的緣故，按ctrl+]發現PATH_MAX定義在include/linux/limits.h。&lt;br /&gt;&lt;br /&gt;我就在sumversion.c最前面的include file裡面加上#include &lt;limits.h&gt;。&lt;br /&gt;&lt;br /&gt;之後我又下make，到一半又出現了這個錯誤：undefined reference to `__umoddi3'&lt;br /&gt;&lt;br /&gt;上網搜尋了一下在&lt;a href="http://blog.yam.com/yunlung/article/17809151"&gt;這個網站&lt;/a&gt;找到了解法。&lt;br /&gt;&lt;br /&gt;原來是gcc 4.3.2太新的問題，要修改makefile。&lt;br /&gt;&lt;br /&gt;cd kernel&lt;br /&gt;&lt;br /&gt;vi Makefile&lt;br /&gt;&lt;br /&gt;找到：&lt;br /&gt;&lt;br /&gt;CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \&lt;br /&gt;                 -fno-strict-aliasing -fno-common&lt;br /&gt;&lt;br /&gt;增加一行，修改成：&lt;br /&gt;&lt;br /&gt;CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \&lt;br /&gt;                 -fno-strict-aliasing -fno-common \&lt;br /&gt;                 &lt;span style="color: rgb(255, 0, 0);"&gt;-fno-tree-scev-cprop&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;最後我make modules出現了下面這些問題：&lt;br /&gt;gavin@gavin-desktop:~/linux-source-2.6.21.4-eeepc$ make modules&lt;br /&gt;scripts/kconfig/conf -s arch/i386/Kconfig&lt;br /&gt;CHK     include/linux/version.h&lt;br /&gt;CHK     include/linux/utsrelease.h&lt;br /&gt;Building modules, stage 2.&lt;br /&gt;MODPOST 311 modules&lt;br /&gt;WARNING: "acpi_bus_generate_netlink_event" [drivers/acpi/battery.ko] undefined!&lt;br /&gt;WARNING: "acpi_bus_generate_proc_event" [drivers/acpi/battery.ko] undefined!&lt;br /&gt;make[1]: *** [__modpost] Error 1&lt;br /&gt;make: *** [modules] Error 2&lt;br /&gt;乍看之下make modules有過，且.o檔都有make出來，但是.ko卻沒出現。&lt;br /&gt;&lt;br /&gt;因為我要trace USB的緣故，因此"more .config | grep ACPI"發現是在power management&lt;br /&gt;&lt;br /&gt;options底下。&lt;br /&gt;&lt;br /&gt;把power management options--&gt; ACPIsupport --&gt; 把battery勾掉。&lt;br /&gt;&lt;br /&gt;接著就可以過了。但不懂的是為何相同的kernel source在eeepc上面編譯gcc版本為gcc 4.1.2&lt;br /&gt;&lt;br /&gt;20061115(Debian 4.1.1-21)卻沒有這麼多的問題。&lt;br /&gt;&lt;/limits.h&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-8593919696637256973?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/8593919696637256973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=8593919696637256973' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/8593919696637256973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/8593919696637256973'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/02/eeepc-26214-xandros-kernelgccubuntu-432.html' title='EeePC 2.6.21.4 Xandros kernel在gcc(Ubuntu 4.3.2-1ubuntu11）下編譯問題'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-9128237107452396512</id><published>2009-02-25T06:24:00.000-08:00</published><updated>2009-04-28T00:01:28.452-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Eeepc Xandros busybox下如何enable USB</title><content type='html'>因為eeepc的linux /dev/sda系統碟有做保護所以要更新kernel無法直接把kernel copy到&lt;br /&gt;/boot底下。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;以下&lt;/span&gt;是在busybox底下用usb copy進去的一個方法。&lt;br /&gt;&lt;br /&gt;開機後按F9進入grub的開機選單。&lt;br /&gt;&lt;br /&gt;之後在normal的那個選項按下e進去編輯，之後選擇第二個選項"kernel /boot/vmlinuz-&lt;br /&gt;&lt;br /&gt;2.6.21.4-eeepc quiet rw vga=785 irqpoll root=/dev/sda1"，之後按e進入編輯模式。&lt;br /&gt;&lt;br /&gt;之後把"root=/dev/sda1"刪掉，按下enter。&lt;br /&gt;&lt;br /&gt;再按b直接開機。&lt;br /&gt;&lt;br /&gt;開機後因為剛剛把root弄掉，所以會造成設定錯誤進入busybox。&lt;br /&gt;&lt;br /&gt;接著要把/dev/sda1 mount起來，因為他是系統碟，我們的modules都放在下面。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;"mount /dev/sda1 /mnt-system"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;"cd /mnt-system/lib/modules/2.6.21.4-eeepc/kernel/drivers/usb"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;以下這些記得要按照順序mount不然會出錯。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;"insmod core/usbcore.ko"&lt;/span&gt;  &lt;span style="color: rgb(51, 51, 255);"&gt;"insmod host/ehci-hcd.ko"&lt;/span&gt;  &lt;span style="color: rgb(51, 51, 255);"&gt;"insmod storage/libusual.ko"&lt;/span&gt;  &lt;span style="color: rgb(51, 51, 255);"&gt;"insmod storage/usb-storage.ko"&lt;/span&gt;  &lt;span style="color: rgb(51, 51, 255);"&gt;"cd /mnt-system/lib/modules/2.6.21.4-eeepc/kernel/fs"&lt;/span&gt;  &lt;span style="color: rgb(51, 51, 255);"&gt;"insmod fat/fat.ko"&lt;/span&gt;  &lt;span style="color: rgb(51, 51, 255);"&gt;"insmod vfat/fat.ko"&lt;/span&gt;  &lt;span style="color: rgb(51, 51, 255);"&gt;"insmod nls/nls_cp850.ko"&lt;/span&gt;  &lt;span style="color: rgb(51, 51, 255);"&gt;"insmod nls/nls_iso8859-1.ko"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;這些都弄完了以後&lt;span style="color: rgb(51, 51, 255);"&gt;"cat /proc/partitions"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;可以看到插入的隨身碟是sdd和sdd1這兩個。&lt;br /&gt;&lt;br /&gt;但是這時沒結束要自己make node。你去/dev/底下是找不到這兩個node的。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;"mknod /dev/sdd1 b 8 49"&lt;/span&gt;     b是代表block device，8是major number，49是minor number。&lt;br /&gt;&lt;br /&gt;這兩個number在"cat /proc/partitions"裡頭可以看到。&lt;br /&gt;&lt;br /&gt;接著&lt;span style="color: rgb(51, 51, 255);"&gt;"mount /dev/sdd1 /mnt-user"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;"ls /mnt-user"&lt;/span&gt;就可以看到隨身碟裡頭的資料了。&lt;br /&gt;&lt;br /&gt;其實要變動kernel還可以用隨身碟linux開機，之後再把eeepc上面的系統碟mount起來。&lt;br /&gt;&lt;br /&gt;再來就可以把資料從usb碟copy進去。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-9128237107452396512?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/9128237107452396512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=9128237107452396512' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/9128237107452396512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/9128237107452396512'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/02/eeepc-xandros-busyboxenable-usb.html' title='Eeepc Xandros busybox下如何enable USB'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-5506532218334416276</id><published>2009-02-09T22:29:00.000-08:00</published><updated>2009-02-10T00:13:06.147-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><title type='text'>Ctags 補充常用功能</title><content type='html'>(1) 若是你用ctags搜尋到不只一個標籤時，&lt;br /&gt;可以用"g ctrl + ]"，之後按"下"或是"j"把所有的tags顯示出來，&lt;br /&gt;他就會問你要第幾個，若是只有一個則jump過去。相當於":tj"&lt;br /&gt;&lt;br /&gt;(2) ":ts {ident}"(g]), 若沒有加ident則tag select把tag stack最近的tag拿來搜尋，並列出所有的標籤。&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;PS&lt;/span&gt;:":tj" 和 ":ts"本質上是一樣的，差別在於只有一個的狀況下會不會jump過去。&lt;br /&gt;&lt;br /&gt;(3) 當你想看tags stack ":tags"&lt;br /&gt;&lt;br /&gt;(4) ":tag {ident}"可以直接搜尋標籤，":tag /norm"可以列出所有包含norm字串的tag，像"id_norm"，":tag /^norm"則是跳到最優先的tag。&lt;br /&gt;&lt;br /&gt;(5) "g + {LeftMouseClick}" 跳到滑鼠指的標籤，相當於"ctrl + ]"&lt;br /&gt;&lt;br /&gt;(6) "g + {RightMouseClick}" 跳到上一個標籤，相當於"ctrl + t" or ":pop"&lt;br /&gt;&lt;br /&gt;(7) 若搜尋到數個，想看下一個tag則使用":tn"，相反的上一個":tp" or ":tN"&lt;br /&gt;&lt;br /&gt;(8) "[i"會show出第一個tag，從檔案最前頭開始，並且會去除掉comment裡相同的tag。"]i"也類似，只是會從現在游標的位置往下找。&lt;br /&gt;&lt;br /&gt;(9) "[I"會show出所有的tags，從檔案最前頭開始，並且會去除掉comment裡相同的tag。"]I"同上。&lt;br /&gt;&lt;br /&gt;(10) 若是懶的每次都要在ctags檔案在的資料夾才進入vim，可以在.vimrc裡頭加上tags所在的目錄。&lt;br /&gt;       set tags=~/xxx/xxx/xxx/tags,/xx/xxx/xx,tags&lt;br /&gt;&lt;br /&gt;(11) 最後，當ctags列出所有的標籤的時候是依照下面的順序。&lt;br /&gt;&lt;pre&gt;When there are multiple matches for a &lt;a href="http://www.vim.org/htmldoc/tagsrch.html#tag"&gt;tag&lt;/a&gt;, this priority is used:&lt;br /&gt;1. "FSC"  A full matching static &lt;a href="http://www.vim.org/htmldoc/tagsrch.html#tag"&gt;tag&lt;/a&gt; for the current file.&lt;br /&gt;2. "&lt;a href="http://www.vim.org/htmldoc/motion.html#F"&gt;F&lt;/a&gt; C"  A full matching global &lt;a href="http://www.vim.org/htmldoc/tagsrch.html#tag"&gt;tag&lt;/a&gt; for the current file.&lt;br /&gt;3. "&lt;a href="http://www.vim.org/htmldoc/motion.html#F"&gt;F&lt;/a&gt;  "  A full matching global &lt;a href="http://www.vim.org/htmldoc/tagsrch.html#tag"&gt;tag&lt;/a&gt; for another file.&lt;br /&gt;4. "FS "  A full matching static &lt;a href="http://www.vim.org/htmldoc/tagsrch.html#tag"&gt;tag&lt;/a&gt; for another file.&lt;br /&gt;5. " SC"  An ignore-case matching static &lt;a href="http://www.vim.org/htmldoc/tagsrch.html#tag"&gt;tag&lt;/a&gt; for the current file.&lt;br /&gt;6. "  C"  An ignore-case matching global &lt;a href="http://www.vim.org/htmldoc/tagsrch.html#tag"&gt;tag&lt;/a&gt; for the current file.&lt;br /&gt;7. "   "  An ignore-case matching global &lt;a href="http://www.vim.org/htmldoc/tagsrch.html#tag"&gt;tag&lt;/a&gt; for another file.&lt;br /&gt;8. " &lt;a href="http://www.vim.org/htmldoc/change.html#S"&gt;S&lt;/a&gt; "  An ignore-case matching static &lt;a href="http://www.vim.org/htmldoc/tagsrch.html#tag"&gt;tag&lt;/a&gt; for another file.&lt;br /&gt;&lt;/pre&gt;一般我們在trace code來說，當我們用"g ctrl ]"跳來跳去，如果我們看到第四個以後的標籤，&lt;br /&gt;&lt;pre&gt;應該就不大可能會用到，因為別的檔案的static variable，只能在那個點c檔裡頭被使用，這是C的封裝特性。&lt;br /&gt;&lt;/pre&gt; 這些問題可以在":help ctrl-]"找到。&lt;br /&gt;&lt;br /&gt;reference:&lt;a href="http://www.vim.org/htmldoc/tagsrch.html"&gt;http://www.vim.org/htmldoc/tagsrch.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-5506532218334416276?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/5506532218334416276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=5506532218334416276' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/5506532218334416276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/5506532218334416276'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/02/ctags_09.html' title='Ctags 補充常用功能'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-2028570636005446613</id><published>2009-02-09T18:44:00.000-08:00</published><updated>2009-05-06T00:38:38.232-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='生活'/><title type='text'>幾個不錯的irc channel</title><content type='html'>&lt;style&gt; &lt;!--  /* Font Definitions */  @font-face  {font-family:新細明體;  panose-1:2 2 3 0 0 0 0 0 0 0;} @font-face  {font-family:"\@新細明體";  panose-1:2 2 3 0 0 0 0 0 0 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal  {margin:0cm;  margin-bottom:.0001pt;  font-size:12.0pt;  font-family:"Times New Roman";} a:link, span.MsoHyperlink  {color:blue;  text-decoration:underline;} a:visited, span.MsoHyperlinkFollowed  {color:purple;  text-decoration:underline;} span.EmailStyle17  {mso-style-type:personal-compose;  font-family:Arial;  color:windowtext;}  /* Page Definitions */  @page Section1  {size:595.3pt 841.9pt;  margin:72.0pt 90.0pt 72.0pt 90.0pt;  layout-grid:18.0pt;} div.Section1  {page:Section1;} --&gt; &lt;/style&gt;&lt;div class="Section1" style=""&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-family:Times New Roman;font-size:100%;"&gt;&lt;span style="font-size: 12pt;" lang="EN-US"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;Server&lt;/span&gt;: irc.freenode.net&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-family:Times New Roman;font-size:100%;"&gt;&lt;span style="font-size: 12pt;" lang="EN-US"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;Channels&lt;/span&gt;: #tossug,#kalug,#eeeuser-tw,#python.tw,#lot,#ubuntu-tw,#twjug&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Arial;font-size:78%;"&gt;&lt;span style="font-size: 9pt; font-family: Arial;" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-2028570636005446613?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/2028570636005446613/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=2028570636005446613' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/2028570636005446613'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/2028570636005446613'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/02/irc-channel.html' title='幾個不錯的irc channel'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-3117366139845602536</id><published>2009-02-06T03:30:00.000-08:00</published><updated>2009-02-06T03:36:58.484-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><title type='text'>Ctags要留心的小地方</title><content type='html'>當我們要瀏覽整個kernel souce的時候，在kernel根目錄下"ctags -R"。&lt;br /&gt;&lt;br /&gt;接著，ctags會幫我們把整個kernel的tags關聯性都建立起來。&lt;br /&gt;&lt;br /&gt;接著，你要直接在kernel的根目錄下面下"vim drivers/input/input.c"，&lt;br /&gt;&lt;br /&gt;如此，你在trace input.c裡面的tags時，若是不在input資料夾下面的tag才能被找到。&lt;br /&gt;&lt;br /&gt;若是你直接"cd drivers/input; vim input.c"則在drivers/input以外的tags是無法用"ctrl + ]"找到的。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-3117366139845602536?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/3117366139845602536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=3117366139845602536' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/3117366139845602536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/3117366139845602536'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/02/ctags.html' title='Ctags要留心的小地方'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-1380262108738915286</id><published>2009-02-06T02:50:00.000-08:00</published><updated>2009-02-06T03:42:42.049-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><title type='text'>Vim Colorscheme和字型</title><content type='html'>最近在Ubuntu上面的vim開發程式，預設的顏色和字型，怎麼看都看不順眼。&lt;br /&gt;&lt;br /&gt;後來上網搜尋了一下找到了&lt;span style="color: rgb(51, 51, 255);"&gt;ir_black&lt;/span&gt;的colorscheme和&lt;span style="color: rgb(51, 51, 255);"&gt;monaco&lt;/span&gt;以及&lt;span style="color: rgb(51, 51, 255);"&gt;consolas&lt;/span&gt;兩個字型。&lt;br /&gt;&lt;br /&gt;安裝方式如下，把ir_black.vim放在"~/.vim/colors"底下(.vim資料夾不存在要自己create)，&lt;br /&gt;&lt;br /&gt;且在~/.vimrc裡面加上這行"colorscheme ir_black"(也可在vim的command mode下":colorscheme ir_black")。&lt;br /&gt;&lt;br /&gt;ps:"colorscheme + tab鑑"可以選擇更多的colorscheme&lt;br /&gt;&lt;br /&gt;monaco.tff &amp;amp; consolas.tff放在"/usr/share/fonts/truetype"底下&lt;br /&gt;&lt;br /&gt;(也可以在Truetype底下自己建資料夾放進去，fc-cache會自己去掃)&lt;br /&gt;&lt;br /&gt;之後在command line下"&lt;span style="color: rgb(255, 0, 0);"&gt;fc-cache -f -v&lt;/span&gt;"，&lt;br /&gt;&lt;br /&gt;並且將桌面上的系統-&gt;偏好設定-&gt;外觀設定-&gt;字型-&gt;固定寬度字型改成Monaco，&lt;br /&gt;&lt;br /&gt;然後在terminal的編輯-&gt;設定組合偏好設定-&gt;把使用系統的固定寬度字型勾選起來，&lt;br /&gt;&lt;br /&gt;之後vim開啟後就會是monaco。&lt;br /&gt;&lt;br /&gt;但不知道為何不能直接在terminal的設定組合偏好設定裡直接更改字型，&lt;br /&gt;&lt;br /&gt;會有找不到Monaco &amp;amp; Consolas的情形，但我發現在安裝字型後才安裝的gvim有抓到。&lt;br /&gt;&lt;br /&gt;參考:&lt;br /&gt;&lt;h3 class="title"&gt;&lt;a href="http://plog.longwin.com.tw/my_note-programming/2008/05/07/gvim_color_scheme_theme_ir_black_2008"&gt;gVim 的 color scheme (ir_black.vim)&lt;/a&gt;&lt;/h3&gt;&lt;h3 class="title"&gt;&lt;a href="http://plog.longwin.com.tw/programming/2007/08/14/programmer_best_font_monaco_2007"&gt;Programmer 專用最佳字型 - Monaco font&lt;/a&gt;&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-1380262108738915286?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/1380262108738915286/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=1380262108738915286' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/1380262108738915286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/1380262108738915286'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/02/vim-colorscheme.html' title='Vim Colorscheme和字型'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-6992004095382029188</id><published>2009-02-01T21:33:00.000-08:00</published><updated>2009-02-01T21:38:36.356-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><title type='text'>Ubuntu 中文輸入法</title><content type='html'>因為要compile Android的關係，所以裝了Ubuntu(官方指定作業系統)，裝了以後，發現沒有中文輸入法(我安裝的是中文的版本)，後來找到下面這篇文章，和我有同樣的問題。&lt;br /&gt;&lt;br /&gt;&lt;h3 class="title"&gt;&lt;a href="http://blog.ilc.edu.tw/blog/blog/2731/post/8146/32959"&gt;Ubuntu -- 中文輸入法的安裝&lt;/a&gt;&lt;/h3&gt;可以參考看看。&lt;br /&gt;&lt;br /&gt;&lt;p&gt; 我同事的 Ubuntu 裝好之後 &lt;/p&gt; &lt;p&gt; 就有中文輸入法可用了 &lt;/p&gt; &lt;p&gt; 搞不懂我的為什麼沒有 &lt;/p&gt; &lt;p&gt; 所以只好自己動手囉～ &lt;/p&gt; &lt;p&gt; &lt;/p&gt;  &lt;p&gt; 原本桌面左上方的選單是英文的 &lt;/p&gt; &lt;p&gt; 右下方輸入法部分也沒有中文輸入法（如以下二圖） &lt;/p&gt; &lt;p&gt; &lt;a id="res_147065" href="http://blog.ilc.edu.tw/blog/gallery/2731/2731-147065.jpg"&gt;&lt;img src="http://blog.ilc.edu.tw/blog/gallery/2731/previews-med/2731-147065.jpg" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt; &lt;a id="res_147066" href="http://blog.ilc.edu.tw/blog/gallery/2731/2731-147066.jpg"&gt;&lt;img src="http://blog.ilc.edu.tw/blog/gallery/2731/previews-med/2731-147066.jpg" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt; 該從何著手呢？請看以下說明 ： &lt;/p&gt; &lt;p&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;--------------------------------------------------&lt;/span&gt; &lt;/p&gt; &lt;p&gt; &lt;strong&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;【步驟一】&lt;/span&gt;&lt;/strong&gt; &lt;/p&gt; &lt;p&gt; 到「System」→「管理」→「Language Support」 &lt;/p&gt; &lt;p&gt; &lt;a id="res_147067" href="http://blog.ilc.edu.tw/blog/gallery/2731/2731-147067.jpg"&gt;&lt;img src="http://blog.ilc.edu.tw/blog/gallery/2731/previews-med/2731-147067.jpg" border="0" /&gt;&lt;/a&gt;  &lt;/p&gt; &lt;p&gt; 就會開始下載相關套件 &lt;/p&gt; &lt;p&gt; &lt;a id="res_147068" href="http://blog.ilc.edu.tw/blog/gallery/2731/2731-147068.jpg"&gt;&lt;img src="http://blog.ilc.edu.tw/blog/gallery/2731/previews-med/2731-147068.jpg" border="0" /&gt;&lt;/a&gt;  &lt;/p&gt; &lt;p&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;&lt;strong&gt; 【步驟二】 &lt;/strong&gt;&lt;/span&gt; &lt;/p&gt; &lt;p&gt; 按"Close"  &lt;/p&gt; &lt;p&gt; &lt;a id="res_147069" href="http://blog.ilc.edu.tw/blog/gallery/2731/2731-147069.jpg"&gt;&lt;img src="http://blog.ilc.edu.tw/blog/gallery/2731/previews-med/2731-147069.jpg" border="0" /&gt;&lt;/a&gt;  &lt;/p&gt; &lt;p&gt; &lt;strong&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; 【步驟三】 &lt;/span&gt;&lt;/strong&gt; &lt;/p&gt; &lt;p&gt; 再按一次"Close" 後，請自行重新開機。 &lt;/p&gt; &lt;p&gt;  &lt;a id="res_147070" href="http://blog.ilc.edu.tw/blog/gallery/2731/2731-147070.jpg"&gt;&lt;img src="http://blog.ilc.edu.tw/blog/gallery/2731/previews-med/2731-147070.jpg" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;   &lt;/p&gt; &lt;p&gt;   之後就可以看到左上方的選單變成中文的，右下方也有很多輸入法可以選擇囉！  &lt;/p&gt; &lt;p&gt; &lt;a id="res_147071" href="http://blog.ilc.edu.tw/blog/gallery/2731/2731-147071.jpg"&gt;&lt;img src="http://blog.ilc.edu.tw/blog/gallery/2731/previews-med/2731-147071.jpg" border="0" /&gt;&lt;/a&gt;  &lt;/p&gt; &lt;p&gt; &lt;a id="res_147064" href="http://blog.ilc.edu.tw/blog/gallery/2731/2731-147064.jpg"&gt;&lt;img src="http://blog.ilc.edu.tw/blog/gallery/2731/previews-med/2731-147064.jpg" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-6992004095382029188?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/6992004095382029188/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=6992004095382029188' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/6992004095382029188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/6992004095382029188'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2009/02/ubuntu.html' title='Ubuntu 中文輸入法'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-2815905588773983844</id><published>2008-12-01T01:37:00.000-08:00</published><updated>2008-12-01T01:50:13.154-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='健力運動'/><title type='text'>健力大概心得分享</title><content type='html'>&lt;span style="color: rgb(51, 51, 255);"&gt;之前波在ptt的文章:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;想想乾脆和大家分享依下心得好了，之前都一直潛水，有時候想說幾句話，但又怕大家覺得這傢伙不知道在屌什麼，今天懶的想那麼多了。畢竟，練健力南北的環境真的差很多，北部真的少有這種人，但如果大家有認識的麻煩幫小弟引薦一下，大家團結起來，可以成立一個團隊，互相切磋，鼓勵加油。甚至可以搞個自己的場地，感覺會很棒。在這邊波個文章，算是給入門者一點指引吧。想當初我也是跌跌撞撞的。&lt;br /&gt;&lt;br /&gt;       主要力量的練法，簡單講就是要做重，至於是要怎麼做才可以增加自己的最大肌力?我解釋一下，增加力量有兩種途徑，第一個是&lt;span style="color: rgb(255, 0, 0);"&gt;增加肌肉量&lt;/span&gt;。第二是在&lt;span style="color: rgb(255, 0, 0);"&gt;有限的肌肉量裡面增加力量&lt;/span&gt;。第一個我就不解釋了，版上大多都是練健美的人，這方面我比各位都弱。至於如何在有限的肌肉量裡增加力量，原理就是不外乎訓練motor unit的&lt;span style="color: rgb(255, 0, 0);"&gt;喚起數量&lt;/span&gt;，以及motor unit的運動同步化，還有就是atp在肌肉裡的含量，或是pc的含量，以及其他等等因素。(這邊懶的再去翻資料了，有人知道的可以補充一下。)回歸到訓練法，力量的練法就是訓練你的神經系統，你做重，耗損最多的是你在喚起你的肌肉時，神經系統傳導所需要的物質。(如果有人知道需要什麼物質也可以補充一下，我不是本科系的，沒有研究的很徹底，只有大概看看生理學，還有Zatsiorsky教授的書而已)只是我猜平常飲食應該要均衡，蔬菜水果要盡量吃，維生素，礦物質不能少。再來就是訓練這天，飲食攝取的熱量要夠，至於怎樣叫做夠，我是懶的去算那些基本代謝，試個幾次你就大概知道了，如果今天來沒有力氣，你就要檢討一下是不是吃太少，或是太累，前天打牌打太晚，或是怎麼的原因影響到了。通常不外乎吃太少，或是精神方面的問題。當然也不能吃太多，就會變胖。自己調整一下就大概知道了。&lt;br /&gt;&lt;br /&gt;       虎爛了一堆，都沒講到重點，我現在開始說如何練。主要說練法，至於基本動作，蹲舉，硬舉，還有臥推，就不講了。練習法有幾種，主要分為&lt;span style="color: rgb(255, 0, 0);"&gt;maximum effort&lt;/span&gt;，&lt;span style="color: rgb(255, 0, 0);"&gt;dynamic effort&lt;/span&gt;，還有&lt;span style="color: rgb(255, 0, 0);"&gt;repetition effort&lt;/span&gt;。力量主要是用maximum effort還有dynamic effort。我解釋一下maximum effort是什？maximum effort是做不超過六下直到你，做到1RM為止。怎麼做你可以參考我的前篇硬舉分享大概就知道了，至於休息時間大概是二到五分鐘。我通常都是休息到五分鐘左右。網路上也有一堆文章，可以google一下。Dynamic method大概是做三下左右，每一下盡全力，做到最快，休息大概一分鐘，用50% percent of 1RM的重量，做十組。結合這兩種就叫做conjugate method(至於為何要做dynamic method，我大概說一下，因為身體不是在最大負荷的是使不出全力的，如果空身能使力的力量強造就的就是很強的爆發力，變的速度很快。所以反過來說在增加速度的同時，負荷不變，相對的，也增加了力量，F=ma。這個方法是訓練爆發力也就是空身的力量，再來就是訓練神經系統，讓神經在沒有重負荷的時候也可以被active)。&lt;br /&gt;&lt;br /&gt;       以蹲舉而言，一個禮拜做一天maximum method，另一天是dynamic method。通常間隔三天左右。蹲舉Maximum做完可以挑一些動作做一些輔助，次數為8RM以上目的是強化輔助肌群。與，增加肌肉量。休息不超過2 minutes。至於dynamic day，可以選輔助動作做重，大概3~6rm，輔助動作休息時間可以久點。大概二到五分鐘。我使用的是&lt;span style="color: rgb(255, 0, 0);"&gt;Westside barbell training system&lt;/span&gt;。大家可以google一下，Westside有很多文章喔。&lt;br /&gt;&lt;br /&gt;      大概就是這樣子，打的很匆促，又沒有引經據典，句子不順，大家包容一下。有問題再問。至於比我強的高手，就看看笑笑，我只是愛現分享一下心得罷了。&lt;br /&gt;&lt;br /&gt;PS:補充一下，maximum effort連續練三個禮拜要休息一個禮拜，以免神經系統疲憊。會影響效果。我通常休息的那次就是做repetition method。像硬舉做個三組，180，拉個10~12下這樣。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-2815905588773983844?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/2815905588773983844/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=2815905588773983844' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/2815905588773983844'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/2815905588773983844'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/12/blog-post.html' title='健力大概心得分享'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-4937422541861254179</id><published>2008-11-30T22:47:00.000-08:00</published><updated>2008-12-03T22:10:18.351-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><title type='text'>Multiboot USB Bootloader</title><content type='html'>因為之前工作上的需要，所以我有一顆usb專門裝上DOS，有一個usb裝winpe，另一個usb是裝上Gparted linux。因為usb實在是太多顆了，突發奇想，看看能不能把所有的OS放在一個USB上面。又因為winpe是目的端Windows時，才需要load起來，Linux是目的端Linux，才需要load起來。後來就參考了&lt;a href="http://share.solrex.cn/WriteOS/download.php"&gt;solrex的文章&lt;/a&gt;自己寫了一個bootloader判斷目的端的作業系統，然後自動載入usb上面對應的作業系統。至於如何製作一個multiboot partition請參考&lt;a href="http://bboytaiwan.blogspot.com/2008/11/usbwinpe-linux.html"&gt;我的另一篇文章&lt;/a&gt;。&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;其實這篇文章主要的概念就在下面的圖示。&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_r6LKRJP8V4w/STOVuwFmyXI/AAAAAAAAAHs/exBOiueX3-U/s1600-h/multiboot.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 301px;" src="http://3.bp.blogspot.com/_r6LKRJP8V4w/STOVuwFmyXI/AAAAAAAAAHs/exBOiueX3-U/s400/multiboot.JPG" alt="" id="BLOGGER_PHOTO_ID_5274724218995919218" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;我會在USB partition做好了以後，把我的bootloader用Winhex放到USB MBR裡面。(ctrl+c &amp;amp; ctrl +b千萬記住不能蓋掉partition table，可以分兩次copy，用winhex把編好的bin先copy第一個sector的446bytes，再copy第二個sector的512bytes，事實上第二支code只要copy有東西的地方就可以了，後面零的地方可以不用理他。但在copy前要確認usb已經被低階格式化過了，都清成零才不會錯)。這支程式的架構是分為&lt;span style="color: rgb(255, 0, 0);"&gt;兩段code&lt;/span&gt;。每段code分別為一個sector也就是512 bytes的大小，放在usb最前面&lt;span style="color: rgb(255, 0, 0);"&gt;MBR開始連續兩個sectors&lt;/span&gt;的地方。一開機，MBR的512bytes會被load到記憶體&lt;span style="color: rgb(255, 0, 0);"&gt;0x0000:0x7C00&lt;/span&gt;的位置。這支程式接著會把接續著MBR後面的第二支程式copy到&lt;span style="color: rgb(255, 0, 0);"&gt;0x9000:0000&lt;/span&gt;的位置。並且jmp到第二支code，把權力交給他之後他會到硬碟上去把第一個partition的boot sector 0x0000003F抓到9000:0200並且檢查byte number &lt;span style="color: rgb(255, 0, 0);"&gt;3&lt;/span&gt;也就是第&lt;span style="color: rgb(255, 0, 0);"&gt;四個byte&lt;/span&gt;處(&lt;span style="color: rgb(255, 0, 0);"&gt;9000:0203&lt;/span&gt;)，檢查是否為&lt;span style="color: rgb(255, 0, 0);"&gt;NTFS&lt;/span&gt;。這會有一個小問題，以我這顆usb為例，開機時被認為硬碟，所以int 13h的dl硬碟代號就是80h。而PC上面的硬碟就會被認為是第二顆，就是81h。若是有的usb隨身碟開機的時候被認做是floppy則dl會是零。則硬碟會是80h。這要自己判斷，可以先假設為80h，若是int 13，call完後carry flag on，則為錯誤，這時就可以判斷為被當作是floppy。判斷完了以後，就把要load in的os所在partition的bootsector抓出來放到0x0000:0x7c00處，並且jmp過去，他bootsector裡面的&lt;span style="color: rgb(255, 0, 0);"&gt;NTLoader&lt;/span&gt;(Windows PE) or &lt;span style="color: rgb(255, 0, 0);"&gt;SYSlinux&lt;/span&gt;(GParted linux)就會幫你做loader OS的動作。看完了以後就知道，我是用偷懶的方式，用chainloading load進相對的bootloader。真正的bootloader是不好寫的，以linux為例，要去/doc底下看boot protocol。才知道linux kernel要抓到哪個相對的位置。&lt;br /&gt;&lt;br /&gt;首先下面這個是&lt;span style="color: rgb(51, 51, 255);"&gt;Makefile&lt;/span&gt;&lt;br /&gt;CC=gcc&lt;br /&gt;LD=ld&lt;br /&gt;OBJCOPY=objcopy&lt;br /&gt;&lt;br /&gt;CFLAGS=-c&lt;br /&gt;TRIM_FLAGS=-R .pdr -R .comment -R.note -S -O binary&lt;br /&gt;&lt;br /&gt;LDFILE_BOOT=solrex_x86_boot.ld&lt;br /&gt;LDFILE_DOS=solrex_x86_dos.ld&lt;br /&gt;LDFLAGS_BOOT=-e c -T$(LDFILE_BOOT)&lt;br /&gt;LDFLAGS_DOS=-e c -T$(LDFILE_DOS)&lt;br /&gt;&lt;br /&gt;all: boot.img LOADER.BIN&lt;br /&gt;&lt;br /&gt;boot.bin: boot.S&lt;br /&gt;$(CC) $(CFLAGS) boot.S&lt;br /&gt;$(LD) boot.o -o boot.elf $(LDFLAGS_BOOT)&lt;br /&gt;$(OBJCOPY) $(TRIM_FLAGS) boot.elf $@&lt;br /&gt;&lt;br /&gt;LOADER.BIN: loader.S&lt;br /&gt;$(CC) $(CFLAGS) loader.S&lt;br /&gt;$(LD) loader.o -o loader.elf $(LDFLAGS_DOS)&lt;br /&gt;$(OBJCOPY) $(TRIM_FLAGS) loader.elf $@&lt;br /&gt;#&lt;span style="color: rgb(255, 0, 0);"&gt;下面這邊可以看到編完的loader.bin是接在boot.bin的後面&lt;/span&gt;&lt;br /&gt;boot.img: boot.bin LOADER.BIN&lt;br /&gt;dd if=boot.bin of=boot.img bs=512 count=1&lt;br /&gt;dd if=LOADER.BIN of=boot.img seek=1 bs=512 count=1&lt;br /&gt;&lt;br /&gt;# You must have the authority to do mount, or you must use "su root" or&lt;br /&gt;# "sudo" command to do "make copy"&lt;br /&gt;copy: boot.img&lt;br /&gt;&lt;br /&gt;clean:&lt;br /&gt;@rm -f *.o *.elf *.bin *.BIN&lt;br /&gt;&lt;br /&gt;再下來是&lt;span style="color: rgb(51, 51, 255);"&gt;solrex_x86_boot.ld&lt;/span&gt;，因為一開機時是0x0000:0x7c00所以要offset 0x7c00。&lt;br /&gt;SECTIONS&lt;br /&gt;{&lt;br /&gt;. = &lt;span style="color: rgb(255, 0, 0);"&gt;0x7c00&lt;/span&gt;;&lt;br /&gt;.text :&lt;br /&gt;{&lt;br /&gt;_ftext = .;&lt;br /&gt;} = 0&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;solrex_x86_dos.ld&lt;/span&gt;(因為是放在0x9000:0x0000所以offset 0x0000)&lt;br /&gt;其實這邊如果為了要在dos下面的debug.exe可以run，則可以改成0x0100。&lt;br /&gt;前面的100是program segment prefix。放一些類似命令列參數的資料。&lt;br /&gt;SECTIONS&lt;br /&gt;{&lt;br /&gt;. = &lt;span style="color: rgb(255, 0, 0);"&gt;0x0000&lt;/span&gt;;&lt;br /&gt;.text :&lt;br /&gt;{&lt;br /&gt;_ftext = .;&lt;br /&gt;} = 0&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;再來就是第一支code &lt;span style="color: rgb(51, 51, 255);"&gt;boot.S&lt;/span&gt;，真的不長啦，很簡單！&lt;br /&gt;.code16&lt;br /&gt;.set    BaseOfStack,     0x7c00    /* Stack base address, inner */&lt;br /&gt;.set    BaseOfLoader,    0x9000    /* Section loading address of LOADER.S */&lt;br /&gt;.set    OffsetOfLoader,  0x0000    /* Loading offset of LOADER.S */&lt;br /&gt;.text&lt;br /&gt;jmp     LABEL_START /* Start to boot. */&lt;br /&gt;BS_DrvNum:          .byte   0x80          /* Driver number of interrupt 13 */&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/* Initial registers. */&lt;br /&gt;LABEL_START:&lt;br /&gt;mov     %cs,%ax&lt;br /&gt;mov     %ax,%ds&lt;br /&gt;mov     %ax,%es&lt;br /&gt;mov     %ax,%ss&lt;br /&gt;mov     $BaseOfStack, %sp&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/* Reset floppy &lt;span style="color: rgb(255, 0, 0);"&gt;把磁頭歸零&lt;/span&gt;*/&lt;br /&gt;xor     %ah,%ah&lt;br /&gt;xor     %dl,%dl       /* %dl=0: floppy driver 0 */&lt;br /&gt;int     $0x13         /* BIOS int 13h, ah=0: Reset driver 0 */&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;    //我們這邊是用int 13h extension所以si那邊指向一個結構。&lt;/span&gt;&lt;br /&gt;mov     $0x80,%dl&lt;br /&gt;mov     $0x42,%ah&lt;br /&gt;mov     $(HardPacket),%si&lt;br /&gt;int     $0x13&lt;br /&gt;&lt;br /&gt;jmp     $BaseOfLoader,$OffsetOfLoader&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;//因為第二支code是放在usb mbr後面的第二個sector，所以是0x00000001&lt;/span&gt;&lt;br /&gt;HardPacket:&lt;br /&gt;size_packet:    .byte    0x10&lt;br /&gt;reserved:    .byte    0&lt;br /&gt;SectorToTran:    .2byte    1&lt;br /&gt;Offset:        .2byte    OffsetOfLoader&lt;br /&gt;Segment:    .2byte  BaseOfLoader&lt;br /&gt;SectorLow:    .4byte    &lt;span style="color: rgb(255, 0, 0);"&gt;0x00000001&lt;/span&gt;&lt;br /&gt;SectorHigh:    .4byte    0&lt;br /&gt;&lt;br /&gt;.org 510        /* Skip to address 0x510. */&lt;br /&gt;.2byte 0xaa55   /* Write boot flag to 1st sector(512 bytes) end */&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;Loader.S&lt;/span&gt;&lt;br /&gt;.code16&lt;br /&gt;.set    BaseOfLoader,    0x0000&lt;br /&gt;.set    OffsetOfLoader,    0x7C00&lt;br /&gt;.text&lt;br /&gt;LabelStart:&lt;br /&gt;&lt;br /&gt;mov    %cs,%ax&lt;br /&gt;mov    %ax,%ds&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;    //我們的硬碟是第二顆，因為usb是第一顆，所以硬碟代號是0x81h&lt;/span&gt;&lt;br /&gt;mov    $(HardDPacket),%si&lt;br /&gt;mov    $&lt;span style="color: rgb(255, 0, 0);"&gt;0x81&lt;/span&gt;,%dl&lt;br /&gt;mov    $0x42,%ah&lt;br /&gt;int    $0x13&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;    //把硬碟bootsector放到9000:0200以後開始比對，第四個byte 0x0203。&lt;/span&gt;&lt;br /&gt;mov    $0x0203,%si&lt;br /&gt;cld&lt;br /&gt;mov    $CompS,%di&lt;br /&gt;mov    %ds,%ax&lt;br /&gt;mov    %ax,%es&lt;br /&gt;mov    $4,%cx   &lt;span style="color: rgb(255, 0, 0);"&gt;//因為四個字"NTFS"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;CompNTFS:&lt;br /&gt;cmp    $0,%cx&lt;br /&gt;jz    EQUAL&lt;br /&gt;dec    %cx&lt;br /&gt;lodsb&lt;br /&gt;cmp    %bl,%al&lt;br /&gt;jz    KeepGoingComp&lt;br /&gt;jmp    DIFFERENT&lt;br /&gt;&lt;br /&gt;KeepGoingComp:&lt;br /&gt;inc    %di&lt;br /&gt;jmp    CompNTFS&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;//如果比對後等於"NTFS"，則載入第一個partition也就是windows PE。&lt;/span&gt;&lt;br /&gt;EQUAL:&lt;br /&gt;mov    $HardPacket,%di&lt;br /&gt;add    $8,%di&lt;br /&gt;mov    $0,%bx&lt;br /&gt;mov    %bx,%ds&lt;br /&gt;mov    $0x7c00,%si&lt;br /&gt;add    $0x&lt;span style="color: rgb(255, 0, 0);"&gt;1C6&lt;/span&gt;,%si&lt;br /&gt;mov    %ds:(%si),%eax&lt;br /&gt;mov    %eax,%es:(%di)&lt;br /&gt;jmp    DONE&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;//不同則是第二個partition。&lt;/span&gt;&lt;br /&gt;DIFFERENT:&lt;br /&gt;mov    $HardPacket,%di&lt;br /&gt;add    $8,%di&lt;br /&gt;mov    $0,%bx&lt;br /&gt;mov    %bx,%ds&lt;br /&gt;mov    $0x7c00,%si&lt;br /&gt;add    $0x&lt;span style="color: rgb(255, 0, 0);"&gt;1D6&lt;/span&gt;,%si&lt;br /&gt;mov    %ds:(%si),%eax&lt;br /&gt;mov    %eax,%es:(%di)&lt;br /&gt;&lt;br /&gt;DONE:&lt;br /&gt;mov    %cs,%bx&lt;br /&gt;mov    %bx,%ds&lt;br /&gt;mov    $(HardPacket),%si    /* ds:si--&gt; offset of disk information */&lt;br /&gt;mov    $0x80,%dl            /* Drive number of floppy disk */&lt;br /&gt;mov    $0x42,%ah&lt;br /&gt;&lt;br /&gt;int    $0x13&lt;br /&gt;&lt;br /&gt;jmp    $BaseOfLoader,$OffsetOfLoader&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;//要比對的那顆硬碟的bootsector，載入後放在9000:0200。硬碟上的第一個partition原則上&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;//初始位置都是在0x0000003F&lt;/span&gt;&lt;br /&gt;HardDPacket:&lt;br /&gt;        .byte    0x10&lt;br /&gt;        .byte    0&lt;br /&gt;        .2byte    1&lt;br /&gt;        .2byte    0x&lt;span style="color: rgb(255, 0, 0);"&gt;0200&lt;/span&gt;&lt;br /&gt;        .2byte    0x&lt;span style="color: rgb(255, 0, 0);"&gt;9000&lt;/span&gt;&lt;br /&gt;        .4byte    0x&lt;span style="color: rgb(255, 0, 0);"&gt;0000003F&lt;/span&gt;&lt;br /&gt;        .4byte    0&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;//這個就是我們最後載入OS loader的詳細資訊了。&lt;/span&gt;&lt;br /&gt;HardPacket:&lt;br /&gt;size_packet:    .byte    0x10&lt;br /&gt;reserved:    .byte    0&lt;br /&gt;SectorToTran:    .2byte    1&lt;br /&gt;Offset:        .2byte    &lt;span style="color: rgb(255, 0, 0);"&gt;0x0000&lt;/span&gt;&lt;br /&gt;Segment:    .2byte    &lt;span style="color: rgb(255, 0, 0);"&gt;0x07C0&lt;/span&gt;&lt;br /&gt;SectorLow:    .4byte    &lt;span style="color: rgb(255, 0, 0);"&gt;0x00000000&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;//這個位置會依照partition table裡面的值來填&lt;/span&gt;&lt;br /&gt;SectorHigh:    .4byte    0&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;CompS:        .ascii    "NTFS"&lt;br /&gt;.org 512&lt;br /&gt;&lt;br /&gt;其實寫bootloader最麻煩的就是debug，原本的code我裡面加了很多的print message所以比較長，這邊為了要容易理解，所以把那些code全部都拿掉了。如果想要debug可以把link script裡".=0x7c00"這行改成".=0x0100"，之後副檔名設為.com就可以在dos底下run，就算不改成.com也可以直接debug。改成".=0x0100"是因為com格式的檔案，在被載到記憶體run的時候最前面有一個128 bytes Program Segment Prefix，可知dos在分配記憶體空間時，後面的offset都是從零開始。且在com檔裡code segment 和 data segment是合在一起的。執行檔案大小不可超過64k。&lt;br /&gt;&lt;br /&gt;這邊再記錄一下linker的原理，以免忘掉。因為最近又要開始趕touch panel，恐怕以後沒有時間再摸這塊了。這邊".=0x7c00"可以想想看他的原理，先看看開機的時候cs=0x0000, ip=0x7c00。因為寫好的code裡面變數儲存都是根據相對的位置。假設一個變數宣告在整個檔案的0x3位置。而在開機的時候binary被load進0000:7c00，此時變數的相對位置便為0000:7c03。&lt;br /&gt;這個資訊在compile時期是看不到的，在object file裡頭看到的還是0x3相對位置，在link以後才會變成0x7c03。可以用objdump來查看原本被組譯的二進位檔，如:"objdump boot.o -d -M data16,addr16"這些檔案是沒有絕對位置的資訊。當link後的binary，可以用winhex或是khexedit來看。&lt;br /&gt;&lt;br /&gt;##說明上面兩段code的link運作原理。&lt;br /&gt;起先因為我們知道一開機的時候，MBR裡面的code是被放到cs:ip = 0000:7c00的地方。所以第一段code的solrex_x86_boot.ld linker script裡面".=0x7c00"就是這樣來的。後來，我們的第二段code是接在MBR後面的一個sector。預設會load到9000:0000，因此solrex_x86_dos.ld裡面會寫成".=0x0000"。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-4937422541861254179?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/4937422541861254179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=4937422541861254179' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/4937422541861254179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/4937422541861254179'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/11/multiboot-usb-bootloader.html' title='Multiboot USB Bootloader'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_r6LKRJP8V4w/STOVuwFmyXI/AAAAAAAAAHs/exBOiueX3-U/s72-c/multiboot.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-6213235007283531549</id><published>2008-11-14T00:35:00.000-08:00</published><updated>2009-04-28T00:01:28.452-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>USB多重開機的作法(winpe, linux)</title><content type='html'>&lt;span style="color: rgb(255, 0, 0);"&gt;第一步&lt;/span&gt;(這一步也可以用linux底下的fdisk)&lt;br /&gt;首先為了能在windows底下對隨身碟做磁碟分割，要先把本身隨身碟的driver取代掉。&lt;br /&gt;&lt;br /&gt;執行regedit找到 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\USBSTOR\&lt;br /&gt;          裏面有 Disk&amp;amp;Ven_xxxxxxxxxxxxxxxxxxxxxxxxx，找到要格式化的隨身碟，並進去&lt;br /&gt;          選 Hardware ID-&gt;按右鍵-&gt;編輯, copy第一行&lt;br /&gt;&lt;br /&gt;編輯Hitachi Microdrive Filter cfadisk.inf , 找到 [cfadisk_device]&lt;br /&gt;         底下的項目全部刪除 , 並加入一行&lt;br /&gt;            %MicroDrive_devdesc% = cfadisk_install,XXXXXXXX (剛剛copy的文字)&lt;br /&gt;      &lt;br /&gt;&lt;br /&gt;到裝置管理員,找到磁碟機/"usb的名稱", 強行變更 driver 為 剛剛修改的 cfadisk.inf&lt;br /&gt;&lt;br /&gt;之後到我的電腦看到的隨身碟名稱，就會變成硬碟的圖示，而不是usb可移除隨身碟的圖示。&lt;br /&gt;接下來就可以進行格式化了。到設定-&gt;控制台-&gt;系統管理工具-&gt;電腦管理-&gt;存放-&gt;磁碟管理。&lt;br /&gt;然後選擇你要format的磁碟機，按右鑑，刪除磁碟分割。之後再按右鍵，新增磁碟分割。在這裡你可以新增兩個磁碟分割，一個擺放winpe，另一個擺放linux。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;第二步&lt;/span&gt;&lt;br /&gt;為了要做到多重開機，你必須先在MBR裡頭安裝GRUB4DOS：&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;1.&lt;/span&gt; 到&lt;a href="http://download.gna.org/grubutil/"&gt;這裡&lt;/a&gt;下載 &lt;a href="http://download.gna.org/grubutil/grubinst-1.1-bin-w32-2008-01-01.zip"&gt;grubinst-1.1-bin-w32-2008-01-01.zip&lt;/a&gt;&lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;&lt;a href="http://download.gna.org/grubutil/"&gt; &lt;/a&gt;這個東西，再到&lt;a href="http://download.gna.org/grub4dos/"&gt;這邊&lt;/a&gt;下載&lt;a href="http://download.gna.org/grub4dos/grub4dos-0.4.3-2008-03-14.zip"&gt;grub4dos-0.4.3-2008-03-14.zip&lt;/a&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;2.&lt;/span&gt; 開啟grubinst裡頭的grubinst_gui.exe，選擇disk為你要的磁碟機，再來因為我們要把grub裝在MBR裡，所以選擇part list為MBR，再來按下install就會開始安裝。&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;3.&lt;/span&gt; 安裝完畢後，必須要把grub4dos-0.4.3裡的menu.lst和grldr兩個檔案，放到第一個partition內。&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;4&lt;/span&gt;. 把menu.lst改成下面這樣&lt;br /&gt;# This is a sample menu.lst file. You should make some changes to it.&lt;br /&gt;# The old install method of booting via the stage-files has been removed.&lt;br /&gt;# Please install GRLDR boot strap code to MBR with the bootlace.com&lt;br /&gt;# utility under DOS/Win9x or Linux.&lt;br /&gt;&lt;br /&gt;color black/cyan yellow/cyan&lt;br /&gt;timeout 30&lt;br /&gt;default /default&lt;br /&gt;&lt;code class="c"&gt;&lt;br /&gt;title Windows PE&lt;br /&gt;&lt;br /&gt;hide (hd0,1)&lt;br /&gt;unhide (hd0,0)&lt;br /&gt;rootnoverify (hd0,0)&lt;br /&gt;makeactive&lt;br /&gt;chainloader +1&lt;br /&gt;&lt;br /&gt;title Linux&lt;br /&gt;&lt;br /&gt;hide (hd0,0)&lt;br /&gt;unhide (hd0,1)&lt;br /&gt;rootnoverify (hd0,1)&lt;br /&gt;makeactive&lt;br /&gt;chainloader +1&lt;/code&gt;&lt;br /&gt;很明顯的，我們就是要在第一個partition安裝winpe，在第二個partition安裝linux。&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;第三步&lt;/span&gt;(下面step 1也可以用dd來做，就不用一定要到windows底下做)&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;1.&lt;/span&gt; 製做winpe可開機分割區。因為我們拿到的winpe image是放在可開機的usb碟。所以使用程式winhex:Tools-&gt;disk tools -&gt; clone disk，就可以選擇來源為已經做好的win pe usb碟，目的地選擇第一個logical partition，記得目的的partition要大於來源的partition才可以clone。&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;2.&lt;/span&gt; 首先要先在linux上面安裝syslinux + mtools&lt;br /&gt;sudo apt-get install mtools&lt;br /&gt;sudo apt-get install syslinux&lt;br /&gt;&lt;br /&gt;接下來到&lt;a href="http://sourceforge.net/project/showfiles.php?group_id=115843&amp;amp;package_id=195292"&gt;這邊&lt;/a&gt;&lt;br /&gt;下載Gparted LiveUsb。&lt;br /&gt;&lt;br /&gt;再來我們要對隨身碟做安裝Syslinux的動作，在這個動作進行之前記得將usb碟umount：syslinux /dev/sdxx(sdxx是你的第二個邏輯分割區)，這邊做完了以後，已經可以進行開機了，但在開機時會秀出找不到kernel的訊息。&lt;br /&gt;補充:可以到&lt;a href="http://ftp.ntu.edu.tw/linux/boot/syslinux/"&gt;這裡&lt;/a&gt;去 下載Syslinux的程式，解開後再win32資料夾裡會有syslinux.exe，也有syslinux的source code。在xp底下可以開啟終端機，接著再到syslinux.exe的目錄底下，用"syslinux.exe f:"就可以成功的安裝syslinux。&lt;br /&gt;&lt;br /&gt;完成之後把下載下來的gparted-liveusb-0.3.1-1.zip解壓縮。得到下面的檔案&lt;br /&gt;boot.cat&lt;br /&gt;boot.msg&lt;br /&gt;gparted&lt;br /&gt;initrd.gz&lt;br /&gt;linux&lt;br /&gt;splash.lss&lt;br /&gt;syslinux.cfg&lt;br /&gt;總共有七個。&lt;br /&gt;把檔案直接copy進usb碟即可。&lt;br /&gt;&lt;br /&gt;reference:&lt;br /&gt;&lt;a href="http://www.911cd.net/forums//index.php?showtopic=18846"&gt;&lt;span style="font-size:100%;"&gt;&lt;u&gt;&lt;b&gt;&lt;span style="font-size: 24pt; line-height: 100%;"&gt;Guide for Multi-booting from a USB Drive&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.mobile01.com/print.php?f=233&amp;amp;t=455291&amp;amp;p=1"&gt;&lt;span class="rb16"&gt;&lt;成功EEEPC 雙系統 &gt; SSD 裝 Linux; SD裝XP&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ubuntu-tw.org/modules/newbb/viewtopic.php?topic_id=5745&amp;amp;forum=11&amp;amp;post_id=25239#forumpost25239"&gt; 如何使隨身碟能開機的方法&lt;/a&gt;&lt;br /&gt;&lt;h3 class="post-title entry-title"&gt;&lt;a href="http://semson.blogspot.com/2007/12/boot-manager-grub4dos.html"&gt;免費好用的 boot manager 何處尋 -- grub4dos 篇&lt;/a&gt;&lt;/h3&gt;&lt;a href="http://tw.myblog.yahoo.com/noname-team/article?mid=833&amp;amp;prev=929&amp;amp;next=768&amp;amp;page=1&amp;amp;sc=1#yartcmt"&gt;&lt;span&gt;在硬碟上跑 XPE (RAMDISK)---感謝網友金田一提供教學&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;h1&gt;&lt;a href="http://www.53vi.com/system/windows/20080424/2652_2.html"&gt;grub4dos初级教程 - 入门篇&lt;/a&gt;&lt;/h1&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="float: left;"&gt;&lt;a href="http://blog.teatime.com.tw/1/post/277"&gt; &lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="float: left;"&gt;&lt;a href="http://blog.teatime.com.tw/1/post/277"&gt; &lt;/a&gt;&lt;/span&gt;&lt;span style="float: left;"&gt;&lt;a href="http://blog.teatime.com.tw/1/post/277"&gt; &lt;/a&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-6213235007283531549?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/6213235007283531549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=6213235007283531549' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/6213235007283531549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/6213235007283531549'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/11/usbwinpe-linux.html' title='USB多重開機的作法(winpe, linux)'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-2366494777548506890</id><published>2008-11-10T23:04:00.000-08:00</published><updated>2008-11-13T23:15:18.560-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><title type='text'>自己動手寫作業系統 第二章bootloader範例</title><content type='html'>這是拜讀對岸高手Solrex所著&lt;a href="http://share.solrex.cn/WriteOS/download.php"&gt;自己動手寫作業系統&lt;/a&gt;之後的心得。&lt;br /&gt;下面是第二章的sample code。作為在閱讀這本書時的筆記。&lt;br /&gt;這段code做的事情為，在boot sector內寫一個程式，之後把另外一個loader名為&lt;br /&gt;"loader.bin"從fat12 file system裡頭找出來並且load到記憶體位置9000:0100的&lt;br /&gt;地方之後jmp過去開始run。如果你無聊，loader.bin裡頭可以秀一段hello world字串。&lt;br /&gt;&lt;br /&gt;完成了這段code以後，用它書裡頭的方法，先把這個image在linux底下mount起來&lt;br /&gt;。之後因為裡面有fat12 file system，所以可以把loader.bin copy到mount的資料夾內，&lt;br /&gt;這樣linux就會自動去把loader.bin加到我們的file system。umount以後，我再用windows&lt;br /&gt;底下的vmware新增一個floppy的Device，把掛載的映像檔，設為我們的image，再用vmware開啟。&lt;br /&gt;&lt;br /&gt;同時實驗後發現了用usb開機也是可行的，這樣就可以用usb開啟自己寫的bootloader了。&lt;br /&gt;首先，把image從usb的MBR開始位置用winhex寫入。因為在eeepc底下，&lt;br /&gt;usb開機被視為floppy disk，所以可以用int 13 , dl = 0去讀取sector。&lt;br /&gt;winhex的寫入法有兩種，&lt;span style="color: rgb(255, 0, 0);"&gt;第一種&lt;/span&gt;把我們要copy的磁區先反白起來，接著ctrl+c,然後&lt;br /&gt;切換到要貼上的磁碟磁區，把滑鼠游標移到第一個Byte，ctrl + b。&lt;span style="color: rgb(255, 0, 0);"&gt;第二種&lt;/span&gt;是用winhex&lt;br /&gt;中的tools -&gt; disk tools -&gt; clone disk。就可以選擇來源檔案為我們的image，目的選&lt;br /&gt;usb實體磁碟機(不能選logical disk不然會寫到partition的boot sector去)。或是你要&lt;br /&gt;在linux底下用&lt;span style="color: rgb(255, 0, 0);"&gt;dd&lt;/span&gt;也是可以。&lt;br /&gt;&lt;br /&gt;一開始所需要的必備知識就是&lt;span style="color: rgb(255, 0, 0);"&gt;GAS組語的語法&lt;/span&gt;，和&lt;span style="color: rgb(255, 0, 0);"&gt;FAT的格式&lt;/span&gt;。&lt;br /&gt;GAS的語法，網路上很多可以搜尋一下，或者這個bootsector多看幾次就會了解。&lt;br /&gt;至於file system可以參考我的另外一篇文章&lt;a href="http://bboytaiwan.blogspot.com/2008/10/fat-series-file-system.html"&gt;FAT系列檔案系統&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_r6LKRJP8V4w/SR0ihOzkOwI/AAAAAAAAAHk/esRKlfa2FcQ/s1600-h/mmp.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 299px;" src="http://4.bp.blogspot.com/_r6LKRJP8V4w/SR0ihOzkOwI/AAAAAAAAAHk/esRKlfa2FcQ/s400/mmp.JPG" alt="" id="BLOGGER_PHOTO_ID_5268405093398756098" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;/* chapter2/2/boot.S&lt;br /&gt;&lt;br /&gt;Author: Wenbo Yang &lt;solrex@gmail.com&gt; &lt;http: cn=""&gt;&lt;br /&gt;&lt;br /&gt;This file is part of the source code of book "Write Operating System with&lt;br /&gt;Free Software". The latest version, see &lt;http: cn="" writeos=""&gt;.&lt;br /&gt;&lt;br /&gt;This file is licensed under the GNU General Public License; either&lt;br /&gt;version 3 of the License, or (at your option) any later version. */&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;.code16 &lt;span style="color: rgb(51, 51, 255);"&gt;//因&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;為一開機是Real mode所以是以16 bits為定址模式&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;.set    BaseOfStack,     0x7c00    /* Stack base address, inner */&lt;br /&gt;.set    BaseOfLoader,    0x9000    /* Section loading address of LOADER.BIN */&lt;br /&gt;.set    OffsetOfLoader,  0x0100    /* Loading offset of LOADER.BIN */&lt;br /&gt;.set    RootDirSectors,  14        /* Root directory sector count */&lt;br /&gt;.set    SecNoOfRootDir,  19        /* 1st sector of root directory */&lt;br /&gt;.set    SecNoOfFAT1,     1         /* 1st sector of FAT1 */&lt;br /&gt;.set    DeltaSecNo,      17        /* BPB_(RsvdSecCnt+NumFATs*FATSz) -2 */&lt;br /&gt;/* Start sector of file space =*/&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;.text &lt;span style="color: rgb(51, 51, 255);"&gt;//這邊是程式開始&lt;br /&gt;//&lt;/span&gt;&lt;/span&gt;&lt;/http:&gt;&lt;/http:&gt;&lt;/solrex@gmail.com&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;前面的這些欄位是BPB(Bios Parameter Block)儲存後面程式用的到的變數&lt;/span&gt;&lt;solrex@gmail.com&gt;&lt;http: cn=""&gt;&lt;http: cn="" writeos=""&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;/* Floppy header of FAT12 */&lt;br /&gt;jmp     LABEL_START /* Start to boot. */&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;nop&lt;/span&gt;                 /* nop required &lt;span style="color: rgb(51, 51, 255);"&gt;因為前面是三個bytes所以還需要一個nop來湊&lt;/span&gt;*/&lt;br /&gt;BS_OEMName:         .ascii  "WB. YANG"    /* OEM String, 8 bytes required */&lt;br /&gt;BPB_BytsPerSec:     .2byte  512           /* Bytes per sector */&lt;br /&gt;BPB_SecPerCluse:    .byte   1             /* Sector per cluse */&lt;br /&gt;BPB_ResvdSecCnt:    .2byte  1             /* Reserved sector count */&lt;br /&gt;BPB_NumFATs:        .byte   2             /* Number of FATs */&lt;br /&gt;BPB_RootEntCnt:     .2byte  224           /* Root entries count */&lt;br /&gt;BPB_TotSec16:       .2byte  2880          /* Total sector number */&lt;br /&gt;BPB_Media:          .byte   0xf0          /* Media descriptor */&lt;br /&gt;BPB_FATSz16:        .2byte  9             /* FAT size(sectors) */&lt;br /&gt;BPB_SecPerTrk:      .2byte  18            /* Sector per track */&lt;br /&gt;BPB_NumHeads:       .2byte  2             /* Number of magnetic heads */&lt;br /&gt;BPB_HiddSec:        .4byte  0             /* Number of hidden sectors */&lt;br /&gt;BPB_TotSec32:       .4byte  0             /* If TotSec16 equal 0, this works */&lt;br /&gt;BS_DrvNum:          .byte   0             /* Driver number of interrupt 13 */&lt;br /&gt;BS_Reserved1:       .byte   0             /* Reserved */&lt;br /&gt;BS_BootSig:         .byte   0x29          /* Boot signal */&lt;br /&gt;BS_VolID:           .4byte  0             /* Volume ID */&lt;br /&gt;BS_VolLab:          .ascii  "Solrex 0.01" /* Volume label, 11 bytes required */&lt;br /&gt;BS_FileSysType:     .ascii  "FAT12   "    /* File system type, 8 bytes required */&lt;br /&gt;&lt;br /&gt;/* Initial registers. */&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//因為在一開機時只有cs有被填值，其他的segment register要靠自己填&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 153, 51);"&gt;LABEL_START&lt;/span&gt;:&lt;br /&gt;mov     %cs,%ax&lt;br /&gt;mov     %ax,%ds&lt;br /&gt;mov     %ax,%es&lt;br /&gt;mov     %ax,%ss&lt;br /&gt;mov     $BaseOfStack, %sp    &lt;span style="color: rgb(51, 51, 255);"&gt; //BaseOfStack = 0x7c00，很明顯stack就是從0x7c00往下減&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;/* Clear screen */&lt;br /&gt;mov     $0x0600,%ax   /* %ah=6, %al=0 */&lt;br /&gt;mov     $0x0700,%bx   /* Black white */&lt;br /&gt;mov     $0,%cx        /* Top left: (0,0) */&lt;br /&gt;mov     $0x184f,%dx   /* Bottom right: (80,50) */&lt;br /&gt;int     $0x10         /* BIOS int 10h, ah=6: Initialize screen */&lt;br /&gt;&lt;br /&gt;/* Display "Booting**" */&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//它下面有三個字串，每個分別都是九個bytes那麼大。而第零個就是booting**&lt;/span&gt;&lt;br /&gt;mov     $0,%dh&lt;br /&gt;call    DispStr       /* Display string(index 0)*/&lt;br /&gt;&lt;br /&gt;/* Reset floppy */&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//這邊我也不知道為什麼要重設floppy&lt;/span&gt;&lt;br /&gt;xor     %ah,%ah&lt;br /&gt;xor     %dl,%dl       /* %dl=0: floppy driver 0 */&lt;br /&gt;int     $0x13         /* BIOS int 13h, ah=0: Reset driver 0 */&lt;br /&gt;&lt;br /&gt;/* Find LOADER.BIN in root directory of driver 0 */&lt;br /&gt;&lt;/http:&gt;&lt;/http:&gt;&lt;/solrex@gmail.com&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//在下面可以看到SecNoOfRootDir = 19，而實際上是第20個sectors，因為從零開始。&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//因為wSectorNo是&lt;span style="color: rgb(255, 0, 0);"&gt;變數&lt;/span&gt;所以用&lt;span style="color: rgb(255, 0, 0);"&gt;括號&lt;/span&gt;。而SecNoOfRootDir是被define的所以用"&lt;span style="color: rgb(255, 0, 0);"&gt;$&lt;/span&gt;"的符號。&lt;/span&gt;&lt;br /&gt;&lt;solrex@gmail.com&gt;&lt;http: cn=""&gt;&lt;http: cn="" writeos=""&gt;    movw    $SecNoOfRootDir, (wSectorNo)&lt;br /&gt;&lt;br /&gt;/* Read root dir sector to memory */&lt;br /&gt;&lt;span style="color: rgb(204, 153, 51);"&gt;LABEL_SEARCH_IN_ROOT_DIR_BEGIN&lt;/span&gt;:&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//wRootDirSizeForLoop=14因為整個Root Directory只有14個sectors這麼大&lt;br /&gt;&lt;/span&gt;   cmpw    $0,(wRootDirSizeForLoop)    /* If searching in root dir */&lt;br /&gt;jz      LABEL_NO_LOADERBIN          /* can find  LOADER.BIN ?   */&lt;br /&gt;decw    (wRootDirSizeForLoop)&lt;br /&gt;mov     $BaseOfLoader,%ax&lt;br /&gt;mov     %ax,%es                     /* %es &lt;- BaseOfLoader*/    &lt;br /&gt;mov     $OffsetOfLoader,%bx         /* %bx &lt;- OffsetOfLoader */   &lt;br /&gt;mov     (wSectorNo),%ax             /* %ax &lt;- sector number in root */&lt;br /&gt;  mov     $1,%cl &lt;span style="color: rgb(51, 51, 255);"&gt;    //cl是儲存一次要讀幾個Sectors到es:bx去&lt;/span&gt;&lt;br /&gt;call    ReadSector     &lt;span style="color: rgb(51, 51, 255);"&gt;//呼叫完了以後要讀取的Sector就會被copy到es:bx&lt;/span&gt;&lt;br /&gt;mov     $LoaderFileName,%si         /* %ds:%si -&gt; LOADER  BIN */&lt;br /&gt;mov     $OffsetOfLoader,%di         /* BaseOfLoader&lt;&lt;4+100*/&gt; %al*/&lt;br /&gt;cld  &lt;span style="color: rgb(51, 51, 255);"&gt;//這邊清除了direction以後，後面的lodsb才會以遞增的方式去load&lt;/span&gt;&lt;br /&gt;mov     $0x10,%dx  &lt;span style="color: rgb(51, 51, 255);"&gt;//2^9 / 2^5 = 16 因為一個sector 512 bytes，一個root entry 32 bytes&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;/* Search for "LOADER  BIN", FAT12 save file name in 12 bytes, 8 bytes for&lt;br /&gt;file name, 3 bytes for suffix, last 1 bytes for '\20'. If file name is&lt;br /&gt;less than 8 bytes, filled with '\20'. So "LOADER.BIN" is saved as:&lt;br /&gt;"LOADER  BIN"(4f4c 4441 5245 2020 4942 204e).&lt;br /&gt;*/&lt;br /&gt;&lt;span style="color: rgb(204, 153, 51);"&gt;LABEL_SEARCH_FOR_LOADERBIN&lt;/span&gt;:&lt;br /&gt;cmp     $0,%dx                      /* Read control */&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//一個Sector如果16個root entry都讀完了當然就讀下個sector&lt;/span&gt;&lt;br /&gt;jz      LABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR&lt;br /&gt;dec     %dx&lt;br /&gt;mov     $11,%cx  &lt;span style="color: rgb(51, 51, 255);"&gt;//每個entry的最前面11個bytes就是檔名&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 153, 51);"&gt;LABEL_CMP_FILENAME&lt;/span&gt;:&lt;br /&gt;cmp     $0,%cx   &lt;span style="color: rgb(51, 51, 255);"&gt;//如果全部比完了，當然就是找到&lt;/span&gt;&lt;br /&gt;jz      LABEL_FILENAME_FOUND    /* If 11 chars are all identical? */&lt;br /&gt;dec     %cx&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//這個的lodsb就會把ds:si的值放到al去，並且由於"cld"的原因所以遞增一&lt;/span&gt;&lt;br /&gt;lodsb                           /* %ds:(%si) -&gt; %al*/&lt;br /&gt;cmp     %es:(%di),%al   &lt;span style="color: rgb(51, 51, 255);"&gt;//es:di就是我們所要比對的root entry&lt;/span&gt;&lt;br /&gt;jz      LABEL_GO_ON&lt;br /&gt;jmp     LABEL_DIFFERENT         /* Different */&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 153, 51);"&gt;LABEL_GO_ON&lt;/span&gt;:&lt;br /&gt;inc     %di&lt;br /&gt;jmp     LABEL_CMP_FILENAME      /* Go on loop */&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 153, 51);"&gt;LABEL_DIFFERENT&lt;/span&gt;:&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//因為只有後面的五個bits會用到2^5=32所以把di後面五個bits清掉&lt;br /&gt;//之後跳到下一個檔名繼續比對&lt;br /&gt;&lt;/span&gt;   and     $0xffe0,%di             /* Go to head of this entry */&lt;br /&gt;add     $0x20,%di&lt;br /&gt;mov     $LoaderFileName,%si     /* Next entry */&lt;br /&gt;jmp     LABEL_SEARCH_FOR_LOADERBIN&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 153, 51);"&gt;LABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR&lt;/span&gt;:&lt;br /&gt;addw    $1,(wSectorNo)    &lt;span style="color: rgb(51, 51, 255);"&gt;//這邊就是讀下一個Sector，所以把Sector number加一&lt;/span&gt;&lt;br /&gt;jmp     LABEL_SEARCH_IN_ROOT_DIR_BEGIN&lt;br /&gt;&lt;br /&gt;/* Not found LOADER.BIN in root dir. */&lt;br /&gt;&lt;span style="color: rgb(204, 153, 51);"&gt;LABEL_NO_LOADERBIN&lt;/span&gt;:&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//第三個字串&lt;/span&gt;&lt;/http:&gt;&lt;/http:&gt;&lt;/solrex@gmail.com&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;"No LOADER"&lt;/span&gt;&lt;br /&gt;&lt;solrex@gmail.com&gt;&lt;http: cn=""&gt;&lt;http: cn="" writeos=""&gt;  mov     $2,%dh&lt;br /&gt;call    DispStr         /* Display string(index 2) */&lt;br /&gt;jmp        .            /* Infinite loop */&lt;br /&gt;&lt;br /&gt;/* Found. */&lt;br /&gt;&lt;span style="color: rgb(204, 153, 51);"&gt;LABEL_FILENAME_FOUND&lt;/span&gt;:&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//RootDirSectors是14，DeltaSecNo是17，FAT表的前兩個欄位是系統欄位，不代表&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//檔案的資訊，所以第三個欄位也就是2，開始是代表第33號sector(實際上第34個)。&lt;br /&gt;//也就是Data的開始。&lt;/span&gt;&lt;br /&gt;mov     $RootDirSectors,%ax&lt;br /&gt;and     $0xffe0,%di             /* Start of current entry, 32 bytes per entry */&lt;br /&gt;add     $0x1a,%di               /* First sector of this file */&lt;br /&gt;mov     %es:(%di),%cx&lt;br /&gt;push    %cx                     /* Save index of this sector in FAT */&lt;br /&gt;add     %ax,%cx&lt;br /&gt;add     $DeltaSecNo,%cx         /* LOADER.BIN's start sector saved in %cl */&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//到這邊為止，要存取的Data放在哪個sector已經算好且放在cx裡面&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//接下來就是把ES:BX兩個register的值填好，再把cx放到ax裡，接下&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//來的code就可以呼叫ReadSector把Sector載入。&lt;/span&gt;&lt;br /&gt;mov     $BaseOfLoader,%ax&lt;br /&gt;mov     %ax,%es                 /* %es &lt;- BaseOfLoader */    &lt;br /&gt;mov     $OffsetOfLoader,%bx     /* %bx &lt;- OffsetOfLoader */   &lt;br /&gt;mov     %cx,%ax                 /* %ax &lt;- Sector number */ &lt;br /&gt;/* Load LOADER.BIN's sector's to memory. */ &lt;span style="color: rgb(204, 153, 51);"&gt;&lt;br /&gt;LABEL_GOON_LOADING_FILE&lt;/span&gt;:&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//抓幾個sectors就秀出幾個點&lt;/span&gt;&lt;br /&gt;push    %ax&lt;br /&gt;push    %bx&lt;br /&gt;mov     $0x0e,%ah&lt;br /&gt;mov     $'.',%al&lt;br /&gt;/* Char to print */&lt;br /&gt;mov     $0x0f,%bl   /* Front color: white */&lt;br /&gt;int     $0x10       /* BIOS int 10h, ah=0xe: Print char */&lt;br /&gt;pop     %bx&lt;br /&gt;pop     %ax&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//到這邊為止，前面這幾行印出一個點，都不重要&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//下面這行開始就要把剛剛填好的ax號sector抓到ES:BX內。&lt;/span&gt;&lt;br /&gt;mov     $1,%cl           &lt;span style="color: rgb(51, 51, 255);"&gt;//只抓一個sector&lt;/span&gt;&lt;br /&gt;call    ReadSector&lt;br /&gt;pop     %ax               &lt;span style="color: rgb(51, 51, 255);"&gt;//這邊pop出來的是剛剛存入的cx，代表現在在第幾個FAT欄位&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;/* Got index of this sector in FAT */&lt;br /&gt;call    GetFATEntry&lt;br /&gt;cmp     $0x0fff,%ax  &lt;span style="color: rgb(51, 51, 255);"&gt; //如果這個Fat欄位顯示結束就jmp&lt;/span&gt;&lt;br /&gt;jz      LABEL_FILE_LOADED&lt;br /&gt;push    %ax             /* Save index of this sector in FAT */&lt;br /&gt;mov     $RootDirSectors,%dx&lt;br /&gt;add     %dx,%ax&lt;br /&gt;add     $DeltaSecNo,%ax&lt;br /&gt;add     (BPB_BytsPerSec),%bx  &lt;span style="color: rgb(51, 51, 255);"&gt;//load完一個sector要把offset加上512bytes&lt;/span&gt;&lt;br /&gt;jmp     LABEL_GOON_LOADING_FILE&lt;br /&gt;&lt;span style="color: rgb(204, 153, 51);"&gt; LABEL_FILE_LOADED:   &lt;/span&gt;&lt;br /&gt;mov     $1,%dh     &lt;br /&gt;call    DispStr        /* Display string(index 1) */&lt;br /&gt;&lt;br /&gt;/*    Jump to LOADER.BIN's start address in memory. */&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//當然把loader.bin load到9000:0100也就是90100的位置就要jmp過去了&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;jmp     $BaseOfLoader,$OffsetOfLoader //(這邊是整個boot sector跳到loader.bin的地方)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;/*=================================    Variable table */&lt;br /&gt;&lt;br /&gt;wRootDirSizeForLoop:    .2byte  RootDirSectors&lt;br /&gt;wSectorNo:              .2byte  0       /* Sector number to read */&lt;br /&gt;bOdd:                   .byte   0       /* odd or even? */&lt;br /&gt;&lt;br /&gt;/* String table */&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 153, 51);"&gt;LoaderFileName: &lt;/span&gt;&lt;br /&gt;.asciz  "LOADER  BIN"        /* File name */&lt;br /&gt;.set    MessageLength,9&lt;br /&gt;BootMessage:        .ascii    "Booting**"        /* index 0 */&lt;br /&gt;Message1:           .ascii    "Loaded in"        /* index 1 */&lt;br /&gt;Message2:           .ascii    "No LOADER"        /* index 2 */&lt;br /&gt;&lt;br /&gt;/* Routine: DispStr    Action: Display a string, string index stored in %dh */&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 153, 51);"&gt;DispStr:      &lt;/span&gt;&lt;br /&gt;mov     $MessageLength, %ax&lt;br /&gt;mul     %dh&lt;br /&gt;add     $BootMessage,%ax&lt;br /&gt;mov     %ax,%bp               /* String address */&lt;br /&gt;mov     %ds,%ax&lt;br /&gt;mov     %ax,%es&lt;br /&gt;mov     $MessageLength,%cx    /* String length */&lt;br /&gt;mov     $0x1301,%ax           /* ah = 0x13, al = 0x01(W) */&lt;br /&gt;mov     $0x07,%bx             /* PageNum 0(bh = 0), bw(bl= 0x07)*/&lt;br /&gt;mov     $0,%dl                /* Start row and column */&lt;br /&gt;int     $0x10                 /* BIOS INT 10h, display string */&lt;br /&gt;ret&lt;br /&gt;&lt;br /&gt;/* Routine: ReadSector    Action: Read %cl Sectors from %ax sector(floppy) to %es:%bx(memory)       Assume sector number is 'x', then:        x/(BPB_SecPerTrk) = y,        x%(BPB_SecPerTrk) = z.      The remainder 'z' PLUS 1 is the start sector number;      The quotient 'y' devide by BPB_NumHeads(RIGHT SHIFT 1 bit)is cylinder        number;      AND 'y' by 1 can got magnetic header. */&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//剛開始在ax裡頭，我門只會有sector number，接著我門會計算總共&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//占有幾個tracks，所以會先把sector number除以18，這個值代&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//表總共占有幾個tracks。餘數加一以後就是&lt;span style="color: rgb(255, 0, 0);"&gt;sector number&lt;/span&gt;，因為&lt;br /&gt;//sector number是從&lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;0開始。接著因為floppy讀寫的順序是cylinder&lt;br /&gt;//從裡到外&lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;head 0-&gt;1讀完就到下一個cylinder。所以還要把它除以二&lt;br /&gt;//就代表&lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;有幾個&lt;span style="color: rgb(255, 0, 0);"&gt;cylinder&lt;/span&gt;。接著也可以從tracks是偶數還是奇數判斷&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//我門的&lt;span style="color: rgb(255, 0, 0);"&gt;head&lt;/span&gt;是多少，這個時候就用and $1的方式。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 153, 51);"&gt;ReadSector:     &lt;/span&gt;&lt;br /&gt;push    %ebp&lt;br /&gt;mov     %esp,%ebp&lt;br /&gt;sub     $2,%esp        /* Reserve space for saving %cl */&lt;br /&gt;mov     %cl,-2(%ebp)&lt;br /&gt;push    %bx            /* Save bx */&lt;br /&gt;mov     (BPB_SecPerTrk), %bl    /* %bl: the devider */&lt;br /&gt;div     %bl            /* 'y' in %al, 'z' in %ah */&lt;br /&gt;inc     %ah            /* z++, got start sector */&lt;br /&gt;mov     %ah,%cl        /* %cl &lt;- start sector number */    &lt;br /&gt;mov     %al,%dh        /* %dh &lt;- 'y' */ &lt;span style="color: rgb(51, 51, 255);"&gt;//這邊就是除以二，shift right 1 bit&lt;/span&gt;&lt;br /&gt;shr     $1,%al         /* 'y'/BPB_NumHeads */&lt;br /&gt;mov     %al,%ch        /* %ch &lt;- Cylinder number(y&gt;&gt;1) */&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//檢查tracks是奇數還是偶數&lt;/span&gt;&lt;br /&gt;and     $1,%dh         /* %dh &lt;- Magnetic header(y&amp;amp;1) */  &lt;br /&gt;pop     %bx            /* Restore %bx */    &lt;br /&gt;/* Now, we got cylinder number in %ch, start sector number in %cl, magnetic       header in %dh. */     mov     (BS_DrvNum), %dl &lt;span style="color: rgb(51, 51, 255);"&gt;//設dl = 0,代表是對floppy做讀取&lt;/span&gt;&lt;span style="color: rgb(204, 153, 51);"&gt;&lt;br /&gt;GoOnReading:    &lt;/span&gt;&lt;br /&gt;mov     $2,%ah&lt;br /&gt;mov     -2(%ebp),%al    /* Read %al sectors */&lt;br /&gt;int     $0x13&lt;br /&gt;jc      GoOnReading     /* If CF set 1, mean read error, reread. */&lt;br /&gt;add     $2,%esp&lt;br /&gt;pop     %ebp&lt;br /&gt;ret&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/* Routine: GetFATEntry   Action: Find %ax sector's index in FAT, save result in %ax */&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//其實這邊每call一次GetFATEntry就要copy兩個Sector到記憶體0x8F000還蠻貴的，&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;//而且其實常常會重複，因為這個例子來說，只會用到FAT的第一個Sector。&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 153, 51);"&gt;GetFATEntry:&lt;/span&gt;&lt;br /&gt;push    %es&lt;br /&gt;push    %bx&lt;br /&gt;push    %ax&lt;br /&gt;mov     $BaseOfLoader,%ax&lt;br /&gt;sub     $0x0100,%ax&lt;br /&gt;mov     %ax,%es           /* Left 4K bytes for FAT */&lt;br /&gt;pop     %ax  &lt;span style="color: rgb(51, 51, 255);"&gt;//這邊pop出來的ax就是第幾個FAT entry&lt;/span&gt;&lt;br /&gt;movb    $0,(bOdd)&lt;br /&gt;mov     $3,%bx&lt;br /&gt;mul     %bx               /* %dx:%ax = %ax*3 */&lt;br /&gt;mov     $2,%bx&lt;br /&gt;div     %bx               /* %dx:%ax/2 */&lt;br /&gt;cmp     $0,%dx            /* remainder %dx = 0 ? */&lt;br /&gt;jz      LABEL_EVEN&lt;br /&gt;movb    $1,(bOdd)&lt;br /&gt;&lt;span style="color: rgb(204, 153, 51);"&gt;LABEL_EVEN:&lt;/span&gt;&lt;br /&gt;xor     %dx,%dx           /* Now %ax is the offset of FATEntry in FAT */&lt;br /&gt;mov     (BPB_BytsPerSec),%bx&lt;br /&gt;div     %bx               /* %dx:%ax/BPB_BytsPerSec */&lt;br /&gt;push    %dx&lt;br /&gt;mov     $0,%bx&lt;br /&gt;add     $SecNoOfFAT1,%ax  /* %ax &lt;- FATEntry's sector */  &lt;br /&gt;mov     $2,%cl            /* Read 2 sectors in 1 time, because FATEntry */   &lt;br /&gt;call    ReadSector        /* may be in 2 sectors. */ &lt;span style="color: rgb(51, 51, 255);"&gt;//有可能fat的entry剛好在兩個sector的交界    &lt;/span&gt;&lt;br /&gt;pop     %dx&lt;br /&gt;add     %dx,%bx&lt;br /&gt;mov     %es:(%bx),%ax&lt;br /&gt;cmpb    $1,(bOdd)   &lt;span style="color: rgb(51, 51, 255);"&gt;//如果是奇數的話就不用shift&lt;/span&gt;&lt;br /&gt;jnz     LABEL_EVEN_2     &lt;span style="color: rgb(51, 51, 255);"&gt;//如果是偶數的話就要shift right 4 bits&lt;/span&gt;&lt;br /&gt;shr     $4,%ax &lt;span style="color: rgb(204, 153, 51);"&gt;&lt;br /&gt;LABEL_EVEN_2:&lt;/span&gt;&lt;br /&gt;and     $0x0fff,%ax&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 153, 51);"&gt;LABEL_GET_FAT_ENTRY_OK&lt;/span&gt;:&lt;br /&gt;pop     %bx&lt;br /&gt;pop     %es&lt;br /&gt;ret&lt;br /&gt;.org 510        /* Skip to address 0x510. */&lt;br /&gt;.2byte 0xaa55   /* Write boot flag to 1st sector(512 bytes) end */&lt;/http:&gt;&lt;/http:&gt;&lt;/solrex@gmail.com&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-2366494777548506890?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/2366494777548506890/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=2366494777548506890' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/2366494777548506890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/2366494777548506890'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/11/bootloader.html' title='自己動手寫作業系統 第二章bootloader範例'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_r6LKRJP8V4w/SR0ihOzkOwI/AAAAAAAAAHk/esRKlfa2FcQ/s72-c/mmp.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-5754821762140702396</id><published>2008-10-26T19:26:00.000-07:00</published><updated>2008-10-29T00:34:44.641-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='File System'/><title type='text'>FAT series file system</title><content type='html'>在開始看以前可以先參考一下&lt;a href="http://home.educities.edu.tw/wanker742126/asm/ch18.html"&gt;小木偶的FAT12教學&lt;/a&gt;和&lt;a href="http://home.educities.edu.tw/wanker742126/asm/ch33.html"&gt;FAT32教學&lt;/a&gt; 尤其是FAT12一定要先看一下。&lt;br /&gt;&lt;br /&gt;右圖是我的電腦裡硬碟的MBR，從最後反白的那&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_r6LKRJP8V4w/SQUs5kyXCHI/AAAAAAAAAF0/Xio4eqeFpxI/s1600-h/MBR.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 320px; height: 204px;" src="http://1.bp.blogspot.com/_r6LKRJP8V4w/SQUs5kyXCHI/AAAAAAAAAF0/Xio4eqeFpxI/s320/MBR.JPG" alt="" id="BLOGGER_PHOTO_ID_5261661107291359346" border="0" /&gt;&lt;/a&gt;四行(1BE開始的64 bytes，稱為partition table)可以看出真正有作用的只有前兩個16 bytes。這邊可以得知我的硬碟上有兩個partition。以第一組16 bytes來說，第一個byte 80代表這是個開機的磁區，再來01 01 00代表是head 1, sector 1, cylinder 0。注意:第二組01的前兩個bits其實是裝在最後那組cylinder的前面，所以實際上sector是六個bit最大值為63，sector最小是從1開始，而cylinder因為有十個bits的緣故，且從零開始，所以最多有1024個cylinder。上面這個Cylinder, Head, Sector的地址方式稱為CHS。但因為他只能定址8.4G的緣故，所以現在已經不用這種方式了，用後面會說到的LBA線性方式定址。再來一個Byte 07是代表NTFS，這個byte所代表的意義&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_r6LKRJP8V4w/SQUz9jor45I/AAAAAAAAAF8/5IyXxWQH-gE/s1600-h/p1.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 320px; height: 280px;" src="http://1.bp.blogspot.com/_r6LKRJP8V4w/SQUz9jor45I/AAAAAAAAAF8/5IyXxWQH-gE/s320/p1.JPG" alt="" id="BLOGGER_PHOTO_ID_5261668872283218834" border="0" /&gt;&lt;/a&gt;可以查詢&lt;a href="http://www.win.tue.nl/%7Eaeb/partitions/partition_types-1.html"&gt;Andries E. Brouwer寫的partition &lt;/a&gt;&lt;a href="http://www.win.tue.nl/%7Eaeb/partitions/partition_types-1.html"&gt;type&lt;/a&gt;。再來FE FF FF分別為head , sector, cylinder所代表的結束位置。這邊因為超過了8.4G最大能表達的範圍所以填入最大值。00 00 00 3F代表的是第一個partition開始的位置，以sector的大小為單位也就是512 bytes，相對於零開始，所以是0x3F * 0x200 = 0x7E00 = 32256 bytes 除以1024後等於31.5k，這也就是為什麼Hexedit的start sectors會顯示31.5k。可以參考右邊的圖示。&lt;br /&gt;&lt;br /&gt;03 C0 2E CE代表的是第一個partition的大小。可以算得他的大小為0x03C02ECE * 0x200 = 0x7805D9C00 = 32,218,389,504 bytes差不多是30G。下一個partition entry就依此類推。這個是在我電腦上的硬碟，因為是NTFS的緣故，所以只用來解釋partition table的觀念，接下來看我的隨身碟，是由FAT32所format而成的。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_r6LKRJP8V4w/SQZ-A4LQAjI/AAAAAAAAAGc/32w18I6KrUg/s1600-h/format.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 220px; height: 320px;" src="http://4.bp.blogspot.com/_r6LKRJP8V4w/SQZ-A4LQAjI/AAAAAAAAAGc/32w18I6KrUg/s320/format.JPG" alt="" id="BLOGGER_PHOTO_ID_5262031768173675058" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;如右圖所示，首先先把隨身碟Format成FAT的格式，也就是FAT16。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;接著，用winhex開啟我們的磁碟，並且選取Partition 1&lt;br /&gt;，和上面同樣的，Part&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_r6LKRJP8V4w/SQZ_am8kyJI/AAAAAAAAAGk/4qyMv1NkT18/s1600-h/boot+sector.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 320px; height: 180px;" src="http://3.bp.blogspot.com/_r6LKRJP8V4w/SQZ_am8kyJI/AAAAAAAAAGk/4qyMv1NkT18/s320/boot+sector.JPG" alt="" id="BLOGGER_PHOTO_ID_5262033309736945810" border="0" /&gt;&lt;/a&gt;ition 1 坐落在0x7E00的位置。&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;br /&gt;再來看到Boot Sector這裡面就有詳細的說明。按照Reserved sectors =4，所以從0x7E00開始，有四個sectors是保留的磁區，第五個Sector就是第一個FAT table。0x7E00 + 0x200 * 0x4 = 0x8600。Boot Sector裡頭有BPM這是FAT定義的partition基本資料。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_r6LKRJP8V4w/SQaBXKJVB9I/AAAAAAAAAGs/8Dy8Ve8hB8Q/s1600-h/Boot+sector+table.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 254px; height: 320px;" src="http://2.bp.blogspot.com/_r6LKRJP8V4w/SQaBXKJVB9I/AAAAAAAAAGs/8Dy8Ve8hB8Q/s320/Boot+sector+table.JPG" alt="" id="BLOGGER_PHOTO_ID_5262035449489459154" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;如果你去看0x8600的位置，可以看到只有四個bytes的值。&lt;br /&gt;前兩個bytes是F8 FF，所以代表是一顆硬碟。後兩個通常是FF FF沒有意義。因為我們還沒有置放檔案在這顆硬 碟，所以之後的欄位皆為零。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;接著我們可以算得Root directory =( Reserved sectors + number of FATs * sectors per FAT ) x 512 + Base address&lt;br /&gt;= ( 4 + 2 x 246 ) x 512 + 0x7E00 = 0x45E00&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_r6LKRJP8V4w/SQaIYJ2mReI/AAAAAAAAAG0/zQRlJbrq_lg/s1600-h/45E00.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 320px; height: 42px;" src="http://3.bp.blogspot.com/_r6LKRJP8V4w/SQaIYJ2mReI/AAAAAAAAAG0/zQRlJbrq_lg/s320/45E00.JPG" alt="" id="BLOGGER_PHOTO_ID_5262043163172160994" border="0" /&gt;&lt;/a&gt;&lt;/div&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;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_r6LKRJP8V4w/SQbOnoJciQI/AAAAAAAAAG8/5Z8xQaHW3Z8/s1600-h/MandP.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 326px; height: 243px;" src="http://3.bp.blogspot.com/_r6LKRJP8V4w/SQbOnoJciQI/AAAAAAAAAG8/5Z8xQaHW3Z8/s320/MandP.JPG" alt="" id="BLOGGER_PHOTO_ID_5262120394816260354" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;參考右邊這個圖，這就是整個MBR與file system的關係。右下角是一個partition。是代表第一個&lt;br /&gt;partition entry的partition。&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;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_r6LKRJP8V4w/SQbmeVObB_I/AAAAAAAAAHE/w3pRnGT2n1k/s1600-h/txxt.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 202px; height: 92px;" src="http://1.bp.blogspot.com/_r6LKRJP8V4w/SQbmeVObB_I/AAAAAAAAAHE/w3pRnGT2n1k/s320/txxt.JPG" alt="" id="BLOGGER_PHOTO_ID_5262146623397103602" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;接下來我們新增一個文字檔，之後再觀察FAT和Root directory以&lt;br /&gt;及data area的變化。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;從root directory的位置，0x45E00可以&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_r6LKRJP8V4w/SQbomfUnOnI/AAAAAAAAAHM/NIAu1awAGWU/s1600-h/root.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 400px; height: 161px;" src="http://1.bp.blogspot.com/_r6LKRJP8V4w/SQbomfUnOnI/AAAAAAAAAHM/NIAu1awAGWU/s400/root.JPG" alt="" id="BLOGGER_PHOTO_ID_5262148962569632370" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;看到首先第一個32 bytes是儲存隨身碟&lt;br /&gt;的名稱KINGSTON。不滿的以20填滿。在20之后有一個08，代表的是這個ENTRY儲存隨身碟的名稱。再來到下一個32 bytes的起始位置，0x45E20，可以看到接下來幾個32 bytes的FDB(file descriptor block)都是以E5為開頭，這代表的是已經被刪除的檔案。在這裡發現，我之前只是把檔名作更改而已，但是事實上，os的作法會新增一個新的FDB，並不會更改原本的FDB。我們看到最後一個FDB也就是0x45EC0，可以看到一開始的11 bytes就是檔名。然後在0x45EDA開始的兩個bytes 0002就是起始的cluster。接下來的四個bytes 00 00 00 0C代表的是檔案的大小，是以bytes為單位。所以我們的1234567.txt為12 bytes。因為裡頭有12個3。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_r6LKRJP8V4w/SQbxlF8m9LI/AAAAAAAAAHU/5odUXLjEzvI/s1600-h/fat.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 400px; height: 55px;" src="http://3.bp.blogspot.com/_r6LKRJP8V4w/SQbxlF8m9LI/AAAAAAAAAHU/5odUXLjEzvI/s400/fat.JPG" alt="" id="BLOGGER_PHOTO_ID_5262158834182845618" border="0" /&gt;&lt;/a&gt;因為這邊是FAT16的緣故所以，以16bits為單位。前面兩個word之前有說過。保留給系統使用。最後一個word就是第二個entry也就是我們1234567.txt檔的起始位置cluster，同時第二個entry也是data area開始的地方。這邊顯示為FFFF代表這個檔案沒有接續下一個cluster(在FAT的儲存方式裡，FAT entry所儲存的是下一個cluster的號碼，如果是最後一個cluster則為FFFF)。就在這個cluster結束。雖然只有12 bytes但這邊還是佔有一個cluster。一個cluster佔有32個sectors所以大小為16KB。&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_r6LKRJP8V4w/SQb3i0wsjDI/AAAAAAAAAHc/ETN38ktMMt0/s1600-h/data.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 400px; height: 34px;" src="http://4.bp.blogspot.com/_r6LKRJP8V4w/SQb3i0wsjDI/AAAAAAAAAHc/ETN38ktMMt0/s400/data.JPG" alt="" id="BLOGGER_PHOTO_ID_5262165392279505970" border="0" /&gt;&lt;/a&gt;&lt;/div&gt; 在Data area的開始處，也就是文字檔開始的地方可以看到12個3。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-5754821762140702396?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/5754821762140702396/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=5754821762140702396' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/5754821762140702396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/5754821762140702396'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/10/fat-series-file-system.html' title='FAT series file system'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_r6LKRJP8V4w/SQUs5kyXCHI/AAAAAAAAAF0/Xio4eqeFpxI/s72-c/MBR.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-9006595961439945168</id><published>2008-10-08T08:35:00.000-07:00</published><updated>2008-10-08T08:43:05.792-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><title type='text'>簡單的Gas inline assembly</title><content type='html'>簡單的gas入門嘗試如下，output field裡頭的"=r"改成"+r"之後就一帆風順了。&lt;br /&gt;=是write only的意思。+是read-write。&lt;br /&gt;&lt;br /&gt;#include &lt;stdio.h&gt;&lt;br /&gt;&lt;br /&gt;void main()&lt;br /&gt;{&lt;br /&gt;        int x = 1;&lt;br /&gt;        int z = 3;&lt;br /&gt;        int y = 0;&lt;br /&gt;        printf("x = %d,y = %d, z = %d",x, y, z );&lt;br /&gt;&lt;br /&gt;        __asm__ __volatile__("movl %1, %0\n\t"&lt;br /&gt;                             "movl %2, %0\n\t"&lt;br /&gt;                :"&lt;span style="color: rgb(255, 0, 0);"&gt;+&lt;/span&gt;r"(y)&lt;br /&gt;                :"r"(z),"r"(x)&lt;br /&gt;                :"0"&lt;br /&gt;        );&lt;br /&gt;&lt;br /&gt;        printf("\nx = %d, y = %d, z = %d", x, y, z);&lt;br /&gt;&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-9006595961439945168?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/9006595961439945168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=9006595961439945168' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/9006595961439945168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/9006595961439945168'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/10/gas-inline-assembly.html' title='簡單的Gas inline assembly'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-2037518804159181086</id><published>2008-09-22T04:36:00.000-07:00</published><updated>2009-04-28T00:01:01.046-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux kernel'/><title type='text'>EeePC Xandros Linux的編譯以及Kernel安裝</title><content type='html'>&lt;span style="font-weight: bold;"&gt;1&lt;/span&gt;. 解壓縮 linux-source-2.6.21.4-eeepc.tar.gz&lt;br /&gt;    tar zxvf linux-source-2.6.21.4-eeepc.tar.gz&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;2&lt;/span&gt;. 將原本的 eee PC 的 config (在 boot/config-2.6.21.4-eeepc) copy 到此 source 下，並 更名為&lt;br /&gt;  .config&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;3&lt;/span&gt;. 若你第一次做 compiler 可能需要安裝 library&lt;br /&gt;apt-get install gcc  libc6-dev libncurses-dev ncurses-dev bison flex&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;4&lt;/span&gt;.&lt;br /&gt;(要先把input.tar覆蓋掉原本kernel的input資料夾)&lt;br /&gt;接著打&lt;br /&gt;make oldconfig (make menuconfig，到device driver-&gt;Input device support-&gt;Touchscreens-&gt;Asus PS/2 touchscreen把他編到kernel內)&lt;br /&gt;make&lt;br /&gt;make bzImage (如果有問題可以先make clean) &lt;br /&gt;這個檔案會產生在 arch/i386/boot/bzImage&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;5&lt;/span&gt;. 接著將 bzImage copy 到 eeepc&lt;br /&gt;a. 開機，按 alt+F9 (這邊應該是F9就可以了)&lt;br /&gt;b. 先選擇第四項將系統初始化(暫時不用選這個，不然會把整個系統還原成出場狀況)&lt;br /&gt;c. 選擇 Normal Boot 按 e 做編輯(移到Normal Boot上面，不要按enter)&lt;br /&gt;d. 這時會有三個選單如下&lt;br /&gt;    root&lt;br /&gt;    kernel /boot/vmlinuxz-2.6.24 xxxxxxx&lt;br /&gt;    initrd /boot/initramfs-eeepc.img&lt;br /&gt;先將第三個移除 (d)，再選擇第二個並編輯，修改如下&lt;br /&gt;oll root=/dev/sda1 init=/sbin/fastinit       接著 按enter&lt;br /&gt;  之後按b，boot&lt;br /&gt;e. 進入系統後按 console 出來(ctrl+alt+t)，並且打&lt;br /&gt;    sudo su -&lt;br /&gt;    df&lt;br /&gt;f. 將 /dev/sda1 mount 起來&lt;br /&gt;   mkdir mt&lt;br /&gt;   mount /dev/sda1 /mt&lt;br /&gt;g. 修改 boot kernel&lt;br /&gt;    vim /boot/grub/menu.lst 改 title 內容 及 kernel /boot/檔名&lt;br /&gt;    假設你修改的kernel 在 /boot/vmlinuz-david&lt;br /&gt;    那請將剛才產生的 bzImage 複製到此檔&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;6&lt;/span&gt;. xfree86-input-asus_ts-0.01.tar 為 xorg 的 driver 建立好的 module&lt;br /&gt;copy 到 /usr/lib/xorg/modules/input 下&lt;br /&gt;1. tar -x xfree86-input-asus_ts-0.01.tar&lt;br /&gt;2. cd xfree86-input-asus_ts-0.01&lt;br /&gt;3. make clean&lt;br /&gt;4. make&lt;br /&gt;5. 把asusts_drv.so copy到隨身碟內，接著再copy到/usr/lib/xorg/modules底下&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;7&lt;/span&gt;. 請將 xorg.conf 加入 asusts device&lt;br /&gt;xorg.conf在 /etc/X11底下，改了什麼要去看新的xorg.conf。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Max's new method to update kernel&lt;/span&gt;(在舊版的kernel就不行了)&lt;br /&gt;&lt;br /&gt;Please use the following steps to change kernel image&lt;br /&gt;&lt;br /&gt;1. sudo su&lt;br /&gt;&lt;br /&gt;2. mount -o remount,rw /dev/sda1 /ro&lt;br /&gt;&lt;br /&gt;3. cd /ro/boot&lt;br /&gt;&lt;br /&gt;4. cp (your new kernel) vmlinuz-2.6.21.4-eeepc&lt;br /&gt;&lt;br /&gt;5. cd /&lt;br /&gt;&lt;br /&gt;6. umount /ro&lt;br /&gt;&lt;br /&gt;7. reboot&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-2037518804159181086?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/2037518804159181086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=2037518804159181086' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/2037518804159181086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/2037518804159181086'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/09/eeepc-linuxkernel.html' title='EeePC Xandros Linux的編譯以及Kernel安裝'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-1521459916698965591</id><published>2008-09-22T04:26:00.000-07:00</published><updated>2009-04-27T23:59:29.253-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><title type='text'>Vim-Gnome + Ctags + Taglist + Winmanager</title><content type='html'>一開始要先更新自己的vim，因為內建的vim是vim-mini&lt;br /&gt;1. apt-get install  vim-gnome&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Ctags&lt;/span&gt;&lt;/span&gt; (可以做內建tag的工作，查詢程式裡面的關鍵字所在位置) (在程式碼的根目錄底下 "ctags -R" 可以創立根目錄tags tree，但要記得vim根目錄下的程式碼檔才不會找不到tag)&lt;br /&gt;2. 再來要安裝Ctags，因為沒有內建，所以要去&lt;a href="http://ctags.sourceforge.net/"&gt;http://ctags.sourceforge.net/&lt;/a&gt;下載ctags的source code自己來編譯安裝。&lt;br /&gt;3. 首先把 ctags-5.7.tar.gz在/usr/local/src底下解壓縮，tar -zxvf ctags-5.7.tar.gz&lt;br /&gt;4. 記得要讀一讀它的readme&lt;br /&gt;5. cd /usr/local/src/ctags-5.7/&lt;br /&gt;6. ./configure --prefix=/usr/local/ctags-5.7  之後產生出來的makefile才知道要安裝在/usr/local/ctags-5.7&lt;br /&gt;7. 在/usr/local/src/ctags-5.7底下，make clean&lt;br /&gt;8. make 只有產生可執行檔，沒有安裝到我門要求的目錄&lt;br /&gt;9. make install&lt;br /&gt;10. 再來要設path，PATH="$PATH":/usr/local/ctags-5.7/bin&lt;br /&gt;11. 把man page加到man setup file裡，在/etc/man.config加上MANDATORY_MANPATH /usr/local/ctags-5.7/man&lt;br /&gt;(以後如果要解除安裝，就把/usr/local/ctags-5.7這個資料夾整個刪掉，再把path重設，man page裡頭的選項拿掉即可)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Taglist&lt;/span&gt; (可以show出所有當下這個檔案裡的variables, functions, or macro) 如果不想打開winmanager可以用":TlistToggle"&lt;br /&gt;1. 從&lt;a href="http://www.vim.org/scripts/script.php?script_id=273"&gt;這個網站&lt;/a&gt;下載，因為是plugin的緣故所以不用安裝。&lt;br /&gt;2. copy到~/.vim/這個目錄底下並在下面unzip taglist_45.zip，之後他會自己create doc &amp;amp; plugin 兩個資料夾把檔案copy進去&lt;br /&gt;(如果沒有~/.vim的話，可以自己從/etc/vim 複製過來， .vimrc 也可以從 /etc/vim/.vimrc 複製到 ~/.vimrc )&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Winmanager&lt;/span&gt; (show出所在目錄的所有檔案與資料夾，很方便打開新的程式檔)&lt;br /&gt;1. 步驟和上面Taglist一模一樣，請到&lt;a href="http://www.vim.org/scripts/script.php?script_id=95"&gt;這邊&lt;/a&gt;下載&lt;br /&gt;&lt;br /&gt;最後要編輯~/.vimrc(記得如果編寫錯誤，每次進入.vimrc時就會出現錯誤訊息,ex:no mapping found)&lt;br /&gt;1. vi ~/.vimrc&lt;br /&gt;2. 把syntax on uncommented. 同時也加上set nu&lt;br /&gt;3. 要在.vimrc裡面加上這些東西，就可以按：F進入左上角的視窗，：B進入左下角的視窗，wm把左側兩個視窗同時叫出或關閉&lt;br /&gt;  """"""""""""""""""""""""""""""&lt;br /&gt;  " winManager setting&lt;br /&gt;  """"""""""""""""""""""""""""""&lt;br /&gt;  let g:winManagerWindowLayout = "BufExplorer,FileExplorer|TagList"&lt;br /&gt;  let g:winManagerWidth = 30&lt;br /&gt;  let g:defaultExplorer = 0&lt;br /&gt;  nmap &lt;c-w&gt;&lt;c-f&gt; :FirstExplorerWindow&lt;cr&gt;&lt;br /&gt;  nmap &lt;c-w&gt;&lt;c-b&gt; :BottomExplorerWindow&lt;cr&gt;&lt;br /&gt;  nmap &lt;silent&gt; &lt;leader&gt;wm :WMToggle&lt;cr&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;CScope&lt;/span&gt;&lt;br /&gt;1. apt-get install cscope&lt;br /&gt;2. 假設某個project是在/root/work/input底下，接著你要進入/root/work/input/touchscreen底下打開AsTouchScreen.c,&lt;br /&gt;   cd /root/work/input&lt;br /&gt;   cscope -bqR&lt;br /&gt;   cd /touchscreen,&lt;br /&gt;   vim AsTouchScreen.c&lt;br /&gt;3. 進入vim後，:cs add /root/work/input/cscope.out /root/work/input ，就會把cscope connection加進去&lt;br /&gt;4. 這樣找某個function的calling function就可以找到了&lt;br /&gt;5. 記得在/root/work/input底下也建立ctags的tag，"ctags -R"，所在的子目錄也要建立Tag，在/root/work/input/touchscreen底下"ctags -R"&lt;br /&gt;6. 在/root/.vimrc加上&lt;br /&gt;&lt;br /&gt;if has("cscope")&lt;br /&gt;set csprg=/usr/bin/cscope&lt;br /&gt;set csto=0                                  "use cscope as default tag&lt;br /&gt;set cst&lt;br /&gt;set nocsverb&lt;br /&gt;" add any database in current directory&lt;br /&gt;if filereadable("cscope.out")&lt;br /&gt;cs add cscope.out&lt;br /&gt;" else add database pointed to by environment&lt;br /&gt;elseif $CSCOPE_DB != ""&lt;br /&gt;cs add $CSCOPE_DB&lt;br /&gt;endif&lt;br /&gt;set csverb&lt;br /&gt;set cscopetag&lt;br /&gt;set cscopequickfix=s-,g-,c-,d-,t-,e-,f-,i-&lt;br /&gt;endif&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Reference&lt;/span&gt;&lt;br /&gt;&lt;a href="http://blog.csdn.net/wooin/archive/2007/10/31/1858917.aspx"&gt;手把手&lt;/a&gt;的環境架設教學&lt;br /&gt;&lt;a href="http://hi.baidu.com/phps/blog/item/87e018955c72e50a7bf48097.html"&gt;很棒的ctags教學&lt;/a&gt;，一定要看，看過以後ctags會很熟&lt;br /&gt;&lt;a href="http://www.kuqin.com/developtool/20080601/9142.htm"&gt;"使用vim開發軟件項目"&lt;/a&gt;一系列的文章也都相當頂尖，一定要看&lt;br /&gt;&lt;a href="http://walkingice.twbbs.org/blog/?p=167"&gt;只放拖鞋的鞋櫃&lt;/a&gt;，這也不錯，教你怎麼做快捷鍵&lt;/cr&gt;&lt;/leader&gt;&lt;/silent&gt;&lt;/cr&gt;&lt;/c-b&gt;&lt;/c-w&gt;&lt;/cr&gt;&lt;/c-f&gt;&lt;/c-w&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-1521459916698965591?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/1521459916698965591/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=1521459916698965591' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/1521459916698965591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/1521459916698965591'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/09/vim-gnome-ctags-taglist-winmanager.html' title='Vim-Gnome + Ctags + Taglist + Winmanager'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-1814690697038904928</id><published>2008-09-22T01:40:00.000-07:00</published><updated>2009-04-28T00:01:28.452-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>在EeePc下面用GParted + Syslinux + HP USB Disk Storage Format Tool進行檔案備份</title><content type='html'>如果已經用過HP USB Disk Storage Format Tool格式化以後就可以不用在格式化了，&lt;br /&gt;可直接pass過這個步驟。&lt;br /&gt;&lt;br /&gt;首先要先在linux上面安裝syslinux + mtools&lt;br /&gt;sudo apt-get install mtools&lt;br /&gt;sudo apt-get install syslinux&lt;br /&gt;&lt;br /&gt;接下來到&lt;a href="http://sourceforge.net/project/showfiles.php?group_id=115843&amp;package_id=195292"&gt;這邊&lt;/a&gt;&lt;br /&gt;下載Gparted LiveUsb。&lt;br /&gt;&lt;br /&gt;再來我們要對隨身碟做安裝Syslinux的動作，在這個動作進行之前記得將usb碟umount：syslinux /dev/sdxx(這邊可以用dmesg看你的usb是多少代號)，這邊做完了以後，已經可以進行開機了，但在開機時會秀出找不到kernel的訊息。&lt;br /&gt;補充:可以到&lt;a href="http://ftp.ntu.edu.tw/linux/boot/syslinux/"&gt;這裡&lt;/a&gt;去下載Syslinux的程式，解開後再win32資料夾裡會有syslinux.exe，也有syslinux的source code。在xp底下可以開啟終端機，接著再到syslinux.exe的目錄底下，用"syslinux.exe f:"就可以成功的安裝syslinux。&lt;br /&gt;&lt;br /&gt;完成之後把下載下來的gparted-liveusb-0.3.1-1.zip解壓縮。得到下面的檔案&lt;br /&gt;boot.cat&lt;br /&gt;boot.msg&lt;br /&gt;gparted&lt;br /&gt;initrd.gz&lt;br /&gt;linux&lt;br /&gt;splash.lss&lt;br /&gt;syslinux.cfg&lt;br /&gt;總共有七個。&lt;br /&gt;把檔案直接copy進usb碟即可。&lt;br /&gt;&lt;br /&gt;然後就可以用usb開機了。開機了以後GParted LiveUsb裡面會有file manager，和terminal。&lt;br /&gt;在/dev裡的hdc1和hdd1分別是系統槽，還有使用者的槽。凡是在/home/user底下的東西都釋放再第二個槽。再來用dmesg就知道我們的usb是哪個device，把他們都mount起來以後就可以進行檔案的備份。&lt;br /&gt;&lt;br /&gt;參考:&lt;br /&gt;&lt;a href="http://blog.roodo.com/ystuan/archives/2632860.html"&gt;帝國反抗軍之螞蟻搬家 - 塞進32MB USB的硬碟資料備份利器：Partimage on GParted LiveUSB&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.debian.org/releases/sarge/i386/ch04s04.html.zh_TW"&gt;準備從 USB 隨身碟開機的檔案&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-1814690697038904928?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/1814690697038904928/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=1814690697038904928' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/1814690697038904928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/1814690697038904928'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/09/eeepcgparted-syslinux-hp-usb-disk.html' title='在EeePc下面用GParted + Syslinux + HP USB Disk Storage Format Tool進行檔案備份'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-617338816901871921</id><published>2008-09-02T20:26:00.000-07:00</published><updated>2009-04-28T00:01:28.453-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>pcmanx亂碼設定</title><content type='html'>執行PCManX之後，連線後你應該會發現中文是亂碼，請選擇檢視-&gt;Font，選擇第一個AR StdkaiU30 Medium這個字型之後，選確定即可。之後按下alt+enter就可以把視窗最大化，就很好閱讀。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-617338816901871921?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/617338816901871921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=617338816901871921' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/617338816901871921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/617338816901871921'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/09/pcmanx.html' title='pcmanx亂碼設定'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-6223196761288455692</id><published>2008-09-02T08:02:00.000-07:00</published><updated>2009-04-28T00:01:28.453-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>安裝Xandros eeepc advanced desktop的步驟</title><content type='html'>1. 到&lt;a href="http://download.tuxfamily.org/eeepcrepos/pool/main/"&gt;這裡&lt;/a&gt;下載kicker_3.4.2.201-1_i386.deb, ksmserver_3.4.2.201-1_i386.deb and advanced-desktop-eeepc_1.0-1_i386.deb這三個檔案&lt;br /&gt;2. dpkg -i kicker_3.4.2.201-1_i386.deb&lt;br /&gt;3. dpkg -i ksmserver_3.4.2.201-1_i386.deb&lt;br /&gt;4. 如果直接dpkg -i advanced-desktop-eeepc_1.0-1_i386.deb後來會出現錯誤cannot stat `/usr/bin/xandros_device_detection_dialog.orig'。之後apt-get就會掛掉了，每次安裝想要update都會出現什麼the package needs to be reinstalled的錯誤訊息。&lt;br /&gt;5. 但是事實上我在/usr/bin/底下有發現一個相同檔名xandros_device_detecion_dialog的檔案，只是沒有副檔名，我就cp xandros_device_detection_dialog xandros_device_detection_dialog.orig&lt;br /&gt;6. 接著再安裝dpkg -i advanced-desktop-eeepc_1.0-1_i386.deb就ok了&lt;br /&gt;7. 完成了以後按下power button就多出一個full desktop的選項了。&lt;br /&gt;&lt;br /&gt;##奇怪的是我第二次安裝的時候(有先用f9把電腦完全復原成出場狀態)，連/etc底下都沒有bin的這個資料夾，裝完了以後也沒有出現。而且，安裝的過程很順利一點問題都沒有，linux真是奇怪@@。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-6223196761288455692?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/6223196761288455692/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=6223196761288455692' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/6223196761288455692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/6223196761288455692'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/09/eeepc-advanced-desktop.html' title='安裝Xandros eeepc advanced desktop的步驟'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-4943226665788335816</id><published>2008-05-14T20:03:00.000-07:00</published><updated>2008-05-14T20:06:14.435-07:00</updated><title type='text'>战士跪下大哭：求求你们让我再去救一个</title><content type='html'>reference: http://xiaoneigirl.zhan.cn.yahoo.com/apps/ncpcontent/?module_id=28100000013224&amp;action=read&amp;articleid=833&lt;br /&gt;&lt;br /&gt;本来想今天更新，但是看到了新闻，实在没有了心情。   &lt;br /&gt;　　   &lt;br /&gt;　　刚刚接通了一位采访过我的四川记者朋友的电话，她刚刚从绵竹退下来，这个娇小的丫头在电话里和我讲了她眼见的情况，她只用了四个字形容，就是：“世界末日。”她说她几乎无法工作，眼泪就没有停过，太惨了，一片一片的废墟，到处是哭喊的声音，救援队发了疯一样的救人，然而往往救不了，跟着去的摄影只了拍一张照片，就扔下相机去帮忙，因为那情景让你不可能站着看着。   &lt;br /&gt;　　   &lt;br /&gt;　　她和我说，她在一个学校现场看到了她永远不会忘记的一幕，学校的主教学楼坍塌了大半，当时正在上课，几乎有100多个孩子被压在了下面。全是小学生。一些似乎是消防队员的战士在废墟中已经抢出了十几个孩子和三十多具尸体，看着那些小小的，带着红领巾却再也无法睁开眼睛的孩子，她说她突然觉得自己说话的勇气都没有了。   &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;　　天佑中国，人间有爱。朋友们，无论你们身边有任何的条件，只要是能帮助灾区的，希望我们都马上付之行动，莫以善小而不为，一篇文章，一元捐款，都是一种支持，2008注定是荣耀与灾难交辉的一年，灾难的是中国人的土地，荣耀的是中国人的心。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-4943226665788335816?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/4943226665788335816/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=4943226665788335816' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/4943226665788335816'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/4943226665788335816'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/05/blog-post.html' title='战士跪下大哭：求求你们让我再去救一个'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-5696411493240840936</id><published>2008-04-10T22:48:00.000-07:00</published><updated>2008-04-10T23:22:01.316-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><title type='text'>跨檔案Segment jmp與跨segment呼叫</title><content type='html'>當我們project越做越大的時候，多個檔案的程式開發變成不可避免的。&lt;br /&gt;經過華哥的實驗，最後找出如何跨SEGMENT做jmp。&lt;br /&gt;假設今天在A.asm裡頭有個A segment，想要CALL位在B.asm的B segment的B_SEG則若要能正確運作寫法如下。寫個簡單的例子在B segment印出hello world :&lt;br /&gt;&lt;br /&gt;A.asm&lt;br /&gt;&lt;br /&gt;.586&lt;br /&gt;&lt;br /&gt;B SEGMENT PARA PUBLIC USE16 'b'&lt;br /&gt;    EXTERN B_SEG:FAR&lt;br /&gt;B ENDS&lt;br /&gt;&lt;br /&gt;A SEGMENT PARA PUBLIC USE16 'code'&lt;br /&gt;    ASSUME cs:A, ds:A_DATA&lt;br /&gt;start:&lt;br /&gt;    mov    dx, A_DATA&lt;br /&gt;    mov    ds, dx&lt;br /&gt;    jmp    B_SEG&lt;br /&gt;A ENDS&lt;br /&gt;&lt;br /&gt;A_DATA SEGMENT PARA PUBLIC USE16 'data'&lt;br /&gt;    PUBLIC msg&lt;br /&gt;    msg BYTE 'hello world$'&lt;br /&gt;A_DATA ENDS&lt;br /&gt;&lt;br /&gt;END start&lt;br /&gt;&lt;br /&gt;B.asm&lt;br /&gt;&lt;br /&gt;.586&lt;br /&gt;A_DATA SEGMENT PARA PUBLIC USE16 'data'&lt;br /&gt;    EXTERN msg:BYTE&lt;br /&gt;A_DATA ENDS&lt;br /&gt;&lt;br /&gt;B SEGMENT PARA PUBLIC USE16 'b'&lt;br /&gt;    PUBLIC B_SEG&lt;br /&gt;&lt;br /&gt;B_SEG::&lt;br /&gt;    mov    dx, OFFSET msg&lt;br /&gt;    mov    ah, 09h&lt;br /&gt;    int    21h&lt;br /&gt;&lt;br /&gt;    mov    ax, 4C00h&lt;br /&gt;    int    21h&lt;br /&gt;&lt;br /&gt;B ENDS&lt;br /&gt;&lt;br /&gt;END&lt;br /&gt;&lt;br /&gt;;-----------------------------------------&lt;br /&gt;通常EXTERN B:NEAR ,B:FAR代表B是一個label，FAR代表是要給別的segment用的。&lt;br /&gt;若在文中已經有宣告，EXTERN B:FAR時，則呼叫的時候可以不用jmp FAR PTR B。可以直接jmp B。除非是在同一個檔案裡頭跨不同的SEGMENT jmp or call才需要jmp FAR PTR or call FAR PTR。&lt;br /&gt;另外若是看到EXTERN B:BYTE ,B:WORD代表，B是一個外部檔案來的變數，其型態是BYTE or WORD。&lt;br /&gt;最後EXTERN B:ABS，則代表B是一個defined的常數。ex:B EQU 1234h&lt;br /&gt;;-----------------------------------------&lt;br /&gt;若兩個檔案都在同一個目錄底下，則編譯時可以用&lt;br /&gt;ml /c /Fl a.asm b.asm    ---&gt; '/c'用意是只編譯產生.obj，'/Fl'是編譯過程產生.list檔&lt;br /&gt;ml /Fm a.obj b.obj       ---&gt; 'Fm'指link過程產生map file。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-5696411493240840936?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/5696411493240840936/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=5696411493240840936' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/5696411493240840936'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/5696411493240840936'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/04/segment-jmpsegment.html' title='跨檔案Segment jmp與跨segment呼叫'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-6402022591690052735</id><published>2008-03-30T03:45:00.000-07:00</published><updated>2011-07-28T16:53:19.367-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='健力運動'/><title type='text'>我所知道的硬舉</title><content type='html'>硬舉通常是健力三舉內展現力量最有說服力的一種方式，像大力士(WSM)比賽裡，可以嗅出硬舉的許多變形，如Atlas stone，Barrel carry，Car deadlift，etc。而目前世界硬舉的第一把交椅當屬Andy Bolton(2007 WPO Finals EXPO in Columbus,Ohio)的1003磅世界紀錄。硬舉好的人通常有幾項特點，手臂長，身體短，手掌與手指相對較大，而通常也伴隨著握推較差的弱點。這邊只討論硬舉如何做重，強調他的功能性，對於健美的方面，比較沒有著墨。&lt;br /&gt;&lt;br /&gt;硬舉的主要動作實施，分為兩個種類個別稱為&lt;span style="color: rgb(255, 0, 0);"&gt;窄硬&lt;/span&gt;(Conventional deadlift)和&lt;span style="color: rgb(255, 0, 0);"&gt;寬硬&lt;/span&gt;(Sumo-style deadlift)。一般我們在健身房比較常見的硬舉為窄硬。以下這段討論窄硬，&lt;span style="color: rgb(255, 0, 0);"&gt;窄硬&lt;/span&gt;在健力上常見的方式又可以再細分為兩種，第一種是&lt;span style="color: rgb(255, 0, 0);"&gt;舉重式&lt;/span&gt;的硬舉，第二種是健力比賽常見的&lt;span style="color: rgb(255, 0, 0);"&gt;健力式&lt;/span&gt;硬舉。&lt;br /&gt;&lt;br /&gt;健力硬舉的握槓動作採用正反握&lt;span style="color: rgb(255, 0, 0);"&gt;大拇&lt;/span&gt;指握在四指的&lt;span style="color: rgb(255, 0, 0);"&gt;外面&lt;/span&gt;。非採用舉重式的&lt;span style="color: rgb(255, 0, 0);"&gt;勾握&lt;/span&gt;(大拇指握在&lt;span style="color: rgb(255, 0, 0);"&gt;裡面&lt;/span&gt;)。&lt;br /&gt;&lt;br /&gt;##窄硬敘述&lt;br /&gt;一開始敘述窄硬基礎動作的過程，一開始雙腳與肩同寬，與槓鈴的距離大概是由上往下看五隻腳趾頭都超過槓鈴為標準。接著和蹲舉一樣屁股往後坐，上半身打直挺胸，將肚子挺出去，稍微夾緊上背。再來手掌的握法為雙手正反握，這邊要記住，不管是那隻手正握或是反握，雙手往手指指尖的延伸方向，手掌往前旋轉，&lt;span style="color: rgb(255, 0, 0);"&gt;多抓&lt;/span&gt;一點槓子，把槓子抓在掌心間。握緊以後手打直，頭向上看，上背與後三角夾緊，如同蹲舉從底端向上站起的姿式雷同，重心慢慢往後放在臀部上，&lt;span style="color: rgb(255, 0, 0);"&gt;胸部往上帶&lt;/span&gt;，很像蝴蝶破繭般的扶搖而直上。此時，手掌會感受到重量，因為之前多抓一點的因素，所以兩隻手因為槓鈴重量的牽制，朝指尖的反方向作用而更緊。同時大腿股四頭，還有股二頭，臀大肌，全部發力，槓鈴會緩緩上身，槓鈴的移動過程要貼緊身體，因為支點是腳掌，力臂大概是軀幹的長度(槓鈴離身體的距離)，離身體&lt;span style="color: rgb(255, 0, 0);"&gt;近&lt;/span&gt;，力臂&lt;span style="color: rgb(255, 0, 0);"&gt;短&lt;/span&gt;才會省力。等到槓鈴上升過膝蓋以後，維持膝蓋的角度，先&lt;span style="color: rgb(255, 0, 0);"&gt;不要把腳打直&lt;/span&gt;，用下背的力量把軀幹抬起將近&lt;span style="color: rgb(255, 0, 0);"&gt;與地面垂直&lt;/span&gt;時，這時才順勢把腳打直，才比較省力。(&lt;span style="color: rgb(255, 0, 0);"&gt;太早把腳打直&lt;/span&gt;會造成完全用腰背束脊肌在出力，而且離身體&lt;span style="color: rgb(255, 0, 0);"&gt;遠&lt;/span&gt;，力臂&lt;span style="color: rgb(255, 0, 0);"&gt;長&lt;/span&gt;，不好出力。上面這個腿部延遲伸直的技巧常常在外國的高手影片裡頭可以看到，有些甚至會先把重量放在膝蓋上，軀幹在回到垂直地面的角度，再往上拉。)站直後，有些人會有後仰的動作，其實這是不必要的，因為在比賽時，這樣看起來動作的完整度看起來好像較高，所以有人會如此，若要向後仰，膝關節要維持一定的彎曲，若全部伸直，則壓力會全部&lt;span style="color: rgb(255, 0, 0);"&gt;落在腰椎上&lt;/span&gt;，非常容易受傷，要注意。&lt;br /&gt;&lt;br /&gt;##敘述舉重式和健力式窄硬的差別&lt;br /&gt;舉重式的硬舉在啟動時通常側面上看起來大概&lt;span style="color: rgb(255, 0, 0);"&gt;蹲到平行&lt;/span&gt;左右，在比賽的時候會蹲的更低，有整個人都蹲下去的感覺，而且站起來的時候很明顯的看到胸部會往上帶，感覺胸部中間有一條線從上面拉著，腰椎的部位也會盡量的挺出去。在上昇的過程軀幹也不會趴下去，會一直挺著，不會有"釣蝦仔"的情況發生。&lt;br /&gt;&lt;br /&gt;而健力式的窄硬通常一開始臀部的位置處於高點，和舉重式的硬舉比起來，一開始小腿脛骨離槓子的距離有比較近一點，所以也沒辦法蹲的太下去，因為蹲越下去，小腿就會越往前傾，就會頂到槓子。這是由於健力式的硬舉主要是用&lt;span style="color: rgb(255, 0, 0);"&gt;下背的力量&lt;/span&gt;把重量吊起來的緣故。所以不需要蹲太低。&lt;br /&gt;&lt;br /&gt;下面是Andy bolton的健力比賽影片&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/rh3FsjC3NiU&amp;amp;hl=en&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/rh3FsjC3NiU&amp;amp;hl=en&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;這位是挪威的頂尖舉重運動員Geir Grønnevik 220kg 15 times!&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/cvgjS0N6_tU&amp;amp;hl=en&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/cvgjS0N6_tU&amp;amp;hl=en&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;##寬硬敘述&lt;br /&gt;寬硬一開始腳站的寬度因人而異，但通常不要太寬去&lt;span style="color: rgb(255, 0, 0);"&gt;頂到槓片&lt;/span&gt;，這樣放下的時候會比較有壓力，會怕壓到腳趾。腳掌的外翻角度大概是&lt;span style="color: rgb(255, 0, 0);"&gt;45度&lt;/span&gt;。站的時候小腿脛骨就要&lt;span style="color: rgb(255, 0, 0);"&gt;靠緊槓子&lt;/span&gt;，接著屁股也是往後坐，軀幹打直，同時保持挺胸挺腰的姿勢。持續下降到雙手自然下垂就可以觸摸到槓子的高度，之後用先前講的雙手朝指尖方向延伸的握槓方式把槓子握在&lt;span style="color: rgb(255, 0, 0);"&gt;掌心中間&lt;span style="color: rgb(0, 0, 0);"&gt;(握久了手掌中心會有一條繭)&lt;/span&gt;&lt;/span&gt;。然後集中精神吸氣八分飽，握緊槓子屁股往後坐，上背用力叼著，大腿力量全出用&lt;span style="color: rgb(255, 0, 0);"&gt;股四頭&lt;/span&gt;和大腿後側&lt;span style="color: rgb(255, 0, 0);"&gt;股二頭&lt;/span&gt;的力量把槓鈴拉離地面(注意喔這邊先不要把腰往前頂)，頭向上看，背部想辦法用力打直(這時候若是最大肌力則會有點小釣蝦是正常的)。等待腳完全打直後，接著順勢很快的把腰部往前頂讓軀幹垂直地面。完成動作後，在放下槓鈴時不要拋槓，手抓緊槓子，雙腳掌往&lt;span style="color: rgb(255, 0, 0);"&gt;內旋轉&lt;/span&gt;，順勢放下。就不會壓到腳掌。&lt;br /&gt;&lt;br /&gt;所以寬硬通常就是分作&lt;span style="color: rgb(255, 0, 0);"&gt;兩動&lt;/span&gt;，第一動腳撐直，第二動頂腰。重點是第一動上升時背&lt;span style="color: rgb(255, 0, 0);"&gt;不能往前傾&lt;/span&gt;，不然第二動就推不出去，因為力臂變長了。之前有練過腳在伸直的過程同時也做頂腰的動作，但是練久了，不知道什麼原因，大腿上側和髖骨連接的肌肉處會有痠痛感。&lt;br /&gt;&lt;br /&gt;Alex Vishnitsky 400kg ( 881lbs) deadlift&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/xdFlfmmLMbs&amp;amp;hl=en&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/xdFlfmmLMbs&amp;amp;hl=en&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-6402022591690052735?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/6402022591690052735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=6402022591690052735' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/6402022591690052735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/6402022591690052735'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/03/blog-post_30.html' title='我所知道的硬舉'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-588321515315401555</id><published>2008-03-08T22:34:00.000-08:00</published><updated>2009-05-06T00:38:38.232-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='生活'/><title type='text'>關於分紅費用化</title><content type='html'>轉載從ptt tech job&lt;br /&gt; 作者  buggy (立春 等待)                                       看板  Tech_Job&lt;br /&gt; 標題  Re: 有人為了進聯發科而重讀台清交成電機大學部嗎？&lt;br /&gt; 時間  Sun Mar  9 00:55:07 2008&lt;br /&gt;&lt;br /&gt;前面有非常多對於分紅費用化的錯誤資訊... 像 MTK 原本分紅比例 30 幾 %，&lt;br /&gt;費用化後變成 25%，影響比例並不高。&lt;br /&gt;&lt;br /&gt;我知道很多電子公司的 HR 都會看這個版，不知道為何無人澄清...&lt;br /&gt;&lt;br /&gt;MTK 都決定分紅是盈餘的 25% 了，也就是分紅總額是&lt;br /&gt;        (營收 * 毛利 - operating expense) * 25%&lt;br /&gt;而且薪水要列入 operating expense 而非最後 25% 的分紅中，有興趣可以自己算算看&lt;br /&gt;&lt;br /&gt;MTK 今年營收如果能幸運成長到1000億.. 毛利 50%, 營運支出 180 億(Q1法說會數據)&lt;br /&gt;則分紅總額會有 80 億，而這個總額跟股價無關..&lt;br /&gt;&lt;br /&gt;不過今年的最終業績是無法預測的.. 也許好一點或差一點&lt;br /&gt;這就是進去的人要承擔的風險&lt;br /&gt;&lt;br /&gt;另外 MTK 分紅不是很極端的金字塔制... 去年 mtk 分最高的一位拿一百來張...&lt;br /&gt;(是一位高階主管，這差不多等於十幾位員工的平均分紅，但以 MTK 人力規模來看，&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;或 EPS 都是一樣的，但對於員工自己在繳所得稅有影響。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;一家公司的分紅總額是當年盈餘 * 分紅比例，再看怎樣分配給每位員工。&lt;br /&gt;&lt;br /&gt;舉個例子，除非 Realtek 的分紅比例遠高於 25%&lt;br /&gt;(這不可能，否則股價會狂跌、另外分紅比例有法規上限 50%)，&lt;br /&gt;否則假使 Realtek 盈餘除以員工數低於 MTK，Realtek 的「平均分紅」就不可能&lt;br /&gt;高於MTK。這跟公司政策無關，純粹是看公司業績。&lt;br /&gt;&lt;br /&gt;所以有留意過去新聞的人會發現蔡明介是發言支持員工分紅費用化的！&lt;br /&gt;表面上是說回到正規的制度。背後原因恐怕是可以解決掉分紅很高、獲利卻沒一樣高的&lt;br /&gt;的競爭對手。 (我就不提是哪一家了) 所以分紅費用化會對 MTK 招募不見得不利！&lt;br /&gt;&lt;br /&gt;再舉 HTC 的例子，分紅總額 = 股價 * 股數。所以分紅高低跟股價是無關的。&lt;br /&gt;股價只取決於 EPS 以及投資人對於未來獲利成長的信心，但不決定分紅。&lt;br /&gt;電子業過去分紅總額最多的是股價二位數的台積電，因為台積電總盈餘最高。&lt;br /&gt;&lt;br /&gt;HTC 2008 年分紅會是 2008 年獲利的 18%，MTK 2008 年分紅是 2008 獲利的 25%。&lt;br /&gt;&lt;br /&gt;所以除非 HTC 每個員工獲利的 18% 高於 MTK 每個員工獲利的 25%，否則 HTC 的&lt;br /&gt;「平均分紅」不應該比 MTK 高。這都有辦法估算出來。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;舉比較具體的例子，假如 MTK 未分紅的年盈餘 320 億，分紅 25%，則分紅有 80 億。&lt;br /&gt;假如 HTC 未分紅的年盈餘 400 億 (隨便舉例勿當真)，分紅 18%，則分紅共有 72 億。&lt;br /&gt;&lt;br /&gt;假如 HTC 發給員工一張股票的成本是 600 塊，過兩個月漲到 800 塊，&lt;br /&gt;公司的成本還是 60 萬，員工多賺的那 20 萬是員工個人投資的獲利。&lt;br /&gt;&lt;br /&gt;所以如果看好一間公司股票會漲，應該是去買它的股票，而不是加入這間公司。&lt;br /&gt;&lt;br /&gt;同樣的 MTK 資本額現在約 100 億，假如老闆心血來潮去減資 50 億，&lt;br /&gt;原本股價若是 300 塊，股價就會跳成 600 塊，但這只是「數字遊戲」而已，&lt;br /&gt;除了少了約一兩億的利息錢外，MTK 的盈餘跟分紅有多少錢完全不會改變。&lt;br /&gt;(上面只是舉例，沒聽說 MTK 有減資計畫)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;不過如果分部門來看，的確可能會看到 HTC 的一些員工會比 MTK 一些員工高，&lt;br /&gt;因為統計的平均值不代表個體囉。MTK 分紅比例較 HTC 高可能是因為沒有額外廠房&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;至於為何老是有人聽說 MTK 發得不好呢？&lt;br /&gt;&lt;br /&gt;一般來講進 mtk 要一年多才拿得到分紅，而且還取決於前一年的在職月數，&lt;br /&gt;所以前兩年的確有可能收入不太高。&lt;br /&gt;&lt;br /&gt;若只是為了錢進去，就得賭他能賺三年以上，這取決於每個人自己的選擇以及&lt;br /&gt;是否信賴這間公司的管理階層，我就不多說了。&lt;br /&gt;&lt;br /&gt;若不提錢的話，MTK 這間公司如果進入的部門沒什麼問題，還是不錯的學習發展&lt;br /&gt;的地方。我有朋友最近進去後才後悔沒有早幾年投履歷，因為舞台比較大，做出&lt;br /&gt;來的東西可能會有影響力。但我猜也有不少人是為了錢待下來的。 :b&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;今天如果看鴻海、華碩、MTK、HTC 等公司，會發現他們董事及其關係人&lt;br /&gt;持有的股權比例相當高，雖然不排除他們可能能用一些財務操作開海外公司&lt;br /&gt;掌握更多股票，但政府能掌握的股票總額已經夠多了，所以如果公司有重大&lt;br /&gt;利空，受限於內線交易規範，這些董事沒辦法像外資逃命得這麼快，另外上&lt;br /&gt;述公司有不少董事已經很少拿員工分紅了 (甚至有人自掏腰包捐股票)&lt;br /&gt;&lt;br /&gt;雖然人心隔肚皮，但若就「動機」來說，這些大老闆的「利益」已經比較接&lt;br /&gt;近長期投資者，跟拿股票的員工不在同一個陣營了。為什麼他們還願意分紅呢？&lt;br /&gt;這就是市場機制。舉一個板友常舉的例子，過去 VIA 的股權蠻集中在大股東&lt;br /&gt;手上，員工分紅可能因此發比較少或集中在高層，所以反而員工離職率高&lt;br /&gt;(當然還有一些別的原因)，最後大老闆反而賠錢。反而是政府出資為主的 TSMC&lt;br /&gt;過去發股票比較少人心疼，發得不手軟也把那個時候的人才都吸光，反而奠定&lt;br /&gt;永續經營的基業。&lt;br /&gt;&lt;br /&gt;這裡絕對不是說 VIA 的問題會在 HTC 重演，市場機制會讓大老闆學習教訓選擇&lt;br /&gt;對自己最有利的分紅方式，所以今天 HTC 仍會有高額分紅吸引員工。&lt;br /&gt;&lt;br /&gt;既然已經是回到市場機制，就不能再說這些公司發股票是康股東之凱了。&lt;br /&gt;其實台灣的電子公司相較於歐美公司還是很省錢的，我看過 MTK 副總或處長等&lt;br /&gt;級出差坐經濟艙，如果板上有待過 BenQ 的板友，就知道 Siemens 多浪費錢了。&lt;br /&gt;&lt;br /&gt;================&lt;br /&gt;&lt;br /&gt;員工分紅其實是歷史的過程，最好把它視作類似 NASDAQ 網路泡沫或荷蘭鬱金香&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;br /&gt;;----------------------------------------------------------------&lt;br /&gt; 作者  mimi0213 (提拉米蘇好好吃喔)                             看板  Tech_Job&lt;br /&gt; 標題  Re: 分紅費用化 (Re: 有人為了進聯發科而重讀台清? …&lt;br /&gt; 時間  Sun Mar  9 10:34:29 2008&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;"舉個例子，除非 Realtek 的分紅比例遠高於 25% (這不可能、否則股價會狂跌)"&lt;br /&gt;                                                                                &lt;br /&gt;為什麼股價會跌呢？股價和分紅比列有什麼樣的關係，導致分紅比例決定股價？&lt;br /&gt;                                                                                &lt;br /&gt;                                                                                &lt;br /&gt;還有下面這段：&lt;br /&gt;                                                                                &lt;br /&gt;"同樣的 MTK 資本額現在約 100 億，假如老闆心血來潮去減資 50 億，&lt;br /&gt; 原本股價若是 300 塊，股價就會跳成 600 塊"&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;※ 發信站: 批踢踢實業坊(ptt.cc)&lt;br /&gt;◆ From: 220.134.200.244&lt;br /&gt;推 anewjuer:假設資本減少50%淨營收維持不變的情況?                   03/09 10:48&lt;br /&gt;推 RB:當你分紅給員工比較多的時候，股東就不開心，就會賣，就會跌     03/09 10:53&lt;br /&gt;→ RB:減資50%，股價就會變兩倍                                      03/09 10:54&lt;br /&gt;推 bitspirit:但是，2張變1張~~                                      03/09 11:52&lt;br /&gt;→ buggy:前面 RB 大說得不太正確，不管股價高低，只影響張數          03/09 12:45&lt;br /&gt;→ buggy:不影響分紅的市值... 所以說減資拉高股價是數字遊戲          03/09 12:45&lt;br /&gt;→ buggy:像 MTK 這種公司因為多年保留盈餘，所以手邊的現金跟短期     03/09 12:46&lt;br /&gt;→ buggy:投資其實相當驚人，扣掉庫存週轉所需，五十億仍不多...       03/09 12:46&lt;br /&gt;→ buggy:國外像 Apple, MS 等公司也是蠻怕死的... 現金都非常的多     03/09 12:47&lt;br /&gt;;---------------------------------------------------------&lt;br /&gt; 作者  mimi0213 (提拉米蘇好好吃喔)                             看板  Tech_Job&lt;br /&gt; 標題  Re: 分紅費用化 (Re: 有人為了進聯發科而重讀台清? …&lt;br /&gt; 時間  Sun Mar  9 14:14:36 2008&lt;br /&gt;───────────────────────────────────────&lt;br /&gt;                                                                                &lt;br /&gt;剛剛查了一下減資有分為兩種(1)公司法減資 (2)庫藏股減資&lt;br /&gt;                                                                                &lt;br /&gt;其中公司法減資又分為1.名目減資—將列在業主權益項下的累計損失，透過減資方法予以&lt;br /&gt;                                                                                &lt;br /&gt;沖銷，它不改變資產總值，只是認列損失，尤其是先減資再增資。2.實質減資—是將現金&lt;br /&gt;                                                                                &lt;br /&gt;退還給股東，它同時進行資產負債表兩邊的調整（同步減少現金及資產的數量）。&lt;br /&gt;                                                                                &lt;br /&gt;參考:http://www.blogger.com/feeds/2685653712905100724/posts/default&lt;br /&gt;                                                                                &lt;br /&gt;我想這邊前面原波所說的應該是現金減資。&lt;br /&gt;                                                                                &lt;br /&gt;後來又找到了這篇文章:http://blog.pixnet.net/fcko2007/post/3912190&lt;br /&gt;                                                                                &lt;br /&gt;說明如果是減資5成(公司用現金買回1000股中的500股)，換句話說股東的每一張股票公司&lt;br /&gt;                                                                                &lt;br /&gt;用現金5000元買回其中的500股，等於是用股票的面額(10元/股)買回股東手中的持股並註&lt;br /&gt;                                                                                &lt;br /&gt;銷掉，同時股票做加權的動作。我的問題是在加權這邊。假設原本股價500某股東擁有十張&lt;br /&gt;                                                                                &lt;br /&gt;也就是500萬。而公司這時減資買回一半的股票，股東可以獲得10x1000x5 = 50k。&lt;br /&gt;                                                                                &lt;br /&gt;倘若沒有做加權的動作，則這時所擁有的股票總價值變成5 x 50 = 250萬。&lt;br /&gt;                                                                                &lt;br /&gt;為了要恢復原本的價值所以將股價拉到(1000/股)，使的總價值變成5 x 100 = 500萬。&lt;br /&gt;                                                                                &lt;br /&gt;這時股東就多獲得了5萬元。是這樣嗎？不知道我的理解有沒有錯誤？&lt;br /&gt;                                                                                &lt;br /&gt;                                                                                &lt;br /&gt;--&lt;br /&gt;※ 發信站: 批踢踢實業坊(ptt.cc)&lt;br /&gt;◆ From: 220.134.200.244&lt;br /&gt;推 Maybetrue:好深奧O.O                                             03/09 17:24&lt;br /&gt;;-----------------------------------------------------------------------&lt;br /&gt;目前按照面額課稅的作法是根據 促進產業升級條例&lt;br /&gt;  而這個條例要在 98 年落日了 ，之後怎麼課稅應該還沒有結論&lt;br /&gt;  但是不會像以前這麼爽 絕對的肯定的&lt;br /&gt;                                                                                &lt;br /&gt;  98年後 如果要按照除權後價格課稅&lt;br /&gt;  那MTK 大概被課稅25%&lt;br /&gt;  分紅從 3x% 變成25%  剩下的部分還有1/4 會被政府拿走&lt;br /&gt;  員工所得大概會剩下現在的六成不到....&lt;br /&gt;                                                                                &lt;br /&gt;  而未上市的公司就沒有這方面的問題&lt;br /&gt;  到時候為了避稅 說不定都發未上市子公司的股票給員工...&lt;br /&gt;                                                                                &lt;br /&gt;--&lt;br /&gt;※ 發信站: 批踢踢實業坊(ptt.cc)&lt;br /&gt;◆ From: 203.70.242.28&lt;br /&gt;推 buggy:請問原 po 如果是 98 年落日，是指 2010 年所得開始換新制嗎  03/10 00:32&lt;br /&gt;→ buggy:其實 MTK 現金的收入已經佔一定比例了，而且新方法還沒出來   03/10 00:35&lt;br /&gt;→ buggy:所得課稅應該不是從 0% 跳到 25%，這離實際情況很遠..        03/10 00:38&lt;br /&gt;→ buggy:不過屆時如果員工分紅用新制，海外所得仍然只適用於最低稅    03/10 00:42&lt;br /&gt;→ buggy:負制的話，不知道會不會增加 google 這種發 option 的公司    03/10 00:42&lt;br /&gt;→ buggy:的吸引力.. :b                                             03/10 00:43&lt;br /&gt;&lt;br /&gt;;----------------------------------------------------------------&lt;br /&gt;作者  johnstockton (清新明亮系)                               看板  Tech_Job&lt;br /&gt; 標題  Re: 分紅費用化 (Re: 有人為了進聯發科而重讀台清? …&lt;br /&gt; 時間  Sun Mar  9 15:04:08 2008&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;   所以就您這個例子 , 原本股東持有5張股票 ,股價500元 , 公司減資5成&lt;br /&gt;                                                                                &lt;br /&gt;   則減資後參考價為      (500 - 5)&lt;br /&gt;                      ----------------- =   990  元&lt;br /&gt;                           0.5 (減資五成)&lt;br /&gt;                                                                                &lt;br /&gt;                                                                                &lt;br /&gt;                                                                                &lt;br /&gt;   所以這位持有五張股票的股東&lt;br /&gt;                                                                                &lt;br /&gt;       原有市值           新股價 X 剩下股數   +  每股退還 X 原本持有股數&lt;br /&gt;                                                                                &lt;br /&gt;    500  X  5000    =     990   X  2500       +    5      X   5000&lt;br /&gt;                                                                                &lt;br /&gt;     2500000        =     2475000             +     25000&lt;br /&gt;                                                                                &lt;br /&gt;    所以總價值是沒有變的&lt;br /&gt;                                                                                &lt;br /&gt;                                                                                &lt;br /&gt;   照一般來說 , 股東會賺到的是宣告現金減資後的漲停(在市場算是正面消息吧)&lt;br /&gt;   而且減資後 , 公司的ROE 和 EPS都可以增加&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;※ 發信站: 批踢踢實業坊(ptt.cc)&lt;br /&gt;◆ From: 203.118.235.34&lt;br /&gt;※ 編輯: johnstockton    來自: 203.118.235.34       (03/09 15:09)&lt;br /&gt;推 SaturnTrash:除權除息算法!!(沒記錯的話)                          03/10 11:06&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-588321515315401555?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/588321515315401555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=588321515315401555' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/588321515315401555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/588321515315401555'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/03/blog-post_08.html' title='關於分紅費用化'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-6139598176875528586</id><published>2008-03-08T22:21:00.000-08:00</published><updated>2008-03-08T22:33:16.461-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='股票'/><title type='text'>減資的一些觀念</title><content type='html'>參考從：http://www.blogger.com/feeds/2685653712905100724/posts/default&lt;br /&gt;&lt;br /&gt;一、何謂減資所謂減資是指減少公司資本額，使流通在外的股數減少。基本而言，一家公司要減資的狀態分為下列四類：（1）資本額過大，難以再爆發性成長。（2）股東權益報酬率(ROE)太低。（3）現金過剩，沒有合適的投資案。（4）利用減資再增資達到股權重分配。而現行減資方法可分為兩種：（1）公司法減資。（2）庫藏股減資。其中公司法減資操作可分為：1.名目減資—將列在業主權益項下的累計損失，透過減資方法予以沖銷，它不改變資產總值，只是認列損失，尤其是先減資再增資。2.實質減資—是將現金退還給股東，它同時進行資產負債表兩邊的調整（同步減少現金及資產的數量）。另外，庫藏股減資則是據《證交法》第28條之2第1項，符合「為維護公司信用即股東權益所必要而買回，並辦理銷除股份者」的範疇內公司買回庫藏股。 二、聯電減資案依據聯電財務長劉啟東在〈聯電董事會決議進行現金減資＞&lt;br /&gt;&lt;br /&gt;參考從：http://fund.bot.com.tw/z/zk/zk0/zkmain_5_3.asp.htm&lt;br /&gt;&lt;br /&gt;股東權益報酬率＝(稅後淨利－股利發放數)／股東權益 &lt;br /&gt;股東權益報酬率就是該年度股東權益的成長速度。其中稅後淨利部分係指扣除掉特別股股利後之盈餘，而股東權益係指普通股權益總額。由股東權益成長率可以看出，該公司的經營階層的目標是否與股東目標一致，是以股東權益為主要考量。股東權益報酬率係由於企業保留其盈餘所獲得，因此亦顯示一個企業如果不仰賴對外舉債也能促使其企業成長的能力。&lt;br /&gt;&lt;br /&gt;參考從：http://blog.pixnet.net/fcko2007/post/3912190&lt;br /&gt;&lt;br /&gt;我最近終於搞懂了什麼是現金減資&lt;br /&gt;&lt;br /&gt;其實現金減資沒這麼複雜,不必去記那些公式。現金減資簡單的想就是公司用每股10元的票面價買回你手上的部分股票（看減資多少比例決定買回多少比例的股票)以聯電為例減資3成(公司用現金買回1000股中的300股)換句話說股東的每1張股票，公司用3000元買回其，中的300股等於是用股票的面額(10元/股)買回股東手中的持股並且註銷掉。但別忘了聯電1股市價不止10元，所以現金減資也不是什麼好事。雖然會先作加權的動作，減資後每股市價會增加3成，但股價仍會回歸基本面，短期市價雖增加3成，難保長期股價不會跌回到原點，因為聯電獲利狀況不理想且老闆的誠信有不良記錄。所以不管怎樣，以長期投資而言，減資代表的是公司對未來公司的成長性有疑慮。才會想以減資的方式降低股東權益報酬率的分母。因此我不喜歡減資，我喜歡的是公司好好經營，以好好經營的方式，提高股東權益報酬率的分子。同時每年將保留盈餘以固定比例無償分享給股東，這才是王道。而且最重要的是這個配息的基礎不是借錢來配息(例如台塑四寶)。而是以真正賺進大量的自由現金流量為基礎。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-6139598176875528586?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/6139598176875528586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=6139598176875528586' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/6139598176875528586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/6139598176875528586'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/03/blog-post.html' title='減資的一些觀念'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-5960120986683245889</id><published>2008-03-07T08:18:00.000-08:00</published><updated>2008-03-07T08:24:43.617-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='英文'/><title type='text'>Yours faithfully or Yours sincerely?</title><content type='html'>原文引用:http://www.speakspeak.com/html/f_11_english_letter_writing_phrases_cn.htm&lt;br /&gt;&lt;br /&gt;為什麼我們要為商業信件或電郵設開首語？&lt;br /&gt;&lt;br /&gt;-提及先前的通信作為參照；&lt;br /&gt;- 說明您是如何如得知收信人的姓名/地址； &lt;br /&gt;-說明您為何寫信予收信人。 &lt;br /&gt;&lt;br /&gt;10個恰當的開首語：&lt;br /&gt;&lt;br /&gt;With reference to your letter of 8 June, I ...&lt;br /&gt;&lt;br /&gt;I am writing to enquire about ... &lt;br /&gt;&lt;br /&gt;After having seen your advertisement in ... , I would like ... &lt;br /&gt;&lt;br /&gt;After having received your address from ... , I ...&lt;br /&gt;&lt;br /&gt;I received your address from ... and would like ...&lt;br /&gt;&lt;br /&gt;We/I recently wrote to you about ... &lt;br /&gt;&lt;br /&gt;Thank you for your letter of 8 May. &lt;br /&gt;&lt;br /&gt;Thank you for your letter regarding ... &lt;br /&gt;&lt;br /&gt;Thank you for your letter/e-mail about ... &lt;br /&gt;&lt;br /&gt;In reply to your letter of 8 May, ... &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;If you require any further information, feel free to contact me.&lt;br /&gt;&lt;br /&gt;I look forward to your reply. &lt;br /&gt;&lt;br /&gt;I look forward to hearing from you. &lt;br /&gt;&lt;br /&gt;I look forward to seeing you. &lt;br /&gt;&lt;br /&gt;Please advise as necessary. &lt;br /&gt;&lt;br /&gt;We look forward to a successful working relationship in the future.&lt;br /&gt;&lt;br /&gt;Should you need any further information, please do not hesitate to contact me. &lt;br /&gt;&lt;br /&gt;Once again, I apologise for any inconvenience. &lt;br /&gt;&lt;br /&gt;We hope that we may continue to rely on your valued custom.&lt;br /&gt;&lt;br /&gt;I would appreciate your immediate attention to this matter. &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;在商業信件中，何時寫 'Yours faithfully' ？ 何時寫 'Yours sincerely' ？&lt;br /&gt;假設您不知道收件人的姓名：&lt;br /&gt;&lt;br /&gt;Dear Sir ... Yours faithfully &lt;br /&gt;&lt;br /&gt;Dear Madam ... Yours faithfully &lt;br /&gt;&lt;br /&gt;Dear Sir or Madam ... Yours faithfully &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;假設你知道收件人的姓名： &lt;br /&gt;&lt;br /&gt;Dear Mr Hanson ... Yours sincerely &lt;br /&gt;&lt;br /&gt;Dear Mrs Hanson ... Yours sincerely &lt;br /&gt;&lt;br /&gt;Dear Miss Hanson ... Yours sincerely &lt;br /&gt;&lt;br /&gt;Dear Ms Hanson ... Yours sincerely&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;當您寫信給好朋友或是同事： &lt;br /&gt;&lt;br /&gt;Dear Jack ... Best wishes/Best regards &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;當您寫信給與整個部門： &lt;br /&gt;&lt;br /&gt;Dear Sirs ... Yours faithfully&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-5960120986683245889?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/5960120986683245889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=5960120986683245889' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/5960120986683245889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/5960120986683245889'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/03/yours-faithfully-or-yours-sincerely.html' title='Yours faithfully or Yours sincerely?'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-8884812120783416909</id><published>2008-03-06T21:10:00.000-08:00</published><updated>2008-03-06T23:42:52.197-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PCI'/><title type='text'>Introduction to PCI bus operation</title><content type='html'>定義bus master = initiator，target = slave。&lt;br /&gt;當有資料要傳輸時，傳輸端稱為initiator，接收端稱為target。&lt;br /&gt;&lt;br /&gt;Step1：address phase;initiator會把address放在address line，接著把transaction的type放在byte enable bus上面。接著，initiator會asserted FRAME#，使的所有target device都知道initiator要傳送資料。&lt;br /&gt;&lt;br /&gt;Step2：在target device這端經過decode會知道是否這個transaction是針對自己的。若是，則要asserted DEVSEL#(device select)。在經過一段時間後(6 CLK periods)，如果initiator沒有接收到target device送來的DEVSEL#訊號，則會終止這個transaction。&lt;br /&gt;&lt;br /&gt;Step3：接著initiator開始傳送資料，address line和data line是共用的。32bits可以一次傳4個bytes，64bits可以一次傳8個bytes。Initiator要傳幾個bytes是用byte enable signal的數量來表達。&lt;br /&gt;&lt;br /&gt;Step4：Initiator用deasserting FRAME#和asserting IRDY#的方式來表示要傳輸最後的資料。當傳輸完後則會deasserting IRDY#。&lt;br /&gt;&lt;br /&gt;Step5：若PCI bus arbiter先前已經有決定了接下來的initiator，則這個initiator可以監視FRAME#和IRDY#是否deasserted來決定是否輪到他了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-8884812120783416909?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/8884812120783416909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=8884812120783416909' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/8884812120783416909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/8884812120783416909'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/03/introduction-to-pci-bus-operation.html' title='Introduction to PCI bus operation'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-3770819169907956256</id><published>2008-02-25T07:34:00.000-08:00</published><updated>2008-02-25T07:37:19.575-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='健康'/><title type='text'>發燒的正確觀念</title><content type='html'>http://www.wedar.com/health/show.asp?id=1162&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;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;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;就以感冒為例，病人會有咳嗽、流鼻水、喉嚨痛甚至發燒的症狀，一般來說持續個3~5天就會好了，所以當症狀持續或是加劇，甚至高燒不退時，就必須考慮是否是原先的診斷不對或是病情有了變化。因此如果只是將治療擺在退燒上，就有可能將要發生併發症的跡象給掩蓋住，讓醫師根本無從判別究竟是病人的病情真的好了，還是困為給藥後讓症狀消失了。&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;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-3770819169907956256?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/3770819169907956256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=3770819169907956256' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/3770819169907956256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/3770819169907956256'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/02/blog-post_25.html' title='發燒的正確觀念'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-1070543287111858193</id><published>2008-02-21T19:24:00.000-08:00</published><updated>2008-02-21T21:24:01.849-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><title type='text'>Masm segment研究與實驗(full definition)</title><content type='html'>Q:在不同的module內，如果有相同名稱的segment，但，屬性(align, combine, use, class)卻是不同的，這樣是否會產生assemble error？&lt;br /&gt;&lt;br /&gt;A:可以在不同的module(檔案)內宣告同樣名稱的segment，而且attribute不同，所以事實上雖然名稱相同，但是是不同的segment。&lt;br /&gt;&lt;br /&gt;example:  &lt;em&gt;a.asm&lt;/em&gt;&lt;br /&gt;.586&lt;br /&gt;aa segment para private use16 'code'&lt;br /&gt;        assume ds:cc&lt;br /&gt;start:&lt;br /&gt;        mov dx, cc&lt;br /&gt;        mov ds, dx&lt;br /&gt;        mov ax, 4c00h&lt;br /&gt;        int 21h&lt;br /&gt;aa ends&lt;br /&gt;        &lt;br /&gt;cc segment para public use16 'data'&lt;br /&gt;        var dword 15 dup('ffaa')&lt;br /&gt;cc ends&lt;br /&gt;&lt;br /&gt;aa segment para private use16 'code'&lt;br /&gt;        xor ax, ax&lt;br /&gt;aa ends&lt;br /&gt;&lt;br /&gt;end start&lt;br /&gt;&lt;br /&gt;&lt;em&gt;b.asm&lt;/em&gt;&lt;br /&gt;.586&lt;br /&gt;&lt;br /&gt;aa segment para private use16 'code'&lt;br /&gt;        nop&lt;br /&gt;aa ends&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;command line: ml /Fl /Fm a.asm b.asm&lt;br /&gt;&lt;em&gt;a.map&lt;/em&gt;&lt;br /&gt; Start  Stop   Length Name                   Class&lt;br /&gt; 00000H 0000BH 0000CH AA                     CODE&lt;br /&gt; 00010H 00010H 00001H AA                     CODE&lt;br /&gt; 00020H 0005BH 0003CH CC                     DATA&lt;br /&gt;在上面的例子裡也可以發現，aa segment在a.asm有兩個同樣的segment definition，而且還是private，r,結果就證明了，同樣的檔案(module)，就算是private也會把segment combine起來。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-1070543287111858193?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/1070543287111858193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=1070543287111858193' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/1070543287111858193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/1070543287111858193'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/02/masm-segmentfull-definition.html' title='Masm segment研究與實驗(full definition)'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-7875680679087179083</id><published>2008-02-20T21:59:00.000-08:00</published><updated>2008-02-21T19:23:31.490-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><title type='text'>Masm segment研究與實驗(simplified definition)</title><content type='html'>我的Masm問題如下&lt;br /&gt;Q:在near code segment底下(也就是Tiny, Small, Compact)，在同一個檔案(model)裡頭用不一樣的code segment名稱是否會被combine成一個code segment？&lt;br /&gt;&lt;br /&gt;A:答案是不會，就算是在near code segment底下，不同的code segment名稱會有不同的segment，並不會combine。&lt;br /&gt;我在一個asm檔裡頭寫:&lt;br /&gt;.model compact&lt;br /&gt;.586&lt;br /&gt;.code aa&lt;br /&gt;start:&lt;br /&gt;        mov dx, cc&lt;br /&gt;        mov ds, dx&lt;br /&gt;        nop&lt;br /&gt;        nop&lt;br /&gt;        nop&lt;br /&gt;        mov ax, 4c00h&lt;br /&gt;        int 21h&lt;br /&gt;&lt;br /&gt;cc segment para public use16 'data'&lt;br /&gt;        var dword 15 dup('ffaa')&lt;br /&gt;cc ends&lt;br /&gt;&lt;br /&gt;.code ddd&lt;br /&gt;        nop&lt;br /&gt;        nop&lt;br /&gt;        nop&lt;br /&gt;end start&lt;br /&gt;&lt;br /&gt;command line:ml \Fl \Fm a.asm&lt;br /&gt;&lt;br /&gt;結果在map file裡頭可以看到&lt;br /&gt; Start  Stop   Length Name                   Class&lt;br /&gt; 00000H 00000H 00000H _TEXT                  CODE&lt;br /&gt; 00000H 0000CH 0000DH AA                     CODE&lt;br /&gt; 0000EH 00010H 00003H DDD                    CODE&lt;br /&gt; 00012H 00012H 00000H _DATA                  DATA&lt;br /&gt; 00020H 0005BH 0003CH CC                     DATA&lt;br /&gt; 00060H 0045FH 00400H STACK                  STACK&lt;br /&gt;&lt;br /&gt;若是.code後面不加上名稱，則map file如下:&lt;br /&gt; Start  Stop   Length Name                   Class&lt;br /&gt; 00000H 0000FH 00010H _TEXT                  CODE&lt;br /&gt; 00010H 00010H 00000H _DATA                  DATA&lt;br /&gt; 00010H 0004BH 0003CH CC                     DATA&lt;br /&gt; 00050H 0044FH 00400H STACK                  STACK&lt;br /&gt;同一個檔案裡頭的code segment會被combine在一起。&lt;br /&gt;由之前的實驗結果可以知道，如果.code後面的檔名不依，即使在同一個檔案裡，assembler也不會combine起來，更不用說在不同的檔案了。若是在不同的檔案，如果都不指派檔案名稱給.code，Masm porgrammer's guide說在near code segment的模式會把所有的code segment做combine的動作。&lt;br /&gt;實驗如下:&lt;br /&gt;&lt;em&gt;a.asm&lt;/em&gt;&lt;br /&gt;.model compact&lt;br /&gt;.586&lt;br /&gt;.stack&lt;br /&gt;.code&lt;br /&gt;start:&lt;br /&gt;        mov dx, cc&lt;br /&gt;        mov ds, dx&lt;br /&gt;        nop&lt;br /&gt;        nop&lt;br /&gt;        nop&lt;br /&gt;        mov ax, 4c00h&lt;br /&gt;        int 21h&lt;br /&gt;&lt;br /&gt;cc segment para public use16 'data'&lt;br /&gt;        var dword 15 dup('ffaa')&lt;br /&gt;cc ends&lt;br /&gt;end start&lt;br /&gt;&lt;br /&gt;&lt;em&gt;b.asm&lt;/em&gt;&lt;br /&gt;.model compact&lt;br /&gt;.586&lt;br /&gt;.code&lt;br /&gt;        nop&lt;br /&gt;        nop&lt;br /&gt;        nop&lt;br /&gt;        nop&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;command line: ml /Fl /Fm a.asm b.asm&lt;br /&gt;a.map file&lt;br /&gt; Start  Stop   Length Name                   Class&lt;br /&gt; 00000H 00011H 00012H _TEXT                  CODE&lt;br /&gt; 00012H 00012H 00000H _DATA                  DATA&lt;br /&gt; 00020H 0005BH 0003CH CC                     DATA&lt;br /&gt; 00060H 0045FH 00400H STACK                  STACK&lt;br /&gt;果然在near code segment會被combine在一起。&lt;br /&gt;&lt;br /&gt;我把上面範例裡頭compact改成medium，這樣變成far code segment(medium, large, huge)則&lt;br /&gt;a.map file&lt;br /&gt; Start  Stop   Length Name                   Class&lt;br /&gt; 00000H 0000CH 0000DH A_TEXT                 CODE&lt;br /&gt; 0000EH 00011H 00004H B_TEXT                 CODE&lt;br /&gt; 00012H 00012H 00000H _DATA                  DATA&lt;br /&gt; 00020H 0005BH 0003CH CC                     DATA&lt;br /&gt; 00060H 0045FH 00400H STACK                  STACK&lt;br /&gt;code segment name變成filename_TEXT。&lt;br /&gt;&lt;br /&gt;.data後面不能加name，沒有這種用法。加name會錯。&lt;br /&gt;&lt;br /&gt;.fardata如果要取用，要用以下的方式&lt;br /&gt;mov dx, seg FAR_DATA  ; seg FAR_DATA是取出FAR_DATA的segment address，不是offset address&lt;br /&gt;mov ds, dx&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-7875680679087179083?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/7875680679087179083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=7875680679087179083' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/7875680679087179083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/7875680679087179083'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/02/masm-segment.html' title='Masm segment研究與實驗(simplified definition)'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-312290676997564198</id><published>2008-02-05T05:21:00.000-08:00</published><updated>2011-07-28T16:58:06.153-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='健力運動'/><title type='text'>我所知道的蹲舉</title><content type='html'>以我所認識的健力三項運動來說，蹲舉帶給我的身體非常多的助益。應該這樣說，如同音樂界的聖經，若你沒聽過Mozart(莫札特)，或是Beethoven(貝多芬)，如黃鶯出谷般，如此扣人心弦的音樂，將無法體會何謂餘音繞樑，三日不決於耳。如果你不練蹲舉，同時也不練硬舉，你將錯過發展力量最重要的一個雞絲頭，這個雞絲頭所帶給你的力量札實飽足感，你將無法體會。在這邊討論的是蹲舉的&lt;span style="color: rgb(51, 51, 255);"&gt;方法&lt;/span&gt;及&lt;span style="color: rgb(51, 51, 255);"&gt;種類&lt;/span&gt;，以強調&lt;span style="color: rgb(255, 0, 0);"&gt;功能性&lt;/span&gt;為主，至於那些"養身"大道理，姑且不納入討論範圍之內。&lt;br /&gt;&lt;br /&gt;蹲舉，顧名思義，是一種蹲下起立的動作，因為主要是使用腿部肌肉為主，所以時常被健美選手當做訓練腿部的主要動作，在這裡不談那麼多，只談&lt;span style="color: rgb(255, 0, 0);"&gt;如何做重&lt;/span&gt;，如何把力量的效益發揮到最大。既然腿為最主要的用力肌群，先從腿部的動作開始講起，有分為&lt;span style="color: rgb(255, 0, 0);"&gt;寬&lt;/span&gt;站距還有&lt;span style="color: rgb(255, 0, 0);"&gt;短&lt;/span&gt;站距，個人定義寬站距是&lt;span style="color: rgb(255, 0, 0);"&gt;大於&lt;/span&gt;肩膀的站距，短站距大約是在肩膀的寬度以內。腳掌的開度大概是取45度左右，為最佳的外旋角度。寬站距的優點是身體在下蹲的時候屁股往後移動的距離較少，所以背部傾斜的角度可以大大的減少，又因為屁股往後坐的關係，所以主要用到的是臀大肌，和大腿內側的肌群。由於人體的結構，蹲下的幅度無法像窄站距般的可以達到全蹲的range of motion。所以股四頭肌的受力較少。&lt;span style="color: rgb(255, 0, 0);"&gt;身高高的人&lt;/span&gt;可以用寬站距把自己的身材弱點給休飾掉。&lt;br /&gt;&lt;br /&gt;接著往身體上方開始討論手部動作應該如何實施。先以握槓方式來說，比賽的規定要用實握。若是覺得訓練時手有壓力，偶而可以改用虛握來替換，通常過一段時間就會習慣。首先，握槓時手部盡量&lt;span style="color: rgb(255, 0, 0);"&gt;內旋&lt;/span&gt;用手掌的&lt;span style="color: rgb(255, 0, 0);"&gt;外側根部&lt;/span&gt;去頂住槓子，有點類似握推做重時的握槓方式，這樣比較支撐得住重量，也可以減少護腕使用的機率。但手腕若覺得不舒服可以用護腕當作輔助。(我用過Titan的可以推薦給大家，真的很緊)接著討論握槓的寬度之前，要先說明置槓的位置，因為置槓的位置會影響到握槓的寬度。置槓的位置一般來說可以分為兩種，一種扛在&lt;span style="color: rgb(255, 0, 0);"&gt;斜方上&lt;/span&gt;，另一種則是放在&lt;span style="color: rgb(255, 0, 0);"&gt;三角肌後束上頭&lt;/span&gt;有個凹槽的位置。後者為常見的健力扛法。若使用第一種的扛槓方式，手掌的握法就比較輕鬆，因為重量全部落在斜方上面。若使用健力扛法，就要看個人的肩膀柔軟度，通常初學者比較不容易把槓子放在正確的位置，如果柔軟度不好就要握寬一點，這樣槓子就可以放的比較下面。握的寬度就要看自己的柔軟度而定。久而久之就可以越握越近。輕量級選手柔軟度好的手可以握的離肩膀很近。但健力扛法較舉重扛法手腕的壓力大，優點為身體&lt;span style="color: rgb(255, 0, 0);"&gt;力臂較短&lt;/span&gt;，腰部比較省力。&lt;br /&gt;&lt;br /&gt;這一段要討論蹲舉動作的實施，先講窄蹲好了，在蹲舉的過程，窄蹲若要軀幹能夠不傾斜，你就要適度的把&lt;span style="color: rgb(255, 0, 0);"&gt;膝蓋往腳尖&lt;/span&gt;的地方移，也就是要往超過腳尖的方向移動這個意思。你越把膝蓋往腳尖的方向移動，越可以讓&lt;span style="color: rgb(255, 0, 0);"&gt;腰桿子打直&lt;/span&gt;(下面所謂的打直是腰桿趨近垂直於地面)，重心放在臀部上。這就是身體重心的調整。在窄蹲的過程中建議全蹲，也就是臀部壓到底，大腿和小腿貼緊，壓到底後用臀部去支撐重量，若窄蹲不壓到底，腰桿又要挺直，結果全程膝關節都要一直用力支撐著，就會變的膝蓋的受力很大，&lt;span style="color: rgb(255, 0, 0);"&gt;蠻傷膝蓋&lt;/span&gt;的。前面所述這種方式是舉重的方式，旁邊的人看起來好像用腳去蹲，舉重式蹲舉由於軀幹盡量保持垂直於地面，因此下背部負擔相當小，大部份的重量負擔都是在大腿quadriceps上，若有下背痛的問題可以用舉重式蹲舉訓練減少疼痛。由於上述的緣故。屁股往後坐的幅度沒有健力蹲舉那麼的大。但其實看過有些人的天生條件很好，站的窄也可以屁股往後坐的幅度很大(代表有把力量分配到你的臀大肌以及大腿內側的肌群)，蹲的深度又剛剛好(健力的蹲舉深度定義為髖關節在側面看起來低於膝蓋的高度)，身體又可以打直(像原來是bulgarian的澳大利亞籍的stefan botev，可以搜尋youtube他空蹲320kg影片，no no no squat，no belt，no wraps，no spotter)。這就要靠你自己去抓了。&lt;br /&gt;&lt;br /&gt;接著討論寬蹲，順便把整個蹲舉的過程詳細的描述一便(其實窄蹲的方法也是差不多)。一開始當然是站在槓前，槓子調整到大概胸前的高度，這時調整腳的站距，大概是與肩同寬。調整一下心情，順便把手抓好槓子，槓子擺到肩膀正確的位置，ㄍㄧㄥ好，&lt;span style="color: rgb(255, 0, 0);"&gt;挺胸&lt;/span&gt;。然後&lt;span style="color: rgb(255, 0, 0);"&gt;屁股往後頂&lt;/span&gt;好，腰桿子打直，氣吸&lt;span style="color: rgb(255, 0, 0);"&gt;八分&lt;/span&gt;飽(以免岔氣)，用力抬起槓鈴，全身用力撐著。抬起槓鈴後先不要急著往後跨出，先等重量穩定，槓片不晃。跨出步伐有分做兩種，如果是窄蹲通常要&lt;span style="color: rgb(255, 0, 0);"&gt;兩步&lt;/span&gt;就定位，寬蹲是&lt;span style="color: rgb(255, 0, 0);"&gt;三步&lt;/span&gt;就定位，最多&lt;span style="color: rgb(255, 0, 0);"&gt;不能超過四步&lt;/span&gt;以免浪費體力。就定位後換口氣，也是吸到&lt;span style="color: rgb(255, 0, 0);"&gt;八分&lt;/span&gt;飽，準備好後&lt;span style="color: rgb(255, 0, 0);"&gt;頭向上看&lt;/span&gt;，&lt;span style="color: rgb(255, 0, 0);"&gt;屁股往後&lt;/span&gt;翹，接著屁股好像要頂什麼東西般的一直保持穩定的速度往後坐，感覺不是用腳蹲要注意喔，是屁股往後頂(寬蹲此時會感覺到下背部erector spinae有壓力，因為往後坐的因素把一些重量分配到下背部，腿部的吃力就比較小)，在下降的過程&lt;span style="color: rgb(255, 0, 0);"&gt;頭儘量往上抬&lt;/span&gt;可以幫助身體保持挺直。在達到健力標準動作後，臀大肌和大腿首先發力，身體受力後會稍微前傾，同時要記住頭用力往上抬，手腕同時&lt;span style="color: rgb(255, 0, 0);"&gt;往後順勢旋轉&lt;/span&gt;，感覺很像要掙脫什麼東西的樣子(這邊要記得一個重要的技巧，力量舉的蹲法在底下一蹲起的那一瞬間，身體會往前傾斜，此時要記住腿部不要馬上伸直，因為支點在下背部，受力點在肩膀上，如果馬上伸直，這樣力臂會忽然變長，承受不住重量直接往前趴下去。用下背部的力量先把軀幹盡量垂直地面，膝關節往腳尖的方向移動，重量移到大腿上，這樣就可以像先前說的手腕同時往後順勢旋轉，接著把胸部挺起來，因為此時膝關節的角度比在蹲舉最底的角度大，所以可以比較省力的站起來)，一直用力直到站起來。等到站直，穩定後慢慢走進蹲舉架，走進去後不要急著放下槓鈴，等到槓鈴穩定後再放下槓鈴，比較安全。&lt;br /&gt;&lt;br /&gt;要記住的是蹲舉的&lt;span style="color: rgb(255, 0, 0);"&gt;出槓&lt;/span&gt;還有&lt;span style="color: rgb(255, 0, 0);"&gt;放槓&lt;/span&gt;的過程是比較容易輕忽的部份，在走的過程要記住，一隻腳站好以後且站直，再移動另外一直腳。出槓還有放槓千萬不能急，出槓急，腳步不穩容易跌倒，放槓的時候腳步急，槓片容易撞到蹲舉架，不小心就會落槓，很危險的。&lt;br /&gt;&lt;br /&gt;以上是我所知道的蹲舉，若有錯誤，希望不吝指教。&lt;br /&gt;&lt;br /&gt;這邊補充一下幾個地方：&lt;br /&gt;&lt;br /&gt;第一：前面所述的寬蹲"&lt;span style="color: rgb(51, 51, 255);"&gt;下蹲的時候屁股往後移動的距離較少，所以背部傾斜的角度可以大大的減少&lt;/span&gt;"這兩句話的敘述容易引起誤解，其實如果和舉重式的蹲舉相比較，寬蹲臀部往後的幅度很大的，也因為臀部往後壓的關係，所以背部是&lt;span style="color: rgb(255, 0, 0);"&gt;非常傾斜&lt;/span&gt;的。這句話的原意是，如果和窄蹲又要為了減少膝蓋的壓力而臀部往後坐相比，寬蹲的傾斜幅度會比較小。&lt;br /&gt;&lt;br /&gt;第二：在蹲舉下蹲的過程當中，是閉氣的狀態(而且同時膝蓋是往腳掌的&lt;span style="color: rgb(255, 0, 0);"&gt;切線方向&lt;/span&gt;延伸固定住，不要往內夾，這樣內側廣肌容易拉傷)，直到蹲起時，才放聲喊出來。&lt;br /&gt;&lt;br /&gt;第三：舉重式蹲舉由於蹲到底，且軀幹盡量保持在與地面垂直的情況下，此時腳掌踝關節與膝關節需要非常好的柔韌性，在初學者一開始實施要注意的是阿基里斯腱以及膝關節的柔軟度。訓練前要特別注意這兩個關節的拉筋伸展動作。如果腳踝關節柔軟度仍然不佳，可以在腳跟處墊木板，槓片，或者是穿著專業的舉重鞋，減少腳踝關節延伸的角度。要記得墊高後腳跟的同時也是加重了膝關節的壓力。&lt;br /&gt;&lt;br /&gt;網路上一些不錯的連結&lt;br /&gt;&lt;a href="http://www.halaclub.com/showthread.php?t=46" target="_blank"&gt;一個天賦平平的人如何成為深蹲高手&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.deepsquatter.com/strength/archives/MINE/howIdothesquat2.htm" target="_blank"&gt;How I do the Squat     By: Jason Burnell&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-312290676997564198?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/312290676997564198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=312290676997564198' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/312290676997564198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/312290676997564198'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/02/blog-post.html' title='我所知道的蹲舉'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-5655767139616211902</id><published>2008-01-28T22:20:00.000-08:00</published><updated>2009-05-06T00:38:38.233-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='生活'/><title type='text'>手機業的發展，轉載從ptt tech job</title><content type='html'>[閒聊] 我所知道的手機產業/公司 (上)&lt;br /&gt; &lt;br /&gt;僅就個人知道的部份試著簡單的寫看看好了&lt;br /&gt;(我是 2005 年底從 Industry 領域進入 Mobile 產業)&lt;br /&gt;如有謬誤還請不吝指正 m(_ _)m&lt;br /&gt;                                                                                &lt;br /&gt;x       x       x       x&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;1. Own Brand (自有品牌) ex. HTC(前身是Dopod), BenQ(併Siemens失敗收場), ASUS ..&lt;br /&gt;2. ODM (代工設計/通常兼製造) ex. 華寶, 奇美, 華冠, 英華達 ...&lt;br /&gt;3. OEM (代工製造) ex. 鴻海, 廣達, 英業達 ...&lt;br /&gt;                                                                                &lt;br /&gt;其實通常一開始都是 OEM/ODM (量大但利潤少)&lt;br /&gt;有能力/遠見的廠會開始發展 Own Brand (量少但利潤高)&lt;br /&gt;用 OEM/ODM 賺的錢養 Own Brand 部門,&lt;br /&gt;但 Own Brand 坐大後 OEM/ODM 的客戶會不爽 (給你錢賺讓你壯大來打我!?)&lt;br /&gt;這時候一般就會面臨 品牌/代工 分家&lt;br /&gt;在網通如 友訊 就把代工切出去變 明泰 留下品牌 D-Link&lt;br /&gt; 在其他如 宏基 就把代工切出去變 緯創 留下品牌 Acer&lt;br /&gt;在最近如 華碩 就把代工切出去變 和碩 留下品牌 Asus&lt;br /&gt;                                                                                &lt;br /&gt;HTC/Dopod 是個比較特殊的例子&lt;br /&gt;仗著本身厚實的 Windows mobile 研發功力&lt;br /&gt;它代工客戶在現今產業中找不到其他"同品質"足以替代的 ODM 廠&lt;br /&gt;要不就是找功力差一截的 ODM 同業 (不能指名以免得罪人惹禍上身@@)&lt;br /&gt;要不只好被掐著脖子讓它賺 (這就是為啥 HTC 利潤好到可以當股王!!)&lt;br /&gt;HTC 也從幫手機品牌廠代工轉變成跟系統營運商(ex.Vodafone,中華電信..)合作&lt;br /&gt;稱為 Co-Brand (自己望文生義吧)&lt;br /&gt;好處是系統營運商的利潤不是來自手機銷售, 所以跟 HTC 是互利而不衝突的&lt;br /&gt;然後就是眾所皆知的開始經營 HTC 這個品牌 (尤其 Touch 系列)&lt;br /&gt;                                                                                &lt;br /&gt;其他 Own Brand 我記得的有:&lt;br /&gt;                                                                                &lt;br /&gt;BenQ 想用併 Siemens 抄捷徑 (站在巨人的肩膀上)&lt;br /&gt;我個人認為這個思維/方向本身是對的&lt;br /&gt;可惜低估了難度終究導致失敗&lt;br /&gt;花了新台幣三百億(!?)讓所有人都上了一課&lt;br /&gt;                                                                                &lt;br /&gt;GigaByte (集嘉 from 技嘉) 做了幾隻, 個人不予置評 (XD)&lt;br /&gt;                                                                                &lt;br /&gt;ASUS (華碩) 在走自己的路吧, 我了解的也不多 (sorry &gt;&lt;)&lt;br /&gt;                                                                                &lt;br /&gt;OKWAP (英華達) 也算品牌, 但好像只跼限在台灣(!?)&lt;br /&gt;                                                                                &lt;br /&gt;GoFish (倚天) 也是, 目前為止好像沒幾隻(!?)&lt;br /&gt;                                                                                &lt;br /&gt;再來是 OEM/ODM:&lt;br /&gt;剛好手機從產品角度慣例分為兩大塊:&lt;br /&gt;                                                                                &lt;br /&gt;1. Feature phone: GSM 2G/2.5G/2.75G ...&lt;br /&gt;2. Smartphene: Symbian, Windows Mobile, Linux ...&lt;br /&gt;(我不十分確定 PDA phone 是否列入 Smartphone 還是分開!?)&lt;br /&gt;                                                                                &lt;br /&gt;台灣電子業幾乎都是從 OEM/ODM 起家&lt;br /&gt;所以現今手機產業人才(管理階層/資深研發人員)幾乎都是從代工大廠分家出來的&lt;br /&gt;"我所知道的早期手機代工廠" 大概有 光寶/明基(當時叫明碁)/大霸/泓越 ...&lt;br /&gt;(抱歉其實很晚才進手機產業,很多憑片段記憶沒有詳細考證,時間上可能有點錯亂@@)&lt;br /&gt;從以上幾個[搖籃]的人才/團隊陸續出走&lt;br /&gt;到業界就長成一個個的小公司 只是個個路不一樣&lt;br /&gt;有的來不及長大就夭折了 &gt;o&lt; 有的則變成現在你我熟知的公司&lt;br /&gt;                                                                                &lt;br /&gt;明基最早出走的一批是 行銷/業務(!?)Leader池育陽帶領的團隊&lt;br /&gt;成立了現在的奇美通訊 後來被富士康入股 成了鴻海集團的一員&lt;br /&gt;國碁原本是宏基集團的一園&lt;br /&gt;後來也是被鴻海買下 其中部份產品便是 CDMA 手機&lt;br /&gt;這部份較少在板上被提及/討論&lt;br /&gt;                                                                                &lt;br /&gt;明基陸續"吐出"的人才/團隊, 有一組"曾"在內湖成立一家手機廠叫[研傳 (Exec)]&lt;br /&gt;"號稱"做出第一隻 3M Pixels 的手機 ...&lt;br /&gt;現在"好像"是掛了,人員應該是流到其他各手機廠&lt;br /&gt;                                                                                &lt;br /&gt;明基出走的還有一票去了廣達..&lt;br /&gt;剪不斷理還亂的一堆愛恨情仇到現在(其實是我搞不清楚)&lt;br /&gt;                                                                                &lt;br /&gt;明基(印象中是)的另一批人成立了華山科技&lt;br /&gt;後來被仁寶集團入主就成了現在板友熟知的華寶通訊&lt;br /&gt;之前分別在八德路跟東興街有 Office&lt;br /&gt;在瑞光路上的仁寶內原本也有個做手機的部門 (PMCC)&lt;br /&gt;後來也在組織上合併到華寶&lt;br /&gt;然候不久前一起搬到現在陽光街新址 (亞大經貿)&lt;br /&gt;                                                                                &lt;br /&gt;x       x       x       x&lt;br /&gt;                                                                                &lt;br /&gt;呼~ 原本想簡單寫, 竟寫了這麼多 &gt;&lt;&lt;br /&gt;                                                                                &lt;br /&gt;本篇當做是上半部, 再開一篇寫下半部好了 @@&lt;br /&gt;&lt;br /&gt;作者  EdwardY (葉小飛)                                        看板  Tech_Job&lt;br /&gt; 標題  [閒聊] 我所知道的手機產業/公司 (下)&lt;br /&gt; 時間  Tue Jan 29 04:23:17 2008&lt;br /&gt;───────────────────────────────────────&lt;br /&gt;                                                                                &lt;br /&gt;文前聲明:&lt;br /&gt;前篇與本篇僅為個人記憶/認知/解讀的部份&lt;br /&gt;如有謬誤, 歡迎不吝指正&lt;br /&gt;                                                                                &lt;br /&gt;x       x       x       x&lt;br /&gt;                                                                                &lt;br /&gt;在往下講到另外某些公司前&lt;br /&gt;必須先提一下 大M(聯發科) 還有 Foxlink(正崴)&lt;br /&gt;                                                                                &lt;br /&gt;我只解釋以下有關的部份:&lt;br /&gt;                                                                                &lt;br /&gt;話說聯發科剛發展手機晶片時完全沒人相信/敢用&lt;br /&gt;大M就想自行成立一家公司&lt;br /&gt;希望用自家的Solution做出手機"用以向世人證明"&lt;br /&gt;於是聯合零組件大廠正崴合資成立了達智科技(DARTS)&lt;br /&gt;正崴(Foxlink)常被視為是泛鴻海集團(Foxconn)的一部份&lt;br /&gt;但其實弟弟(郭台強)跟哥哥(郭台銘)算是兄弟各自爬山&lt;br /&gt;甚至在很多領域/產品上是競爭對手&lt;br /&gt;正崴不像鴻海可以包山包海什麼都做&lt;br /&gt;所以期望能在手機產業做到垂直整合&lt;br /&gt;除了本身在手機零組件上的優勢外&lt;br /&gt;更買下Motorola在天津的電池廠&lt;br /&gt;(所以 Moto 的電池大多是正崴代工的)&lt;br /&gt;再下一步就是手機整機設計 也就是達智了&lt;br /&gt;                                                                                &lt;br /&gt;但後來因雙方對公司未來走向意見不合&lt;br /&gt;聯發科要用達智發展/證明更多更高明的技術 (假設例如3G)&lt;br /&gt;這是要接高階手機的訂單&lt;br /&gt;但正崴要的是衝量&lt;br /&gt;手機組裝集團內相關產品的出貨量才是王道&lt;br /&gt;這是要接低階手機的訂單 能才有大量&lt;br /&gt;OOXX 之後的結果&lt;br /&gt;正崴出資買下了達智幾乎全部的股份&lt;br /&gt;達智部份團隊出走華冠 (同時也帶走不少生意)&lt;br /&gt;另外部份則到了聯發科資金再抑注的另間在內湖的公司-易連 (MBK)&lt;br /&gt;約一年後,達智(中和)剩下的團隊還是因為經營不善管理失當&lt;br /&gt;跟前面提及也在之前某個時間點被正崴併的大霸/泓越團隊(內湖)&lt;br /&gt;幾乎同時間被併回到正崴公司內部(土城)&lt;br /&gt;"因為許多不足為外人道的原因"&lt;br /&gt;部份繼續發展 feature phone, 屬移動通訊事業群&lt;br /&gt;另部份則發展其他產品, 一年後也陸續有了 "各自的發展" XD&lt;br /&gt;                                                                                &lt;br /&gt;其中部份的發展是回到中和成立另一家手機公司[景泰]&lt;br /&gt;(好像)又是聯發科大金主蔡老闆明介的資金&lt;br /&gt;除了部份達智/正崴的團隊外&lt;br /&gt;成立時間剛好吸納一批明基併西門子失敗後離開的團隊&lt;br /&gt;最近改名為[景發]&lt;br /&gt;在內湖新成立的 office 重心仍放在 feature phone&lt;br /&gt;原中和的 office 則是專注發展 Smartphone&lt;br /&gt;                                                                                &lt;br /&gt;華碩自己做手機 也曾成立一家兆碩做手機 (恕我不知他們內部怎麼分@@)&lt;br /&gt;只知道(應該吧)後來還是又併回去了&lt;br /&gt;                                                                                &lt;br /&gt;還有一家原來叫[佰創] 後來"傳說是鴻海郭老闆台銘的資金加持"&lt;br /&gt;決定專注發展 Smartphone, "希望" 能接前述不爽 HTC 而轉單的代工&lt;br /&gt;再加上延攬 Cisco China 退下的總裁當負責人&lt;br /&gt;於是改名為板友熟知 HQ 在桃園, 分部在南港的 誠實科技&lt;br /&gt;                                                                                &lt;br /&gt;簡略排名一下(個人觀點):&lt;br /&gt;                                                                                &lt;br /&gt;宏達電 (HTC) 在前面獨跑&lt;br /&gt;其他想做 Smartphone 的各家大小廠商還在大亂鬥&lt;br /&gt;無論是 誠實/華碩 暫時都還構不成威脅&lt;br /&gt;                                                                                &lt;br /&gt;以 Feature ODM 而言,&lt;br /&gt;Nokia / Samsung 沒放單 (之前)&lt;br /&gt;華寶 (CCI) 以專做 Moto 而成為 ODM 第一&lt;br /&gt;原本 華冠 (Arima) 排第二, 專接 SonyErrison, 還有吸收達智後的 LG&lt;br /&gt;但現在 奇美通訊 (FIH) 迎頭趕上, 緊咬華寶, 華冠已被拋在後面&lt;br /&gt;(從股價就看得出來)&lt;br /&gt;景發 (???) 能見度不高 不予置評&lt;br /&gt;易連 (MBK) 震盪整理中 後勢待觀察&lt;br /&gt;明基 (BenQ) 奮力再起中 不可小覷&lt;br /&gt;....&lt;br /&gt;                                                                                &lt;br /&gt;x       x       x       x&lt;br /&gt;                                                                                &lt;br /&gt;我記得的好像就這些了吧!?&lt;br /&gt;                                                                                &lt;br /&gt;反正大家跳來跳去就這幾家&lt;br /&gt;吃個同事喜酒常碰到 "我的前同事是你公司現在同事" 這類事情 ..&lt;br /&gt;                                                                                &lt;br /&gt;所以千萬要記得, "產業很小, 信用非常重要" !!&lt;br /&gt;請參考我在 #18014 提到的最後一段,&lt;br /&gt;大家各自努力吧 ^^&lt;br /&gt;                                                                                &lt;br /&gt;    &lt;br /&gt;                                                                                &lt;br /&gt;Ed~&lt;br /&gt;                                                                                &lt;br /&gt;PS. 再強調一次, 純就個人記憶及解讀所為文,&lt;br /&gt;    如果謬誤, 請不吝賜教, 謝謝 m(_ _)m&lt;br /&gt;                                                                                &lt;br /&gt;還有, 從文章認出我的人, 請發私人信就好,&lt;br /&gt;不要在推文或回文中點破我, 謝謝 @@&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-5655767139616211902?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/5655767139616211902/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=5655767139616211902' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/5655767139616211902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/5655767139616211902'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/01/ptt-tech-job.html' title='手機業的發展，轉載從ptt tech job'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-4221727639538481555</id><published>2008-01-16T01:25:00.000-08:00</published><updated>2008-01-16T01:44:52.613-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><title type='text'>Macro redefinition &amp; recursive</title><content type='html'>簡單的舉個例子：&lt;br /&gt;.code&lt;br /&gt;Test Macro&lt;br /&gt;    &lt;em&gt;LOCAL addloop&lt;/em&gt;&lt;br /&gt;mov ax, 0&lt;br /&gt;mov cx, 5&lt;br /&gt;&lt;br /&gt;addloop:          ;2x5&lt;br /&gt;    add ax, 2&lt;br /&gt;    loop addloop&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;endm&lt;br /&gt;&lt;br /&gt;begin:&lt;br /&gt;    Test          ; call Test macro&lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;.exit&lt;br /&gt;end begin&lt;br /&gt;&lt;br /&gt;若上面的macro之後沒有加上LOCAL addloop則沒有辦法重複呼叫。&lt;br /&gt;會有error A2005 symbol redefinition的問題。&lt;br /&gt;&lt;br /&gt;接著討論recursive macro。今天下午試了很久，終究沒有辦法把recursive macro試出來，結果想了一個例子，最後證明assembly是不支援recursive macro的。上網查了一下發覺C也沒有支援recursive macro。&lt;br /&gt;.code &lt;br /&gt;checkout macro&lt;br /&gt;    jmp exit&lt;br /&gt;    checkout&lt;br /&gt;exit:&lt;br /&gt;&lt;br /&gt;endm&lt;br /&gt;&lt;br /&gt;start:&lt;br /&gt;    checkout&lt;br /&gt;&lt;br /&gt;.exit&lt;br /&gt;end start&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-4221727639538481555?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/4221727639538481555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=4221727639538481555' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/4221727639538481555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/4221727639538481555'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/01/macro-redefinition-recursive.html' title='Macro redefinition &amp; recursive'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-8648816401057804562</id><published>2008-01-09T02:17:00.000-08:00</published><updated>2008-04-10T23:35:37.942-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bios'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><title type='text'>assembly segment的寫法</title><content type='html'>TITLE switch screen&lt;br /&gt;        .586            &lt;br /&gt;code    SEGMENT PARA PUBLIC USE16 &lt;br /&gt;        ASSUME  cs:code&lt;br /&gt;;; 使用 16 位元定址方式，不用use16無法在dos底下運作，執行時會當掉&lt;br /&gt;;-------------------------------------------&lt;br /&gt;;    code area..&lt;br /&gt;;-------------------------------------------&lt;br /&gt;start:&lt;br /&gt;        mov     ax,4C00h      &lt;br /&gt;        int     21h&lt;br /&gt;code    ENDS&lt;br /&gt;        END     start&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-8648816401057804562?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/8648816401057804562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=8648816401057804562' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/8648816401057804562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/8648816401057804562'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2008/01/assembly-segment.html' title='assembly segment的寫法'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36581178.post-116176699474862545</id><published>2006-10-25T02:02:00.000-07:00</published><updated>2006-10-25T02:03:14.760-07:00</updated><title type='text'>hello world~~</title><content type='html'>This is my first google blog.....^^&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36581178-116176699474862545?l=bboytaiwan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bboytaiwan.blogspot.com/feeds/116176699474862545/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36581178&amp;postID=116176699474862545' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/116176699474862545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36581178/posts/default/116176699474862545'/><link rel='alternate' type='text/html' href='http://bboytaiwan.blogspot.com/2006/10/hello-world.html' title='hello world~~'/><author><name>bboy</name><uri>http://www.blogger.com/profile/04536679236003348967</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
