<?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/opensearch/1.1/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0' gd:etag='W/&quot;D0AHR34zcSp7ImA9WhVRE0U.&quot;'><id>tag:blogger.com,1999:blog-810103497999497955</id><updated>2012-03-21T20:08:56.089-07:00</updated><category term='非工作'/><category term='閒聊'/><category term='程式設計'/><category term='EFI'/><category term='心得'/><category term='心情'/><category term='筆記'/><category term='工作'/><title>Matthew's Garbage Dump</title><subtitle type='html'>Garbage Collector</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://matt.tlf.jp/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default?redirect=false&amp;v=2'/><link rel='alternate' type='text/html' href='http://matt.tlf.jp/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Matthew Huang</name><uri>http://www.blogger.com/profile/10773062842303886980</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_k7F3MIx6j_I/RfUsxtiTHYI/AAAAAAAAAA8/Bi9Qx5Nv0lY/s320/jhhead01.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>16</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry gd:etag='W/&quot;DkEHQHk5fCp7ImA9Wx9QEU4.&quot;'><id>tag:blogger.com,1999:blog-810103497999497955.post-1555072006296428097</id><published>2010-12-23T11:37:00.000-08:00</published><updated>2010-12-23T12:03:51.724-08:00</updated><app:edited xmlns:app='http://www.w3.org/2007/app'>2010-12-23T12:03:51.724-08:00</app:edited><category scheme='http://www.blogger.com/atom/ns#' term='心得'/><category scheme='http://www.blogger.com/atom/ns#' term='非工作'/><title>別以為你不會碰到 (2)</title><content type='html'>常常看到有人寫了一堆檔，等到要互相做連結的時候，才開始在需要用的 c 檔裡面做 extern，『要用的函數交給 extern，責任全交給編譯器』，這樣其實超危險。&lt;br /&gt;
&lt;br /&gt;
要知道 c 是一個完全依賴 coder 邏輯的語言，除了 syntax 或 casting 這種低級錯誤之外，其它模陵兩可的動作，編譯器的預設立場是『我相信這是你要的結果』。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;//aaa.c
int func_a (uint8_t numInput) {
  return ++numInput;
}&lt;/pre&gt;&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;//bbb.c
extern int func_a(void);

int func_b (void){
  int numCatch;
  numCatch = func_a();
  printf ("holy shit %d\n", numCatch);
  return 0;
}&lt;/pre&gt;&lt;br /&gt;
範例舉得很傻，但定義如下：&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;int* GetHash (
    int *workingBuffer, 
    char **hashArray, 
    double potential, 
    uint32_t modulus
)&lt;/pre&gt;&lt;br /&gt;
還敢說不會有問題嗎？&lt;br /&gt;
&lt;br /&gt;
extern 聲明參數和定義不同。這範例結果是 linker 在連結的時候不會報 error，程式執行印出來一堆從暫存器拉出來的鬼數字。&lt;br /&gt;
&lt;br /&gt;
當做一個比較大型的項目，也許會拆到近萬隻源檔，這時候一些基本功就能看得出高下。&lt;br /&gt;
&lt;br /&gt;
需要發佈到所有源檔裡面的函數，我會直接拖個原型在 .h，這邊就是發佈的根源，要用這隻函數，請 include header。不需要發佈的，一律上 static 鎖死在這隻檔裡，或乾脆做 inline。&lt;br /&gt;
&lt;br /&gt;
第一個就是多數 compiler 抓得出錯誤，無須下額外指令，第二個就是非常好整理，畢竟用的是近 30 年的舊語言，它不是很聰明，我們就要多想想。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/810103497999497955-1555072006296428097?l=matt.tlf.jp' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://matt.tlf.jp/feeds/1555072006296428097/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://matt.tlf.jp/2010/12/2.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/1555072006296428097?v=2'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/1555072006296428097?v=2'/><link rel='alternate' type='text/html' href='http://matt.tlf.jp/2010/12/2.html' title='別以為你不會碰到 (2)'/><author><name>Matthew Huang</name><uri>http://www.blogger.com/profile/10773062842303886980</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_k7F3MIx6j_I/RfUsxtiTHYI/AAAAAAAAAA8/Bi9Qx5Nv0lY/s320/jhhead01.JPG'/></author><thr:total>0</thr:total></entry><entry gd:etag='W/&quot;DkIBRnw5eSp7ImA9Wx5aGE4.&quot;'><id>tag:blogger.com,1999:blog-810103497999497955.post-7830747946119742909</id><published>2010-11-15T07:22:00.000-08:00</published><updated>2010-11-15T07:22:37.221-08:00</updated><app:edited xmlns:app='http://www.w3.org/2007/app'>2010-11-15T07:22:37.221-08:00</app:edited><category scheme='http://www.blogger.com/atom/ns#' term='心得'/><category scheme='http://www.blogger.com/atom/ns#' term='工作'/><title>近期的感悟</title><content type='html'>最近在工作上發現很多奇妙的東西。OEM 板子 port 的跟 CRB 一模一樣，可是就是點不亮，GPIO 設定說是 62 隻，可是注解就寫 61~63 腳是做啥啥用的。&lt;br /&gt;
&lt;br /&gt;
這次做 Oak Trail 與其說危機，不如說是契機，真的搞出來，我實力會進步得很厲害。&lt;br /&gt;
&lt;br /&gt;
盡信 spec 不如無 spec，但不遵循 spec 做出來的東西就是廢鐵，請密切追蹤本 blog。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/810103497999497955-7830747946119742909?l=matt.tlf.jp' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://matt.tlf.jp/feeds/7830747946119742909/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://matt.tlf.jp/2010/11/blog-post.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/7830747946119742909?v=2'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/7830747946119742909?v=2'/><link rel='alternate' type='text/html' href='http://matt.tlf.jp/2010/11/blog-post.html' title='近期的感悟'/><author><name>Matthew Huang</name><uri>http://www.blogger.com/profile/10773062842303886980</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_k7F3MIx6j_I/RfUsxtiTHYI/AAAAAAAAAA8/Bi9Qx5Nv0lY/s320/jhhead01.JPG'/></author><thr:total>0</thr:total></entry><entry gd:etag='W/&quot;D0ANQn85fyp7ImA9Wx5VE00.&quot;'><id>tag:blogger.com,1999:blog-810103497999497955.post-1243665329169674032</id><published>2010-10-05T12:09:00.000-07:00</published><updated>2010-10-05T12:09:53.127-07:00</updated><app:edited xmlns:app='http://www.w3.org/2007/app'>2010-10-05T12:09:53.127-07:00</app:edited><category scheme='http://www.blogger.com/atom/ns#' term='心得'/><category scheme='http://www.blogger.com/atom/ns#' term='非工作'/><title>別以為你不會碰到 (1)</title><content type='html'>很多時候，問題都是出在空格上面&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;result = *x / *y;&amp;nbsp; //no problem&lt;/pre&gt;&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;result = *x/*y;&amp;nbsp; //compile error&lt;/pre&gt;&lt;br /&gt;
查了好久都不知道為什麼，後來發現… y 被當成多行注解，抹掉了&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;result = (*x) / (*y); //for your safety&lt;/pre&gt;&lt;br /&gt;
其實有時候不是在寫公司的 code 很懶得去注意 style，上述的方法基本上是沒在用，只能說永遠記得，C 是 &lt;b style="background-color: #b6d7a8;"&gt;maximal munch strategy&lt;/b&gt;，你不把運算符切開，它一次就咬住最大口來分析代碼。&lt;br /&gt;
&lt;br /&gt;
經典問題：&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;a = x+++y;&lt;/pre&gt;&lt;br /&gt;
答案為下列何者？&lt;br /&gt;
1.&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;a = x+&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ++y;&lt;/pre&gt;&lt;br /&gt;
2.&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;a = x++&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; +y;&lt;/pre&gt;&lt;br /&gt;
思考一下 :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/810103497999497955-1243665329169674032?l=matt.tlf.jp' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://matt.tlf.jp/feeds/1243665329169674032/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://matt.tlf.jp/2010/10/1.html#comment-form' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/1243665329169674032?v=2'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/1243665329169674032?v=2'/><link rel='alternate' type='text/html' href='http://matt.tlf.jp/2010/10/1.html' title='別以為你不會碰到 (1)'/><author><name>Matthew Huang</name><uri>http://www.blogger.com/profile/10773062842303886980</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_k7F3MIx6j_I/RfUsxtiTHYI/AAAAAAAAAA8/Bi9Qx5Nv0lY/s320/jhhead01.JPG'/></author><thr:total>1</thr:total></entry><entry gd:etag='W/&quot;DUEMR3s5fSp7ImA9Wx5XFkg.&quot;'><id>tag:blogger.com,1999:blog-810103497999497955.post-255031161494621563</id><published>2010-09-16T10:21:00.000-07:00</published><updated>2010-09-16T10:21:26.525-07:00</updated><app:edited xmlns:app='http://www.w3.org/2007/app'>2010-09-16T10:21:26.525-07:00</app:edited><category scheme='http://www.blogger.com/atom/ns#' term='心得'/><category scheme='http://www.blogger.com/atom/ns#' term='工作'/><title>前進</title><content type='html'>下單位一個多月了，感覺 leader 和前輩都很好相處，而且大家知識很深，相較之下自己對於相關的東西還嫌太淺，以下簡述。&lt;br /&gt;
&lt;br /&gt;
對硬體的架構和整個 UEFI 的 Bootflow 了解程度仍需加強，一個平台到手上後要先了解全局構造，有什麼部件，基本上就是要把他們推起來，這自然是廢話，要不然焊在板子上做啥？&lt;br /&gt;
&lt;br /&gt;
EFI 的 flow，怎麼走，pei 怎麼去 init，dxemain 怎麼去推 dispatcher，順序、滿足條件，思考了一下，都需要經驗的累積，這部份其實還算好，common knowledge 上網就能查到，畢竟 tiano 在這一塊仍然是公開的。&lt;br /&gt;
&lt;br /&gt;
難是難在不公開的這一段，就需要多問，多學，多筆記。把學習的東西轉成養份，好好去培。&lt;br /&gt;
&lt;br /&gt;
目前 bring up 不是很大的問題，卡是卡在 windows 下要正常 function，這些東西就很機密了，但不違反商機的學習流路未來可以和大家分享一下。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/810103497999497955-255031161494621563?l=matt.tlf.jp' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://matt.tlf.jp/feeds/255031161494621563/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://matt.tlf.jp/2010/09/blog-post_16.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/255031161494621563?v=2'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/255031161494621563?v=2'/><link rel='alternate' type='text/html' href='http://matt.tlf.jp/2010/09/blog-post_16.html' title='前進'/><author><name>Matthew Huang</name><uri>http://www.blogger.com/profile/10773062842303886980</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_k7F3MIx6j_I/RfUsxtiTHYI/AAAAAAAAAA8/Bi9Qx5Nv0lY/s320/jhhead01.JPG'/></author><thr:total>0</thr:total></entry><entry gd:etag='W/&quot;C0ICQnk4eSp7ImA9Wx5QF0Q.&quot;'><id>tag:blogger.com,1999:blog-810103497999497955.post-9202362383857793764</id><published>2010-09-06T09:46:00.000-07:00</published><updated>2010-09-06T09:46:03.731-07:00</updated><app:edited xmlns:app='http://www.w3.org/2007/app'>2010-09-06T09:46:03.731-07:00</app:edited><category scheme='http://www.blogger.com/atom/ns#' term='非工作'/><category scheme='http://www.blogger.com/atom/ns#' term='心情'/><title>什麼是將才之風？</title><content type='html'>今天跟朋友聊到 cache as ram 和 ram only 的工程模式，在 google code 上做了一些試驗，發現差異不是一個數量級的。朋友就來了個很妙的問題：大將之風…是什麼？&lt;br /&gt;
&lt;br /&gt;
老實說，我不知道，因為從來沒當過大將。一輩子庸庸碌碌的寫 code，看 code，看算法，寫算法，肚子裡的東西不少，搬得上檯面的不多 (肚子本身除外)。&lt;br /&gt;
&lt;br /&gt;
今天在公司好挫折，一個 20 分鐘就解出來的問題，卻遲遲不敢發，到晚上 8 點才不情願的弄了個 solution。為什麼會這樣，工程思維及經驗的不足導致行動遲滯，這一點再不改進，會是非常恐怖的致命傷。&lt;br /&gt;
&lt;br /&gt;
這輩子錯過不少好機會，這次不會再讓它從指間流走。&lt;br /&gt;
&lt;br /&gt;
關於 cache as ram 的問題可能週末搬過來這邊跟大家討論一下，這期間就做一些 common 的討論，順便寫一些紀錄。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/810103497999497955-9202362383857793764?l=matt.tlf.jp' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://matt.tlf.jp/feeds/9202362383857793764/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://matt.tlf.jp/2010/09/blog-post.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/9202362383857793764?v=2'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/9202362383857793764?v=2'/><link rel='alternate' type='text/html' href='http://matt.tlf.jp/2010/09/blog-post.html' title='什麼是將才之風？'/><author><name>Matthew Huang</name><uri>http://www.blogger.com/profile/10773062842303886980</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_k7F3MIx6j_I/RfUsxtiTHYI/AAAAAAAAAA8/Bi9Qx5Nv0lY/s320/jhhead01.JPG'/></author><thr:total>0</thr:total></entry><entry gd:etag='W/&quot;D0QMRng_cCp7ImA9Wx5REUk.&quot;'><id>tag:blogger.com,1999:blog-810103497999497955.post-7200411844387623205</id><published>2010-08-18T08:29:00.000-07:00</published><updated>2010-08-18T08:29:47.648-07:00</updated><app:edited xmlns:app='http://www.w3.org/2007/app'>2010-08-18T08:29:47.648-07:00</app:edited><category scheme='http://www.blogger.com/atom/ns#' term='工作'/><category scheme='http://www.blogger.com/atom/ns#' term='心情'/><title>Assembly</title><content type='html'>下單位之後，整天都在忙 power on，上 feature，自己寫 code 的空間是零。所以最近 leader 放了兩個 assembly 作業，真的超高興，寫得很用心。&lt;br /&gt;
&lt;br /&gt;
組語是本行，寫得真是順手…寫完三個月的 UEFI code，換成組語也是滿恐怖的，沒有語言的保護，直接跟硬體面對面硬幹，有錯誤就毫不留情的噴給你看，這種特性也是蠻值得懷念。 &lt;br /&gt;
&lt;br /&gt;
今天又領了經理裝備 (羅西塔小姐的 "來領鋼盔水壺" 的梗不錯笑)，20" 的 LCD，不免俗的普通牌鍵鼠組，8G dongle。螢幕接上去後，coding 果然是爽歪歪，字好大。&lt;br /&gt;
&lt;br /&gt;
這幾天不忙再把 asm code 貼上來分析分享一下。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/810103497999497955-7200411844387623205?l=matt.tlf.jp' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://matt.tlf.jp/feeds/7200411844387623205/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://matt.tlf.jp/2010/08/assembly.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/7200411844387623205?v=2'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/7200411844387623205?v=2'/><link rel='alternate' type='text/html' href='http://matt.tlf.jp/2010/08/assembly.html' title='Assembly'/><author><name>Matthew Huang</name><uri>http://www.blogger.com/profile/10773062842303886980</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_k7F3MIx6j_I/RfUsxtiTHYI/AAAAAAAAAA8/Bi9Qx5Nv0lY/s320/jhhead01.JPG'/></author><thr:total>0</thr:total></entry><entry gd:etag='W/&quot;DEEHR3s-eCp7ImA9Wx5TFE0.&quot;'><id>tag:blogger.com,1999:blog-810103497999497955.post-7927817165967247618</id><published>2010-07-29T05:27:00.000-07:00</published><updated>2010-07-29T05:30:36.550-07:00</updated><app:edited xmlns:app='http://www.w3.org/2007/app'>2010-07-29T05:30:36.550-07:00</app:edited><category scheme='http://www.blogger.com/atom/ns#' term='工作'/><category scheme='http://www.blogger.com/atom/ns#' term='心情'/><title>下部隊</title><content type='html'>經過三個月的努力，終於完成了階段性的任務，從 NTC 畢業了。&lt;br /&gt;
&lt;br /&gt;
雖然說期末考被我玩炸了，不過看了一下期中考和作業成績，要過關應該還算是容易。&lt;br /&gt;
&lt;br /&gt;
大家紛紛整理裝備往各層移動，一邊和同學說再見，一邊深知這種團體日子應該在今天就會做個總結。&lt;br /&gt;
&lt;br /&gt;
大家都撤了，和 Ian 兩個人在空蕩蕩的會議室等別人來接，心情是很忐忑不安，但潛意識更希望能趕快與工作接軌，畢竟收了錢不是來讀書的，NTC 只是個小門檻。&lt;br /&gt;
&lt;br /&gt;
Vincent 過來把兩人叫出去，分配了位置，結果真的如 mail 所說：暫時座位：x 樓 xx 號。&lt;br /&gt;
&lt;br /&gt;
真囧，仔細想想，我的工作之路好像一路充滿笨點：識別證名字打錯，丟給 HR 重做，到現在還沒來。結果小三梯的學弟都有照片了，我識別證還是白牌，現在連座位都是暫時配置，搞什麼呢。。。&lt;br /&gt;
&lt;br /&gt;
安頓好了之後，跑去問兩位學長接下來該準備什麼。請購單、SVN 申請，去找指導學長，一步步來，穩穩地走。&lt;br /&gt;
&lt;br /&gt;
拷貝 codebase，porting guide，相關 spec。東西都齊了，剩下的就是這三個月磨出來的工程思維，不懂的，搜；不會的，查，心情不能游移，我要變強，我要成為首屈一指的 BIOS 工程師。&lt;br /&gt;
&lt;br /&gt;
不過在達到目標之前，說的話都是屁就是了。&lt;br /&gt;
&lt;br /&gt;
開 Slickedit，導入 codebase 做 tag，開 referrence，比照 code，追函數，查電氣特性，一切都是那麼熟悉，NTC 紮下來的底子果然有用。&lt;br /&gt;
&lt;br /&gt;
接下來就是等 MIS 來新筆電、19" 螢幕、鍵鼠組、Dongle，林林總總的雞絲。&lt;br /&gt;
希望接下來的日子大家都能順利，成功就在不遠的地方，加油吧，1004。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/810103497999497955-7927817165967247618?l=matt.tlf.jp' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://matt.tlf.jp/feeds/7927817165967247618/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://matt.tlf.jp/2010/07/blog-post.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/7927817165967247618?v=2'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/7927817165967247618?v=2'/><link rel='alternate' type='text/html' href='http://matt.tlf.jp/2010/07/blog-post.html' title='下部隊'/><author><name>Matthew Huang</name><uri>http://www.blogger.com/profile/10773062842303886980</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_k7F3MIx6j_I/RfUsxtiTHYI/AAAAAAAAAA8/Bi9Qx5Nv0lY/s320/jhhead01.JPG'/></author><thr:total>0</thr:total></entry><entry gd:etag='W/&quot;DE8EQX89eCp7ImA9WxFbFk0.&quot;'><id>tag:blogger.com,1999:blog-810103497999497955.post-3420955000740827014</id><published>2010-07-07T04:01:00.000-07:00</published><updated>2010-07-08T09:33:20.160-07:00</updated><app:edited xmlns:app='http://www.w3.org/2007/app'>2010-07-08T09:33:20.160-07:00</app:edited><title>PEIM &amp; PPI</title><content type='html'>入口函式原型 (PeiApi.h @ EDK)：&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;typedef
EFI_STATUS
(EFIAPI *EFI_PEIM_ENTRY_POINT)(
  IN EFI_FFS_FILE_HEADER       * FfsHeader,
  IN EFI_PEI_SERVICES          **PeiServices
  );&lt;/pre&gt;&lt;br /&gt;
比較常用到的幾個函數：&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;(**PeiServices).LocatePpi&lt;/pre&gt;這個函數要注意的就是 PEI Phase 下 PPI 的存放和 DXE 下存放 PROTOCOL 略有不同，因為 PEI FOUNDATION 會用來存放 PPI DB，所以很有可能一個 DB 裡 N 個 INSTANCE，第三個參數就是讓你選第幾個 INSTANCE 用的，第一個為 0，以此類推。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;Status = (**PeiServices).CreateHob (
    PeiServices,
    EFI_HOB_TYPE_XXX,
    (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + PrivateDataSize),
    (VOID**) &amp;amp;HobBuffer
    );&lt;/pre&gt;&lt;br /&gt;
這個函數要注意的地方就是 CreateHOB 他只幫你弄個 HEADER 出來，要塞 HOB 資料，要自己拉空間出來，算好 OFFSET 是要件。&lt;br /&gt;
函數成功的話，HobBuffer 就會指一塊空間出來給你。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;(**PeiServices).CopyMem (
    (VOID*)(((UINT8*) HobBuffer) + sizeof (EFI_HOB_GUID_TYPE)),
    (VOID*) PrivateData,
    (UINTN) PrivateDataSize
    );&lt;/pre&gt;&lt;br /&gt;
再來也是算 OFFSET 把資料 COPY 進去，就行了。&lt;br /&gt;
&lt;br /&gt;
DXE Phase 下：&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;EFI_HOB_HANDOFF_INFORMATION_TABLE  *HobList;
LibGetSystemConfigurationTable (&amp;amp;gEfiHobListGuid, (VOID**) &amp;amp;HobList);&lt;/pre&gt;&lt;br /&gt;
藉此取得 HOBLIST，然後再用想對應的函數把你要的 HOB 拉出來就行了，如果我上面 HOB 的 TYPE 是 EFI_HOB_TYPE_GUID_EXTENSION，同時這個 HOB.Name 有加以指定一個 GUID，那我在 DXE Phase 下就能使用下列函數把 HOB 倒出來：&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;GetNextGuidHob ((VOID**) &amp;amp;HobList, &amp;amp;HobNameGuid, (VOID**) &amp;amp;HobContent, &amp;amp;BufferSize);&lt;/pre&gt;&lt;br /&gt;
關於為什麼 PEI Service Table 要做成雙指標，&lt;span style="background-color: #93c47d;"&gt;在 BIOSREN 論壇 srcore 兄做了很漂亮的解釋&lt;/span&gt;，這邊借轉載並改成台灣用語：&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #9fc5e8;"&gt;『這個問題細究起來有點意思。這裡頭有歷史原因，其實依現在看來，定義成直接指標就可以了。』&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;『PEI 階段中，在 Main Memory 可用之前，PEI Core 和 PEIM 都必須在 flash 上 XIP。XIP 就意味著全域變數只能讀，不能寫。所以PEI Core在 memory 可用並且把自己 Shadow 到 memory 之前，是不可以用全域變數保存自己在 Stack 中分配的 PrivateData 的位址的。』&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;『這就是說我們必須有一種方法能讓 PEI CORE 在 PEIM 調用 PEI Service 的時候，能從傳進來的指向 PEI Serivces Table 的間接指標得到 PEI CORE 自己私有資料的位址。』&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;『當初，規範定義 EFI_PEI_SERVICES ** 是期望如下的 PEI CORE 的實現：舉例說明』&lt;/div&gt;&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;typedef struct {    ...
  EFI_PEI_SERVICES *PS,
  ...
  } PEI_CORE_DATA;&lt;/pre&gt;&lt;br /&gt;
&lt;div style="background-color: #9fc5e8;"&gt;『PEI_CORE_DATA 在 Stack 上分配，PS 域被初始化為 PEI Core 資料段中 PEI Service Table 的指標。』&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;『&amp;amp;PEI_CORE_DATA.PS 不就是EFI_PEI_SERVICES ** 嗎？通過 CR 就可能得到 Stack 上 PEI_CORE_DATA 的地址。』&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;『注意，這裡有個前提，就是 PEI Service Table 中所有域的值都是固定的，作為一個 PEI Core 的全域變數存放在資料段中。』&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;『對，這就是定義 EFI_PEI_SERVICES ** 的由來。』&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;『有人會問，如果PEI CORE按照如下實現：』&lt;/div&gt;&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;typedef struct {
  ...
  EFI_PEI_SERVICES PSTable,
  ...
} PEI_CORE_DATA;&lt;/pre&gt;&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;br /&gt;
&lt;div style="background-color: #9fc5e8;"&gt;『就是說在 PEI Core 的 PrivateData 中定義一份 PEI Service Table 而不是指向它的指標，PEI Core 在初始化的時候將自己資料段中 PEI Service Table 作為範本拷到 PEI_CORE_DATA.PSTable 中。』&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;『這樣，就只用定義 EFI_PEI_SERVICES * （即 &amp;amp;PEI_CORE_DATA.PSTable）就可以了。確實如此，但規範仍然定義 EFI_PEI_SERVICES **，是考慮到 PEI Service Table 是固定的，可以直接放在 flash 上 PEI Core image 的資料段裡，PEI CORE 私有資料裡有一個指標指向它就可以了，這樣可以省掉一些對 temporary memory 的佔用，畢竟 temporary memory 的資源還是比較寶貴的。』&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;『瞭解了它的最初的設計意圖，那為什麼說回過頭來看，其實定義成直接指標就可以了？』&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;『因為 PEI CIS 規範的修訂使得 PEI Service Table 裡面的值不再是 build time 決定之後就不變的了。PEI CIS 0.91 在 PEI Service Table 加入了 CPU IO PPI 和 PCI CFG PPI 的指標。這兩個指標必須在執行時填入，所以 PEI Service Table 不能再放在 flash 上了，它必須被放到 memory 裡，這樣它才能被修改。』&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="background-color: #9fc5e8;"&gt;『所以現在PEI CORE的實現一般是這樣：』&lt;/div&gt;&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;typedef struct {
  ...
  EFI_PEI_SERVICES *PS,
  ...
  ...
  EFI_PEI_SERVICES PSTable,
  ...
} PEI_CORE_DATA;&lt;/pre&gt;&lt;br /&gt;
&lt;div style="background-color: #9fc5e8;"&gt;『PEI Core 在初始化的時候將自己資料段中 PEI Service Table 作為模組拷到 PEI_CORE_DATA.PSTable 中，然後 PEI_CORE_DATA.PS = &amp;amp;PEI_CORE_DATA.PSTable。』&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/810103497999497955-3420955000740827014?l=matt.tlf.jp' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://matt.tlf.jp/feeds/3420955000740827014/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://matt.tlf.jp/2010/07/peim-ppi.html#comment-form' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/3420955000740827014?v=2'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/3420955000740827014?v=2'/><link rel='alternate' type='text/html' href='http://matt.tlf.jp/2010/07/peim-ppi.html' title='PEIM &amp; PPI'/><author><name>Matthew Huang</name><uri>http://www.blogger.com/profile/10773062842303886980</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_k7F3MIx6j_I/RfUsxtiTHYI/AAAAAAAAAA8/Bi9Qx5Nv0lY/s320/jhhead01.JPG'/></author><thr:total>2</thr:total></entry><entry gd:etag='W/&quot;CUABRXY6eip7ImA9Wx5WEEQ.&quot;'><id>tag:blogger.com,1999:blog-810103497999497955.post-6416850486272456109</id><published>2010-06-27T13:11:00.000-07:00</published><updated>2010-09-21T11:29:14.812-07:00</updated><app:edited xmlns:app='http://www.w3.org/2007/app'>2010-09-21T11:29:14.812-07:00</app:edited><category scheme='http://www.blogger.com/atom/ns#' term='心得'/><category scheme='http://www.blogger.com/atom/ns#' term='EFI'/><category scheme='http://www.blogger.com/atom/ns#' term='工作'/><category scheme='http://www.blogger.com/atom/ns#' term='筆記'/><title>EFI SMM Driver Programming</title><content type='html'>SMI 分兩種，Sw 和 Hw。&lt;br /&gt;
&lt;br /&gt;
作業是以 Dxe&amp;nbsp; Driver 為主，故討論 Dxe 面。&lt;br /&gt;
&lt;br /&gt;
SwSmi 的主要攻略技巧就是先鎖定幾項重點：&lt;br /&gt;
&lt;br /&gt;
1. SMM Driver 機制 &lt;br /&gt;
2. 如何將 Dxe Driver 送進 SMRAM&lt;br /&gt;
3. 如何 Register SwSmi Notification&lt;br /&gt;
4. 如何控制 SwSmi Notification&lt;br /&gt;
5. 如何產生 SwSmi&lt;br /&gt;
&lt;br /&gt;
SMM Driver 和一般 Dxe Driver 不同的地方，就是 SMM Driver 會&lt;span style="background-color: #b6d7a8;"&gt;跑兩次&lt;/span&gt;。&lt;br /&gt;
&lt;br /&gt;
第一次在 Dxe Phase，經用 EFI_SMM_BASE_PROTOCOL.InSmm () 先做驗證是否在 SMM Mode 下。&lt;br /&gt;
&lt;br /&gt;
如果為 FALSE，則使用 Register () 函數執行第二次，這個函數可以看成是 SMM 下的 Driver Entry Point。&lt;br /&gt;
&lt;br /&gt;
接著，在 SMM 下進入 Entry Point，再做 InSmm () 驗證，如果為 TRUE，則執行相關處理，抱括 SwSmiInputValue 的指定，利用 EFI_SMM_SW_DISPATCH_PROTOCOL&amp;nbsp; 的 Register () 做函數綁定。&lt;br /&gt;
&lt;br /&gt;
這部份很重要，因為 EFI_SMM_SW_DISPATCH_PROTOCOL 是由南橋 Bus 產生，所以當這邊有指定的 Value 填進 SMI Command Port 時，南橋偵測到就會觸發 SMI# 或是傳遞訊息。CPU 收到後，會有小小的 Delay (並不像書上寫的 "馬上"，因為負責偵測 SMI 的組件並不一定就是接受 SMI 的組件)，就會做 Function Callback，工程師就是在這塊做處理。&lt;br /&gt;
&lt;br /&gt;
SmiInputValue 倒是好填，Command Port 指定就很麻煩，每個晶片組都不同，以前在寫 Win32 API 的經驗是 &lt;span style="background-color: #b6d7a8;"&gt;0xB2 for Intel ICH mostly&lt;/span&gt;，具體看那張板子什麼晶片組的吧....估計老師是做 AMD Chipset 的才會報 0xB0，這部份如果照單全收很容易『挫街』。&lt;br /&gt;
&lt;br /&gt;
每個 codebase 都有自己的 SMI Cmd Port 定義的檔，ACPI Spec 也有，程式功夫一大抄，對 codebase 搜索強的自然吃香一點。&lt;br /&gt;
&lt;br /&gt;
上面知道了，Trigger 就比較簡單，只要對特定的 SMI Cmd Port 填特定的值就行了。&lt;br /&gt;
&lt;br /&gt;
進入到 SMM 後可用的服務被限制到很低，可用 SMMBASE 提供的 GetSmstLocation，拿到 SMM 的 System Table ，還是有一些東西可以用的，I/O Mem 存取之類。&lt;br /&gt;
&lt;br /&gt;
比較需要注意的地方就是，因為 SMM 跨度十分廣，所以有可能 driver 存活得比自己的 producer 還久，故在使用 protocol 時務必注意，不要使用到跨度後會失效的 (例如 Boot Services 下的東西)。&lt;br /&gt;
&lt;br /&gt;
另外目前了解到的知識是，如果想把 SMM 下的 driver unload，進到 SMM 解掉掛在上面的 dispatcher 就行了，如下：&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;mSwSmmDispatcher-&amp;gt;UnRegister (mSwSmmDispatcher, mSwmSmmHandle);
mPbSmmDispatcher-&amp;gt;UnRegister (mPbSmmDispatcher, mPbmSmmHandle);&lt;/pre&gt;&lt;br /&gt;
&lt;div style="background-color: #93c47d;"&gt;只是比較奇怪的是，在 DXE 下 register 的 SMM Base 竟然在 DXE 下解不掉，Handle 都對的。。。不緊張，未來搞懂再補充回來。&lt;/div&gt;&lt;br /&gt;
9/22 補充： 為何 SMM Base 在 DXE 下解不掉，原因是在 Unload 處我把他 Handle 下注冊的函數全 UnRegister 了，根據 EFI Spec，當一 Handle 下沒任何掛載時，它會被 Handle Database 回收，所以造成在 UnRegister SMM Base 時找不到 Handle&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/810103497999497955-6416850486272456109?l=matt.tlf.jp' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://matt.tlf.jp/feeds/6416850486272456109/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://matt.tlf.jp/2010/06/efi-smm-driver-programming.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/6416850486272456109?v=2'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/6416850486272456109?v=2'/><link rel='alternate' type='text/html' href='http://matt.tlf.jp/2010/06/efi-smm-driver-programming.html' title='EFI SMM Driver Programming'/><author><name>Matthew Huang</name><uri>http://www.blogger.com/profile/10773062842303886980</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_k7F3MIx6j_I/RfUsxtiTHYI/AAAAAAAAAA8/Bi9Qx5Nv0lY/s320/jhhead01.JPG'/></author><thr:total>0</thr:total></entry><entry gd:etag='W/&quot;DEADQnk4cSp7ImA9WxFbFk0.&quot;'><id>tag:blogger.com,1999:blog-810103497999497955.post-5822238529514885580</id><published>2010-06-27T00:55:00.000-07:00</published><updated>2010-07-08T09:32:53.739-07:00</updated><app:edited xmlns:app='http://www.w3.org/2007/app'>2010-07-08T09:32:53.739-07:00</app:edited><category scheme='http://www.blogger.com/atom/ns#' term='心得'/><category scheme='http://www.blogger.com/atom/ns#' term='工作'/><category scheme='http://www.blogger.com/atom/ns#' term='筆記'/><title>EDK service driver  or Application INF basic structure</title><content type='html'>目前寫程式常常遭遇到最麻煩的地方就是在改變 codebase 時，INF 檔的配置，因為還不太明白，所以都常常在 error message 裡邊看自己缺什麼路徑邊補上去。&lt;br /&gt;
&lt;br /&gt;
這邊做個記錄，EDK 底下做 driver 最基礎的 INF 檔結構，如果沒有其它需求，通常這個 INF 可以直接套上去。&lt;br /&gt;
&lt;br /&gt;
在 .h 檔裡：&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;#include "Tiano.h"
#include "EfiDriverLib.h"
#include "EfiPrintLib.h" //需要 Debug 或 Print 再用&lt;/pre&gt;&lt;br /&gt;
INF 檔裡：&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;[defines]
BASE_NAME            = #BaseName
FILE_GUID            = #Guid
COMPONENT_TYPE       = BS_DRIVER

[sources.common]
  DriverName.c

[includes.common]
  .
  $(EDK_SOURCE)\Foundation
  $(EDK_SOURCE)\Foundation\Include
  $(EDK_SOURCE)\Foundation\Efi
  $(EDK_SOURCE)\Foundation\Efi\Include
  $(EDK_SOURCE)\Foundation\Framework
  $(EDK_SOURCE)\Foundation\Framework\Include
  $(EDK_SOURCE)\Foundation\Library\Dxe\Include

[libraries.common]
  EfiDriverLib
  EfiPrintLib&amp;nbsp;  #同 include 檔
[nmake.common]
  IMAGE_ENTRY_POINT=#DriverEntryPoint&lt;/pre&gt;&lt;br /&gt;
接下來就是 Application 的 include file 和 INF 檔配置，這應該用得比較少，不過有用時就方便了。&lt;br /&gt;
&lt;br /&gt;
.h 檔&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;#include "EfiShellLib.h"&lt;/pre&gt;&lt;br /&gt;
INF 檔&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;[defines]
BASE_NAME            = #BaseName
FILE_GUID            = #Guid
COMPONENT_TYPE       = APPLICATION

[sources.common]
  ApplicationName.c

[includes.common]
  .
  $(EFI_SOURCE)
  $(EFI_SOURCE)\Include
  $(EDK_SOURCE)\Foundation
  $(EDK_SOURCE)\Foundation\Core\Dxe\
  $(EDK_SOURCE)\Foundation\Efi
  $(EDK_SOURCE)\Foundation\Efi\Include
  $(EDK_SOURCE)\Foundation\Framework\
  $(EDK_SOURCE)\Foundation\Include
  $(EDK_SOURCE)\Foundation\Framework\Include
  $(EDK_SOURCE)\Foundation\Include\IndustryStandard
  $(EFI_SOURCE)\Application\Shell\Library
  $(EFI_SOURCE)\Application\Shell\inc

[libraries.common]
  EfiShellLib
  EdkFrameworkGuidLib

[nmake.common]
  IMAGE_ENTRY_POINT=ApplicationEntry&lt;/pre&gt;&lt;br /&gt;
Component Type 可用 FvVolume.c 內查詢得知：&lt;br /&gt;
&lt;pre class="brush: cpp; gutter: false"&gt;static const COMP_TYPE_EXTENSION mCompTypeExtension[] = 
{
  {"bs_driver",             ".dxe" },
  {"rt_driver",             ".dxe" },
  {"sal_rt_driver",         ".dxe" },
  {"pic_peim",              ".pei" },
  {"pe32_peim",             ".pei" },
  {"application",           ".app" },
  {"file",                  ".ffs" },
  {"fvimagefile",           ".fvi" },
  {"raw_file",              ".raw" },
  {"apriori",               ".ffs" },
  {"combined_peim_driver",  ".pei" },
  { NULL,                   NULL }
};&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/810103497999497955-5822238529514885580?l=matt.tlf.jp' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://matt.tlf.jp/feeds/5822238529514885580/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://matt.tlf.jp/2010/06/edk-service-driver-inf-infrastructure.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/5822238529514885580?v=2'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/5822238529514885580?v=2'/><link rel='alternate' type='text/html' href='http://matt.tlf.jp/2010/06/edk-service-driver-inf-infrastructure.html' title='EDK service driver  or Application INF basic structure'/><author><name>Matthew Huang</name><uri>http://www.blogger.com/profile/10773062842303886980</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_k7F3MIx6j_I/RfUsxtiTHYI/AAAAAAAAAA8/Bi9Qx5Nv0lY/s320/jhhead01.JPG'/></author><thr:total>0</thr:total></entry><entry gd:etag='W/&quot;D0EMQ345fyp7ImA9Wx5REUk.&quot;'><id>tag:blogger.com,1999:blog-810103497999497955.post-6930519258259737487</id><published>2010-06-23T11:38:00.000-07:00</published><updated>2010-08-18T08:34:42.027-07:00</updated><app:edited xmlns:app='http://www.w3.org/2007/app'>2010-08-18T08:34:42.027-07:00</app:edited><category scheme='http://www.blogger.com/atom/ns#' term='程式設計'/><category scheme='http://www.blogger.com/atom/ns#' term='心得'/><category scheme='http://www.blogger.com/atom/ns#' term='非工作'/><title>第一隻 Brain Fuck 程式</title><content type='html'>所有程式語言遍歷一次，是我的夢想。&lt;br /&gt;
&lt;br /&gt;
LISP, COBOL, Fortran, Pascal，無聊的時候都有拿來玩過，不求精，有 Hello World 就好。&lt;br /&gt;
&lt;br /&gt;
在軍中有幸見識到迪吉多 1988 年出產的 VAX6000 ，還用它寫過&amp;nbsp; PL/I&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://research.microsoft.com/en-us/um/people/gbell/digital/timeline/photos/vax6200.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://research.microsoft.com/en-us/um/people/gbell/digital/timeline/photos/vax6200.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;這台高貴不貴的電冰箱…不是，這台性能強大的工作站，可是當資訊兵 7、8 個月天天在碰的東西。&lt;br /&gt;
&lt;br /&gt;
第一次看到兩台跟 UPS 一樣大的硬碟，驚訝程度可想而知...它的腳本語言也是十分怪異，有點像 bash 混合 MSDOS。不過工作需求，我竟然還把它玩精了。&lt;br /&gt;
&lt;br /&gt;
這玩意很 high，處理個 3MB 的 txt 檔，包括解密，比對項目 db 到印出報表要 8 小時，常常整天龜在資訊室就是弄這 shit。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
後來一個不爽，用 .NET 改寫整個 flow 才花 15 秒就做完原本三天份的量，剩下 7 小時 59 分鐘就拿來打茫，這又是後話了...&lt;br /&gt;
&lt;br /&gt;
啊啊!! 離題太遠，回到 Brain Fuck。這玩意超級恐怖，果然不負其名，光是寫個小小的 Hi! Matt 就快把我的 Brain 給 Fuck 了。不過它的優點是很原始，很野性，指標和位址的移動，有種 asm 的直觀爽感，而且符合圖靈完全思維…閒話不多說，來看 code：&lt;br /&gt;
&lt;pre class="brush: cpp;gutter: false"&gt;+++++ +++++
[
  &amp;gt; +++
  &amp;gt; +++++ ++
  &amp;gt; +++++ ++++
  &amp;gt; +++++ +++++
  &amp;gt; +++++ +++++ +
  &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; -
]
&amp;gt;&amp;gt; ++.
&amp;gt;&amp;gt; +++++.
&amp;lt;&amp;lt;&amp;lt; +++.
&amp;gt;+. 
&amp;lt; +++++ +.
&amp;gt;&amp;gt;&amp;gt; ++++.
&amp;lt;&amp;lt;&amp;lt; ----- --.
&amp;gt; ++++.
&amp;gt; +++++ ++.
&amp;gt;&amp;gt; +++++ +.
  .
&amp;lt;&amp;lt;&amp;lt;&amp;lt; +.&lt;/pre&gt;&lt;br /&gt;
連成一條龍也不是不行，不過那個太刻意 fuck 了，這樣就夠 fuck 。&lt;br /&gt;
換成 c code:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp;gutter: false"&gt;unsigned char arr[30000] = {0};
*arr = 10; 

while (*arr) {
  *(arr + 1) += 3;
  *(arr + 2) += 7;
  *(arr + 3) += 9;
  *(arr + 4) += 10;
  *(arr + 5) += 11;
  *arr-=1;
} 

putchar (*(arr + 2) += 2);
putchar ((*(arr + 4) += 5));
putchar ((*(arr + 1) += 3));
putchar (++*(arr + 2));
putchar ((*(arr + 1) += 6));
putchar ((*(arr + 4) += 4));
putchar ((*(arr + 1) -= 7));
putchar ((*(arr + 2) += 4));
putchar ((*(arr + 3) += 7));
putchar ((*(arr + 5) += 6));
putchar (*(arr + 5));
putchar ((*(arr + 1) += 1));&lt;/pre&gt;&lt;br /&gt;
或許你會問：有 compiler 嗎？&lt;br /&gt;
別說 compiler，連 IDE 都有!!&lt;br /&gt;
&lt;br /&gt;
可在這邊下載 &lt;a href="http://4mhz.de/bfdev.html"&gt;4mhz.de/bfdev.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
最後還是想說一句…雖然忙，該玩的東西還是要玩一下的...&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_k7F3MIx6j_I/TCJUPimAKAI/AAAAAAAAAJQ/cgSJLunT5Y8/s1600/bf.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="560" src="http://3.bp.blogspot.com/_k7F3MIx6j_I/TCJUPimAKAI/AAAAAAAAAJQ/cgSJLunT5Y8/s640/bf.jpg" width="640" /&gt;&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/810103497999497955-6930519258259737487?l=matt.tlf.jp' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://matt.tlf.jp/feeds/6930519258259737487/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://matt.tlf.jp/2010/06/brain-fuck.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/6930519258259737487?v=2'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/6930519258259737487?v=2'/><link rel='alternate' type='text/html' href='http://matt.tlf.jp/2010/06/brain-fuck.html' title='第一隻 Brain Fuck 程式'/><author><name>Matthew Huang</name><uri>http://www.blogger.com/profile/10773062842303886980</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_k7F3MIx6j_I/RfUsxtiTHYI/AAAAAAAAAA8/Bi9Qx5Nv0lY/s320/jhhead01.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_k7F3MIx6j_I/TCJUPimAKAI/AAAAAAAAAJQ/cgSJLunT5Y8/s72-c/bf.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry gd:etag='W/&quot;DUUMRHwyeSp7ImA9WxFbFk0.&quot;'><id>tag:blogger.com,1999:blog-810103497999497955.post-2110915163295097128</id><published>2010-06-23T02:07:00.000-07:00</published><updated>2010-07-08T09:41:25.291-07:00</updated><app:edited xmlns:app='http://www.w3.org/2007/app'>2010-07-08T09:41:25.291-07:00</app:edited><category scheme='http://www.blogger.com/atom/ns#' term='EFI'/><category scheme='http://www.blogger.com/atom/ns#' term='工作'/><category scheme='http://www.blogger.com/atom/ns#' term='筆記'/><title>EFI Image 初探</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_k7F3MIx6j_I/TCHGS2f6jjI/AAAAAAAAAJI/we6K52tjX04/s1600/imagetype.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_k7F3MIx6j_I/TCHGS2f6jjI/AAAAAAAAAJI/we6K52tjX04/s320/imagetype.png" /&gt;&lt;/a&gt;&lt;/div&gt;左邊就是 EFI Image 分類和依存關係表，spec 上有，可是很多人選擇跳過，這邊就自己了解，獻一下醜。&lt;br /&gt;
&lt;br /&gt;
Image 分兩大類：&lt;i style="background-color: #d5a6bd;"&gt;&lt;b&gt;application&lt;/b&gt;&lt;/i&gt; 和 &lt;i style="background-color: #d5a6bd;"&gt;&lt;b&gt;driver&lt;/b&gt;&lt;/i&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;
Application 就沒什麼懸念，只要 return 個值或是去呼叫&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&lt;pre class="brush: cpp;gutter: false"&gt;BS-&amp;gt;Exit()&lt;/pre&gt;即自動 unload。 Application 中的異類是&amp;nbsp; OS Loader，它的運作機制比較奇特，不 return 也不 exit，它會去叫&lt;br /&gt;
&lt;pre class="brush: cpp;gutter: false"&gt;gBS-&amp;gt;ExitBootServices()&lt;/pre&gt;將控制權從 EFI 轉到 OS，從此 EFI 任務即算完成，接下來 EFI 就從事潛伏等待 OS 呼叫的功能。不過基本上它們兩個執行完後會從記憶體中載出。&lt;br /&gt;
&lt;br /&gt;
Driver 大體上分為 &lt;i&gt;&lt;b&gt;&lt;span style="background-color: #d5a6bd;"&gt;Non Driver-Model Driver&lt;/span&gt; &lt;/b&gt;&lt;/i&gt;和 &lt;i style="background-color: #d5a6bd;"&gt;&lt;b&gt;Driver-Model Driver&lt;/b&gt;&lt;/i&gt; 兩種。如果就工作階段的不同，分為 Boot Service Driver 和 Runtime Driver 兩種，這兩者的差異請自己看 spec，最大的差別就是存活期限。&lt;br /&gt;
&lt;br /&gt;
Driver 和 Application 有個最大的差異，就是 Application 只要回傳 EFI_SUCCESS 就能 unload，而 Driver 剛好相反，後面會有利用這種特性的 Driver。&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #ea9999;"&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Non Driver-Model Driver 以下介紹：&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b style="background-color: #9fc5e8;"&gt;Service Driver:&lt;/b&gt; 故名思義，提供服務 (一個或以上的 protocol 或是 handle)，實作完回傳 EFI_SUCCESS 常駐進記憶體等待呼叫。&lt;br /&gt;
&lt;br /&gt;
&lt;b style="background-color: #9fc5e8;"&gt;Initializing Driver:&lt;/b&gt; 它不出 protocol 也不出 handle，單純做初始化動作，做完故意 return Error Code 強迫自己退出記憶體。&lt;br /&gt;
&lt;br /&gt;
&lt;b style="background-color: #9fc5e8;"&gt;Root Bridge Driver:&lt;/b&gt; 這類型的 driver 專門建立實體 controller handle，每個 controller handle 又有包 Device Path Protocol，Chipset 產生的 root bus I/O 硬體抽象化的 protocol 也是包在這 driver 裡面。較常見的為 PCI_ROOT_BRIDGE_IO_PROTOCOL。&lt;br /&gt;
&lt;br /&gt;
&lt;b style="background-color: #9fc5e8;"&gt;EFI 1.02 Driver:&lt;/b&gt;&amp;nbsp; 其餘非 Driver-Model Driver 的統稱 EFI 1.02 Driver。這類型 Driver 和 Driver-Model Driver 最大的不同處，就是&lt;span style="background-color: #b6d7a8;"&gt;在它 Entry Point 直接就做 Start 了。這種行為代表著它一載入，所有硬體所有 protocol 都必須處理好，挫著等它下手做另外的事，沒有延後呼叫的可能性&lt;/span&gt;。&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="background-color: #ea9999;"&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Driver-Model Driver 以下介紹：&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b style="background-color: #9fc5e8;"&gt;EFI Driver-Model Driver:&lt;/b&gt; 任何遵循 EFI 1.10 spec 製作的 driver 都是 Driver-Model Driver。它和上述 Non Driver-Model Driver 最決定性的差別，&lt;span style="background-color: #b6d7a8;"&gt;就是在它的進入點，絕不會去碰硬體或是produce 跟硬體有關的任何服務&lt;/span&gt;。它會去包一個 Driver Binding Protocol，在進入點只做 Support、Start、Stop 這三種動作，而不像 Non Driver-Model Driver 一進入就直接 Start。這樣有個好處，可以等到條件符合再執行。&lt;br /&gt;
&lt;br /&gt;
&lt;b style="background-color: #9fc5e8;"&gt;Device Driver:&lt;/b&gt; 這類型的 driver 就是藉由 Driver Binding Protocol produce 一個或以上的&amp;nbsp; driver handle (或 driver image handle) 進 handle database。它的特性是在 &lt;br /&gt;
&lt;pre class="brush: cpp;gutter: false"&gt;EFI_DRIVER_BINDING_PROTOCOL.Start ()&lt;/pre&gt;呼叫的時候，不會去生成 child handle，只會在目前系統裡有的 controller handle 上裝 I/O protocol。&lt;br /&gt;
&lt;br /&gt;
&lt;b style="background-color: #9fc5e8;"&gt;Bus Driver:&lt;/b&gt; 它和 Device Driver 行為模式一樣，兩者差別只在 &lt;br /&gt;
&lt;pre class="brush: cpp;gutter: false"&gt;EFI_DRIVER_BINDING_PROTOCOL.Start () &lt;/pre&gt;呼叫的時候，它會生成 child handle 然後把 I/O protocol 附加在這些新創的 handle 上面。&lt;br /&gt;
&lt;br /&gt;
&lt;b style="background-color: #9fc5e8;"&gt;Hybrid Driver:&lt;/b&gt; 和上述兩者行為模式一模一樣，一樣是在 &lt;br /&gt;
&lt;pre class="brush: cpp;gutter: false"&gt;EFI_DRIVER_BINDING_PROTOCOL.Start ()&lt;/pre&gt;呼叫的時候，它不但會生成 child handle，同時會把 I/O protocol 裝在 child handle 和既有的 handle 上。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/810103497999497955-2110915163295097128?l=matt.tlf.jp' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://matt.tlf.jp/feeds/2110915163295097128/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://matt.tlf.jp/2010/06/efi-image.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/2110915163295097128?v=2'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/2110915163295097128?v=2'/><link rel='alternate' type='text/html' href='http://matt.tlf.jp/2010/06/efi-image.html' title='EFI Image 初探'/><author><name>Matthew Huang</name><uri>http://www.blogger.com/profile/10773062842303886980</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_k7F3MIx6j_I/RfUsxtiTHYI/AAAAAAAAAA8/Bi9Qx5Nv0lY/s320/jhhead01.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_k7F3MIx6j_I/TCHGS2f6jjI/AAAAAAAAAJI/we6K52tjX04/s72-c/imagetype.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry gd:etag='W/&quot;DEAHQ386eyp7ImA9WxFbFk0.&quot;'><id>tag:blogger.com,1999:blog-810103497999497955.post-2013500000245177155</id><published>2010-06-22T06:44:00.000-07:00</published><updated>2010-07-08T09:32:12.113-07:00</updated><app:edited xmlns:app='http://www.w3.org/2007/app'>2010-07-08T09:32:12.113-07:00</app:edited><category scheme='http://www.blogger.com/atom/ns#' term='心情'/><title>亂寫</title><content type='html'>今天聽到前輩在詮述問題，句句到位，很是佩服。&lt;br /&gt;
&lt;br /&gt;
一個門檻思考了半天，看了好久的 spec，無法理解。一句話直接中的， 功力從言談就能得知，想必經驗亦是十分豐富。&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/810103497999497955-2013500000245177155?l=matt.tlf.jp' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://matt.tlf.jp/feeds/2013500000245177155/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://matt.tlf.jp/2010/06/blog-post.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/2013500000245177155?v=2'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/2013500000245177155?v=2'/><link rel='alternate' type='text/html' href='http://matt.tlf.jp/2010/06/blog-post.html' title='亂寫'/><author><name>Matthew Huang</name><uri>http://www.blogger.com/profile/10773062842303886980</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_k7F3MIx6j_I/RfUsxtiTHYI/AAAAAAAAAA8/Bi9Qx5Nv0lY/s320/jhhead01.JPG'/></author><thr:total>0</thr:total></entry><entry gd:etag='W/&quot;DEAFQHo6cCp7ImA9WxFbFk0.&quot;'><id>tag:blogger.com,1999:blog-810103497999497955.post-1229068488360396249</id><published>2010-06-21T20:48:00.000-07:00</published><updated>2010-07-08T09:31:51.418-07:00</updated><app:edited xmlns:app='http://www.w3.org/2007/app'>2010-07-08T09:31:51.418-07:00</app:edited><category scheme='http://www.blogger.com/atom/ns#' term='EFI'/><category scheme='http://www.blogger.com/atom/ns#' term='工作'/><category scheme='http://www.blogger.com/atom/ns#' term='筆記'/><title>EFI 基礎知識</title><content type='html'>這邊看情況再回來修改，主要是目前自己學的也不是很熟悉，只把確定的知識拉出來喇迪賽。&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-large;"&gt;&lt;b&gt;幾&lt;/b&gt;&lt;/span&gt;個重要的 EFI object type:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;EFI System Table&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Memory&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Handles&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Images&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Events&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;一般在寫 EFI driver or app，應該最常用到就是 System Table (ST)。裡面有太多的資料結構可供使用，基本可謂之 EFI 的脊骨。&lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;SystemTable-&amp;gt;BootServices&lt;br /&gt;
SystemTable-&amp;gt;RuntimeServices&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
這個常寫 EFI driver (app) 應該很熟著用了，反正基礎思想就是以 code 佐 spec 慢慢去試。&lt;br /&gt;
再來容易讓別人混淆的就是 Handle database、Handle、Protocol 和 Driver 的相互關係。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: x-large;"&gt;H&lt;/span&gt;&lt;/b&gt;andle database 故名思義，不多說；Handle 可看成&amp;nbsp; protocol 的 repository，它本身沒什麼屬性，性質也是看存放的 protocol 而訂。這段不廢話，多做些引用 handle 和 protocol 的練習自然就懂了。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: x-large;"&gt;D&lt;/span&gt;&lt;/b&gt;river 和 Protocol 的關係也是使初接觸的人難以理解。EFI Driver 就是擁有一個或多個函數的 executable EFI image，Protocol 就是 Driver 的函數指標。&lt;br /&gt;
&lt;br /&gt;
所以常常看到 spec 裡面什麼&lt;i&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="color: #741b47;"&gt;&lt;i&gt;&lt;b&gt; "某某 driver consumes protocol 同時又 produces protocol" &lt;/b&gt;&lt;/i&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="color: #741b47;"&gt;&lt;br /&gt;
&lt;/div&gt;之類的，就不要懷疑了，函數互相調用而已。 單個 protocol 要發佈成 global 都得有個 GUID 識別。其實上面那句有點語法問題，基本上不需要 global 的 function 就不要做成 protocol 了…反正喇喇賽。&lt;br /&gt;
&lt;br /&gt;
下面貼個 protocol interface：&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp;gutter: false;"&gt;#define EFI_COMPONENT_NAME_PROTOCOL_GUID \ 
  { 0x107a772c,0xd5e1,0x11d4,\
    0x9a,0x46,0x0,0x90,0x27,0x3f,0xc1,0x4d } //GUID

typedef struct _EFI_COMPONENT_NAME_PROTOCOL { 
  EFI_COMPONENT_NAME_GET_DRIVER_NAME       GetDriverName; 
  EFI_COMPONENT_NAME_GET_CONTROLLER_NAME   GetControllerName; 
  CHAR8                                    *SupportedLanguages; 
} EFI_COMPONENT_NAME_PROTOCOL;&lt;/pre&gt;&lt;br /&gt;
一個 GUID，兩個 function pointer，一個 string，這個 protocol 型體就長這樣，其它的也就差不多，使用頻繁自然會懂。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: x-large;"&gt;E&lt;/span&gt;&lt;/b&gt;FI 下的 Image，無論是 application 還是 driver，都擁有 &lt;i style="background-color: #93c47d;"&gt;&lt;b&gt;PE / COFF header&lt;/b&gt;&lt;/i&gt; 描述，Microsoft Windows 和 Unix 下皆可分析其結構，具體情況 wiki 一下，不贄述。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: x-large;"&gt;E&lt;/span&gt;&lt;/b&gt;FI 接觸現在兩個多月，感覺就是個 protocol 和 driver 的世界，這部份搞得清楚來，以後會比較好作事，先寫到這邊，未來有想法再補充。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/810103497999497955-1229068488360396249?l=matt.tlf.jp' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://matt.tlf.jp/feeds/1229068488360396249/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://matt.tlf.jp/2010/06/efi.html#comment-form' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/1229068488360396249?v=2'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/1229068488360396249?v=2'/><link rel='alternate' type='text/html' href='http://matt.tlf.jp/2010/06/efi.html' title='EFI 基礎知識'/><author><name>Matthew Huang</name><uri>http://www.blogger.com/profile/10773062842303886980</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_k7F3MIx6j_I/RfUsxtiTHYI/AAAAAAAAAA8/Bi9Qx5Nv0lY/s320/jhhead01.JPG'/></author><thr:total>2</thr:total></entry><entry gd:etag='W/&quot;DEEMSHo5fyp7ImA9WxFbFk0.&quot;'><id>tag:blogger.com,1999:blog-810103497999497955.post-8320733065960635223</id><published>2010-06-20T12:10:00.000-07:00</published><updated>2010-07-08T09:31:29.427-07:00</updated><app:edited xmlns:app='http://www.w3.org/2007/app'>2010-07-08T09:31:29.427-07:00</app:edited><category scheme='http://www.blogger.com/atom/ns#' term='EFI'/><category scheme='http://www.blogger.com/atom/ns#' term='工作'/><category scheme='http://www.blogger.com/atom/ns#' term='筆記'/><title>EFI File System</title><content type='html'>&lt;pre class="brush: cpp;gutter: false"&gt;do {
  Status = FileRoot-&amp;gt;Read (
    FileRoot,
    &amp;amp;FileInfoSize,
    FileInfo
  );
  if (Status == EFI_BUFFER_TOO_SMALL) {
    FreePool (FileInfo);
    FileInfo = AllocateZeroPool (FileInfoSize);
  }
} while (FileInfoSize != 0);&lt;/pre&gt;&lt;br /&gt;
比較需要注意的地方就是只有 Read 動作才能讓 FileRoot 往下移位，GetInfo 沒辦法。Spec 是有講，不過很輕鬆的帶過了 (它輕鬆，累工程師)。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp;gutter: false"&gt;Status = FileRoot-&amp;gt;Open (
  FileRoot,
  &amp;amp;FileCreated,
  FileName,
  (EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ),
  Attribute
);&lt;/pre&gt;&lt;br /&gt;
建檔的時候比較麻煩就是這個，單弄個 EFI_FILE_MODE_CREATE 上到某些機器會爆炸，具體情況目前還不知道，未來了解了再過來修改文章。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp;gutter: false"&gt;CopyMem (FileContentMerge, FileContentTemp1, (UINTN)FileInfo1-&amp;gt;Size);
CopyMem (
  (CHAR16*)FileContentMerge + ((UINTN)FileInfo1-&amp;gt;Size / sizeof (CHAR16)),
  FileContentTemp2,
  (UINTN)FileInfo2-&amp;gt;Size
  );&lt;/pre&gt;&lt;br /&gt;
Merge 的時候用 CopyMem 其實都行，了解自己的資料結構最重要，要不然自爆真的就自找的。還是比較推崇強制 typecast 然後再具體解 bug… 比較差的辦法啦，不過出來的東西至少有錯還是有根據反追…&lt;br /&gt;
&lt;br /&gt;
追加一點，如果要把整個 file structure 包含 attribute、filename、content 諸元都截出來，&lt;span style="background-color: #b6d7a8;"&gt;直接隨 Read 隨 Allocate 就行&lt;/span&gt;。但如果只想截 content，&lt;span style="background-color: #b6d7a8;"&gt;要先用 GetInfo 把 FileSize 抓出來&lt;/span&gt;，用那個 Size 去 Allocate 及截取。最重要的差異點應該在這。&lt;br /&gt;
&lt;br /&gt;
※ 追加，一般來說用 LocateProtocol 如 code 所示：&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp;gutter: false"&gt;EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystemProtocol;

Status = BS-&amp;gt;LocateProtocol (       
  &amp;amp;gEfiSimpleFileSystemProtocolGuid,
  NULL,                             
  &amp;amp;FileSystemProtocol                
  );&lt;/pre&gt;&lt;br /&gt;
這樣是只會搜到 &lt;span style="background-color: #f1c232;"&gt;&lt;b&gt;"第一個 FileSystem Protocol (FS0)&lt;/b&gt;"&lt;/span&gt; ，更甚者是沒有，非常賭運氣的作法。&lt;br /&gt;
&lt;br /&gt;
如果比較喜歡指定的 Storage，剛剛聽說了一個方法：&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: cpp;gutter: false"&gt;BS-&amp;gt;HandleProtocol (
  ImageHandle,
  &amp;amp;gEfiLoadedImageProtocolGuid,
  &amp;amp;LoadImage
  );
DeviceHandle = LoadImage-&amp;gt;DeviceHandle;&lt;/pre&gt;&lt;br /&gt;
這樣就會抓到 Executable Image 所在的 storage device，也是比較&amp;nbsp; bulletprove 的做法。&lt;br /&gt;
&lt;br /&gt;
還聽說有人做出在 Shell 下面先找到 current command root，對那個 root 單獨運作的，這就不知道方法了，還望各位大德賜教。&lt;br /&gt;
&lt;br /&gt;
記得 FreePool，記得 Close File，其實這個還滿簡單的。&lt;br /&gt;
&lt;br /&gt;
目前還有一些東西沒解決，例如 SetPosition 還不知道怎麼樣搞才能進到根目錄的各資料夾下面做掃描動作，不過相信時間演進，技術會更進步一些。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/810103497999497955-8320733065960635223?l=matt.tlf.jp' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://matt.tlf.jp/feeds/8320733065960635223/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://matt.tlf.jp/2010/06/efi-file-system.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/8320733065960635223?v=2'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/8320733065960635223?v=2'/><link rel='alternate' type='text/html' href='http://matt.tlf.jp/2010/06/efi-file-system.html' title='EFI File System'/><author><name>Matthew Huang</name><uri>http://www.blogger.com/profile/10773062842303886980</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_k7F3MIx6j_I/RfUsxtiTHYI/AAAAAAAAAA8/Bi9Qx5Nv0lY/s320/jhhead01.JPG'/></author><thr:total>0</thr:total></entry><entry gd:etag='W/&quot;CkAAR3g6eip7ImA9WxFUEEs.&quot;'><id>tag:blogger.com,1999:blog-810103497999497955.post-788225875155390565</id><published>2010-06-20T11:34:00.000-07:00</published><updated>2010-06-20T12:05:46.612-07:00</updated><app:edited xmlns:app='http://www.w3.org/2007/app'>2010-06-20T12:05:46.612-07:00</app:edited><category scheme='http://www.blogger.com/atom/ns#' term='閒聊'/><category scheme='http://www.blogger.com/atom/ns#' term='心情'/><title>Blog 開通</title><content type='html'>先留個底，以後工作上有什麼狗屁知識就貼這邊了&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/810103497999497955-788225875155390565?l=matt.tlf.jp' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://matt.tlf.jp/feeds/788225875155390565/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://matt.tlf.jp/2010/06/blog.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/788225875155390565?v=2'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/810103497999497955/posts/default/788225875155390565?v=2'/><link rel='alternate' type='text/html' href='http://matt.tlf.jp/2010/06/blog.html' title='Blog 開通'/><author><name>Matthew Huang</name><uri>http://www.blogger.com/profile/10773062842303886980</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_k7F3MIx6j_I/RfUsxtiTHYI/AAAAAAAAAA8/Bi9Qx5Nv0lY/s320/jhhead01.JPG'/></author><thr:total>0</thr:total></entry></feed>