<?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-8646454779089790212</id><updated>2012-02-13T01:21:30.832-08:00</updated><category term='install'/><category term='serial'/><category term='arm'/><category term='setup'/><category term='shadow'/><category term='cocoa design patterns'/><category term='android'/><category term='emacs'/><category term='commands'/><category term='java'/><category term='git'/><category term='new survey'/><category term='linux programming'/><category term='qemu'/><category term='MathJax'/><category term='environment'/><category term='hacking'/><category term='algorithm'/><category term='Latex'/><category term='iOS programming'/><category term='OpenGL'/><title type='text'>追求新境界</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>46</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-8012662797737923287</id><published>2012-02-07T03:14:00.000-08:00</published><updated>2012-02-07T14:59:39.658-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shadow'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenGL'/><title type='text'>Shadow Matrix 筆記</title><content type='html'>尋找如何做出 Shadow matrix 的過程中，發現 &lt;a href="http://www.csie.ntu.edu.tw/~r89004/hive/shadow/page_1.html" target="_blank"&gt;HOTBALL'S HIVE&lt;/a&gt; 介紹得很好。但是&lt;br /&gt;有些推導過程，中間的步驟很簡明，對於新手的我來說，還是得拿紙筆來演練，&lt;br /&gt;才能順利接上，在此作個筆記。為了一致性，這裡的&lt;b&gt;圖&lt;/b&gt;與&lt;b&gt;符號標示&lt;/b&gt;，也是沿用該網頁。&lt;br /&gt;&lt;br /&gt;目的：給定光源，在已知平面上 （以 normal vector \( \vec P \) 表示）找出平面以外某一點 \( \vec V \)，&lt;br /&gt;在平面上的投影點，然後導出其 Matrix Operation。&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-6ya13He6XHw/TzELNaUSujI/AAAAAAAAATM/3h1Ic0zz1Vk/s1600/proj.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-6ya13He6XHw/TzELNaUSujI/AAAAAAAAATM/3h1Ic0zz1Vk/s1600/proj.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;如圖，沿著射線，存在ㄧ k 值，使得 \( \vec V \) + k\( \vec L \) 為平面上的交點：&lt;br /&gt;\[    (\vec V + k \vec L) \cdot \vec P = 0\]\[   k = -\frac{\vec V \cdot \vec P}{\vec L \cdot \vec P}\]所以投影點為：\[   \begin{align}      \vec V + k \vec L &amp;amp;= \vec V - \frac{\vec V \cdot \vec P}{\vec L \cdot \vec P} \vec L \cr                        &amp;amp;= \frac{\vec V (\vec L \cdot \vec P) - (\vec V \cdot \vec P) \vec L}{\vec L \cdot \vec P} &amp;amp;(\ddagger)   \end{align}\]令\[   \begin{align}      \vec L &amp;amp;= \langle L_x,L_y,L_z,0 \rangle \cr      \vec V &amp;amp;= \langle V_x,V_y,V_z,1 \rangle \cr      \vec P &amp;amp;= \langle a,b,c,d \rangle   \end{align}\]對於 homogeneous coordinate \( \langle x,y,z,w \rangle \) 而言，w 是分母之意，亦即對應的 3D coordinate 為 \( \langle x/w, y/w, z/w \rangle \)，也就是 \( \vec L \cdot \vec P \) 在 homogeneous coordinate 表示下恰為 \( w \) 之值。展開 \((\ddagger)\) 式子的分子為：\[   \langle V_x,V_y,V_z,1 \rangle (aL_x + bL_y + cL_z) - (aV_x + bV_y + cV_z + d) \langle L_x,L_y,L_z,0 \rangle\]其中 \(x\) 分量為：\[   V_x(bL_y + cL_z) - V_y(bL_x) - V_z(cL_x) - dL_x\]同法可得 \(y,z\) 分量，整理得到 shadow matrix:\[   \begin{bmatrix}      bL_y + cL_z &amp;amp; -bL_x &amp;amp; -cL_x &amp;amp; -dL_x \cr      -aL_y &amp;amp; aL_x + cL_z &amp;amp; -cL_y &amp;amp; -dL_y \cr      -aL_z &amp;amp; -bL_z &amp;amp; aL_x + bL_y &amp;amp; -dL_z \cr      0 &amp;amp; 0 &amp;amp; 0 &amp;amp; aL_x + bL_y + cL_z   \end{bmatrix}\]後記： \(\LaTeX\) 打了會上癮！&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-8012662797737923287?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/8012662797737923287/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2012/02/shadow-matrix.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/8012662797737923287'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/8012662797737923287'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2012/02/shadow-matrix.html' title='Shadow Matrix 筆記'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-6ya13He6XHw/TzELNaUSujI/AAAAAAAAATM/3h1Ic0zz1Vk/s72-c/proj.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-4090340905918938356</id><published>2012-02-07T01:29:00.001-08:00</published><updated>2012-02-07T16:07:49.426-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Latex'/><category scheme='http://www.blogger.com/atom/ns#' term='MathJax'/><title type='text'>MathJax Test</title><content type='html'>This is a test of using MathJax in Blogger &amp;nbsp; Note that enclosing math in single $'s does not work in the default setting for MathJax. &amp;nbsp;However, you may use "\(\backslash(\)" and "\(\backslash)\)" for inline math and double dollar signs or "\(\backslash[\)" and "\(\backslash]\)" for displayed math. &amp;nbsp;Examples for inline is: &amp;nbsp;\( (y+\sqrt z)^{-1} \) and &amp;nbsp;\( \sin^2 x^2 \). &amp;nbsp;And, a displayed equation is: $$\frac 2 3$$&lt;br /&gt;Another displayed equation is here:&lt;br /&gt;\[&lt;br /&gt;\forall x \exists y (x\le y \land y\le x \leftrightarrow x=y) .&lt;br /&gt;\]&lt;br /&gt;\[&lt;br /&gt;\vec \Phi ( \vec r)  = -\frac{G M_1}{| \vec{r}-\vec r_1 |}\]&lt;br /&gt;&lt;br /&gt;To setup the MathJax capability, I added the following line to the HTML code, after the &amp;lt;head&amp;gt; command (as a single line, no line break):&lt;br /&gt;&lt;br /&gt;&amp;lt;script src='http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML' type='text/javascript'/&amp;gt;&lt;br /&gt;&lt;br /&gt;You can find more information from the MathJax website about this at&amp;nbsp;&lt;a href="http://www.mathjax.org/docs/1.1/start.html"&gt;http://www.mathjax.org/docs/1.1/start.html&lt;/a&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/8646454779089790212-4090340905918938356?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/4090340905918938356/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2012/02/mathjax-test.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/4090340905918938356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/4090340905918938356'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2012/02/mathjax-test.html' title='MathJax Test'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-5305779909193105566</id><published>2011-12-20T07:07:00.001-08:00</published><updated>2012-02-13T01:21:30.851-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iOS programming'/><title type='text'>Gestures and View Transform</title><content type='html'>To use the UIGestureRecognizer for pinch and rotate gesture,&lt;br /&gt;we first create it:&lt;br /&gt;&lt;code&gt;  // Create a rotation gesture &lt;br /&gt;  UIRotationGestureRecognizer *rotate = [[UIRotationGestureRecognizer alloc] &lt;br /&gt;  initWithTarget:self &lt;br /&gt;  action:@selector(handleRotateEvent:)]; &lt;br /&gt;  [rotate setDelegate:self]; &lt;br /&gt;  [redBox addGestureRecognizer:rotate]; &lt;br /&gt;&lt;/code&gt;Then write the &lt;b&gt;handleRotateEvent:&lt;/b&gt; method:&lt;code&gt;// Called when the rotate gesture is recognized &lt;br /&gt;- (void)handleRotateEvent:(UIRotationGestureRecognizer*)rotateGesture &lt;br /&gt;{ &lt;br /&gt;    // If our gesture ended, reset the box &lt;br /&gt;    if([rotateGesture state] == UIGestureRecognizerStateEnded) { &lt;br /&gt;    [self resetBox]; &lt;br /&gt;  } &lt;br /&gt;  else { &lt;br /&gt;    // Store the value of our rotation gesture, then &lt;br /&gt;    // call our central update box tranform method &lt;br /&gt;    // Update box transform will also apply any transforms by the pinch gesture &lt;br /&gt;    &lt;span style="color: purple;"&gt;rotation&lt;/span&gt; = rotateGesture.rotation; &lt;br /&gt;    [self updateBoxTransform]; &lt;br /&gt;  } &lt;br /&gt;} &lt;br /&gt;&lt;/code&gt;In the &lt;b&gt;updateBoxTransform&lt;/b&gt;, we &lt;b&gt;directly&lt;/b&gt; use the rotation value to view’s transform:&lt;code&gt;- (void)updateBoxTransform &lt;br /&gt;{ &lt;br /&gt;    // Create a new transform based on the scale (scale determined by pinch gesture) &lt;br /&gt;    CGAffineTransform transform = CGAffineTransformMakeScale(scale, scale); &lt;br /&gt; &lt;br /&gt;    // Rotate the transform based on the rotation gesture value &lt;br /&gt;    transform = CGAffineTransformRotate(transform, rotation);   &lt;br /&gt;    &lt;span style="color: purple;"&gt;//-- contineously using the gesture's rotation &lt;/span&gt;&lt;br /&gt;    // Apply the transform to our red box &lt;br /&gt;    redBox.transform = transform; &lt;br /&gt;} &lt;br /&gt;&lt;/code&gt;&lt;span style="color: blue;"&gt;Here we initialize a transform with &lt;b&gt;Identity&lt;/b&gt; and &lt;b&gt;scale&lt;/b&gt;, each time.&lt;/span&gt;&lt;br /&gt;The following paragraph uses another approach for the rotation:&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&amp;nbsp;&amp;nbsp;&lt;code&gt;- (void)handleRotateEvent:(UIRotationGestureRecognizer *)gestureRecognizer &lt;br /&gt;{ &lt;br /&gt;  [self adjustAnchorPointForGestureRecognizer:gestureRecognizer]; &lt;br /&gt;  if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || &lt;br /&gt;      [gestureRecognizer state] == UIGestureRecognizerStateChanged) { &lt;br /&gt;    [gestureRecognizer view].transform = &lt;br /&gt;      CGAffineTransformRotate( [ [gestureRecognizer view] transform],                                [gestureRecognize rotation] ); &lt;br /&gt;    [gestureRecognizer setRotation:0]; &lt;span style="color: purple;"&gt;//-- reset gesture's rotation  &lt;/span&gt;&lt;br /&gt;                                 } &lt;br /&gt;} &lt;br /&gt;&lt;/code&gt;Since the source of transform is from the view object, &lt;span style="color: blue;"&gt;we have to [gestureRecognizer setRotation:0]; such that we provide a fresh rotation quantum and add to the view’s transform&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-5305779909193105566?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/5305779909193105566/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2011/12/gestures-and-view-transform.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/5305779909193105566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/5305779909193105566'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2011/12/gestures-and-view-transform.html' title='Gestures and View Transform'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-5215741866947398009</id><published>2011-11-25T03:31:00.001-08:00</published><updated>2011-11-25T03:33:38.652-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iOS programming'/><category scheme='http://www.blogger.com/atom/ns#' term='cocoa design patterns'/><title type='text'>Discussions about using "Singleton" and "Archiving/Unarchiving"</title><content type='html'>&lt;p&gt;This is a pratical situation encountered --- We want a "Singleton" object which has the ability of "Archiving/Unarchiving", should we &lt;strong&gt;implement&lt;/strong&gt; these two design patterns together? There is &lt;a href="http://stackoverflow.com/questions/2981269/initwithcoder-works-but-init-seems-to-be-overwriting-my-objects-properties" target="_blank"&gt;a discussion in Stack Overflow&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;My thoughts : Maybe it is unecessary to implement them in the same class, as "wbyoung" said, two lines of code do the same work.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-5215741866947398009?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/5215741866947398009/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2011/11/discussions-about-using-and.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/5215741866947398009'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/5215741866947398009'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2011/11/discussions-about-using-and.html' title='Discussions about using &amp;quot;Singleton&amp;quot; and &amp;quot;Archiving/Unarchiving&amp;quot;'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-6050220341147309911</id><published>2011-08-08T20:32:00.001-07:00</published><updated>2011-11-25T03:34:37.910-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iOS programming'/><title type='text'>deleting trailing whitespace</title><content type='html'>&lt;p&gt;When using git to maintain versions of XCode4 projects,&amp;nbsp; often we need to "delete trailing whitespace" before we add or commit file to the git tree. While XCode4 leaves lots of line with trailing white spaces. How to remove them?&lt;/p&gt;&lt;p&gt;By Bash commands :&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: andale mono,times; color: #008000;"&gt;find -E . -type f -regex ".*\.(h|m|mm)" -print0 | xargs -0 sed -i -E "s/[[:space:]]*$//"&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: andale mono,times; color: #008000;"&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: andale mono,times; color: #008000;"&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808000;"&gt;&lt;strong&gt;&lt;span style="font-family: arial,helvetica,sans-serif;"&gt;Note: &lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: andale mono,times; color: #008000;"&gt;&lt;span style="font-family: arial,helvetica,sans-serif; color: #000000;"&gt;-E for find: Interpret pattern after -regex with &lt;strong&gt;Extended Regular Expression(ERE) syntax&lt;/strong&gt;,&amp;nbsp; should be placed before {&lt;em&gt;directory&lt;/em&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: andale mono,times; color: #008000;"&gt;".*\.(h|m|mm)"&lt;/span&gt;&lt;span style="font-family: andale mono,times; color: #008000;"&gt;&lt;span style="font-family: arial,helvetica,sans-serif; color: #000000;"&gt; : match file name with&amp;nbsp; .h, .m, .mm at the end, which is ERE syntax.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: andale mono,times; color: #008000;"&gt;&lt;span style="font-family: arial,helvetica,sans-serif; color: #000000;"&gt;-E for sed: Interpret pattern using ERE syntax, the [:sapce:] represents the Whitespace character set: [ \t\r\n\v\f]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: andale mono,times; color: #008000;"&gt;&lt;span style="font-family: arial,helvetica,sans-serif; color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: andale mono,times; color: #008000;"&gt;&lt;span style="font-family: arial,helvetica,sans-serif; color: #000000;"&gt;Thus, we can delete trailing white space with one command line in the&lt;strong&gt; project top directory&lt;/strong&gt; ! Simple and clear !&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-6050220341147309911?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/6050220341147309911/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2011/08/deleting-trailing-whitespace.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/6050220341147309911'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/6050220341147309911'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2011/08/deleting-trailing-whitespace.html' title='deleting trailing whitespace'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-4137486953681896451</id><published>2011-07-19T15:58:00.001-07:00</published><updated>2011-11-25T03:34:52.728-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iOS programming'/><title type='text'>The COSCUP 2011 iPhone program</title><content type='html'>&lt;p&gt;緣由: 今年 COSCUP，由於智慧型手機的普遍化，增添了 App 競賽。所以就來共襄盛舉一番。&lt;/p&gt;&lt;p&gt;6 月 20 日：看到 COSCUP 的公告，開始熱血沸騰...可是，我不會 Java 、剛學會 Objective-C，只會寫 Hello World；如果要選比較可能做得到的平台，好像 iPhone 比較接近一些些。所以開始研讀&amp;nbsp; Cocoa 。&lt;/p&gt;&lt;p&gt;7 月 9 日，可以用 COSCUP API 抓到資料，用 json framework 來 parsing，感覺很幸福！&lt;/p&gt;&lt;p&gt;7 月 10, 11 ... 15 日，頭髮一直掉.... 媽！我錯了！但是為了自我實現的一個目標，繼續奮戰。感謝家人，同事的默默支持，也感謝 COSCUP 工作人員的協助。&lt;/p&gt;&lt;p&gt;這是現在完成的三個畫面。&lt;/p&gt;&lt;p&gt;以時間來看&lt;/p&gt;&lt;p&gt;&lt;img src="https://lh6.googleusercontent.com/-TnL-wYvP1Kw/TjDIgfdwC2I/AAAAAAAAAOw/n5CVJy48wa0/s512/coscup-app-2.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;以議程的類型來看&lt;/p&gt;&lt;p&gt;&lt;img src="https://lh5.googleusercontent.com/-E2pD7QpFOa8/TjDVTjwqPtI/AAAAAAAAAPA/5Q7StbdFG8U/s512/coscup-app-4.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;這兩種觀看的模式，可用右上角的按鈕群來互相切換。&lt;/p&gt;&lt;p&gt;另外，贊助廠商的導覽，可以由畫面下方的 Sponsors tab 來選擇。&lt;/p&gt;&lt;p&gt;&lt;img src="https://lh4.googleusercontent.com/-NwdCIHDgyVg/TjDWaZDyWRI/AAAAAAAAAPM/5jcq6ukR2Ws/s512/coscup-app-1.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;因為這是一些資料的 parsing ，目的是使大家很快的找到需要的資訊，所以以極簡風格來完成使命。&lt;/p&gt;&lt;p&gt;第一次執行時，會從 COSCUP 網站下載資訊，之後就存在手機裡了，之後就從手機讀檔，需要 update 的話，左上角按鈕可以再從網站下載。&lt;/p&gt;&lt;p&gt;另外，有提供智慧型的語系選擇，例如，如果從 COSCUP 拿到了 Intel 廠商給的資訊，只有中文，那麼不論手機的語系設定如何，都會看到中文；那如果贊助廠商給的資訊有中、英文，那就會優先以手機的語系設定來顯示出贊助廠商的資訊。&lt;/p&gt;&lt;p&gt;這裡是下載的 QR Code&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;br /&gt; &lt;img src="http://qrcode.kaywa.com/img.php?s=5&amp;amp;d=http%3A%2F%2Fitunes.apple.com%2Ftw%2Fapp%2Fcoscup%2Fid453464232%3Fmt%3D8" alt="qrcode" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;程式碼放在 GitHub&lt;/p&gt;&lt;p&gt;git clone: git@github.com:tomjpsun/Coscup.git&lt;/p&gt;&lt;p&gt;就這樣啦！期待大家在8/20 見面啦！&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-4137486953681896451?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/4137486953681896451/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2011/07/coscup-2011-iphone-program.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/4137486953681896451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/4137486953681896451'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2011/07/coscup-2011-iphone-program.html' title='The COSCUP 2011 iPhone program'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh6.googleusercontent.com/-TnL-wYvP1Kw/TjDIgfdwC2I/AAAAAAAAAOw/n5CVJy48wa0/s72-c/coscup-app-2.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-4558614570357415113</id><published>2011-04-27T21:17:00.000-07:00</published><updated>2011-04-27T21:17:06.956-07:00</updated><title type='text'>Cntrolling tty 解決方法</title><content type='html'>http://hi.baidu.com/kroodylove/blog/item/e7f3cddd74b001df8d102984.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-4558614570357415113?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/4558614570357415113/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2011/04/cntrolling-tty.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/4558614570357415113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/4558614570357415113'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2011/04/cntrolling-tty.html' title='Cntrolling tty 解決方法'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-6640460428282975258</id><published>2011-04-12T00:23:00.001-07:00</published><updated>2011-11-25T03:35:19.693-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithm'/><title type='text'>greedy straegy abstract</title><content type='html'>&lt;div&gt;為了解一個問題，把 [ &lt;a href="http://mitpress.mit.edu/algorithms/" target="_blank"&gt;Introduction to Algorithms&lt;/a&gt; ] 抓來亂翻了一下，&lt;br /&gt;再配合交大 [ &lt;a href="http://www.cs.nctu.edu.tw/%7Etsaich/2011AlgoSpring/" target="_blank"&gt;譚老師的講義&lt;/a&gt; ]，把 greedy algorithm 部份研讀了一下，&lt;br /&gt;大概領悟力不夠，還是不能融會貫通，只好把重點節錄起來，慢慢消化：&lt;br /&gt;&lt;br /&gt;以下 Greedy Algorithm 以 Greedy 簡稱之&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dynamic Algorithm 以 Dynamic 簡稱之&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Optimal Solution 以 Opt. 簡稱之&lt;br /&gt;&lt;br /&gt;Greedy&amp;nbsp; 簡單說就是：經由一連串的選擇，找出全局最佳解，每次&lt;br /&gt;選擇時，是找出當時的最佳解，這種 heuristic 的方法，就稱為 Greedy.&lt;br /&gt;&lt;br /&gt;Greedy 異於 Dynamic 的解法，不像 Dynamic 找出所有 subproblems 的解，再慢慢&lt;br /&gt;用 table 記下，累積到全局：而是先把問題分成一個 greedy choice + subproblem ，&lt;br /&gt;這個 greedy choice 是一個局部最佳解，並且用 recursive 方式繼續 下去解 subproblem。&lt;br /&gt;最後的結果，使得 Greedy 不一定得到 Opt.，但是很快，而且結果可以接近 Opt.&lt;br /&gt;&lt;br /&gt;很多時候，由於這種早期決定的性質，Greedy 無法找到 Opt.&lt;br /&gt;當然，如果能證明，這個 greedy choice 是全局 Opt. 的一環，那麼就可以確保，一系列&lt;br /&gt;的 greedy choice 可以找到全局 Opt.&lt;br /&gt;&lt;br /&gt;下面是從 [&lt;a href="http://en.wikipedia.org/wiki/Greedy_algorithm" target="_blank"&gt;Wiki&lt;/a&gt;] 節錄的，Greedy 的兩個重要成份：&lt;br /&gt;&lt;br /&gt;Greedy choice property &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; We can make whatever choice seems best at the moment and then solve &lt;br /&gt;the subproblems that arise later.&lt;span style="color: #006600;"&gt;&lt;strong&gt; The choice made by a greedy algorithm &lt;br /&gt;may &lt;/strong&gt;&lt;strong&gt;depend on choices made so far but not on future choices or all the &lt;br /&gt;solutions to the subproblem.&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt; &lt;span style="color: #000099;"&gt;It iteratively makes one greedy choice &lt;br /&gt;after another, reducing each given problem into a smaller one. &lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;span style="color: #660000;"&gt;&lt;strong&gt;In other words, a greedy algorithm never reconsiders its choices. &lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;This is the main difference from dynamic programming, which is exhaustive &lt;br /&gt;and is guaranteed to find the solution. &lt;br /&gt;&lt;strong&gt;&lt;span style="color: #006600;"&gt;After every stage&lt;/span&gt;,&lt;span style="color: #660000;"&gt; dynamic programming &lt;span style="color: #000099;"&gt;makes decisions based on all &lt;br /&gt;the decisions made in the previous stage&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;, and may reconsider the &lt;br /&gt;previous stage's algorithmic path to solution.&lt;br /&gt;&lt;br /&gt;Optimal substructure &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "A problem exhibits optimal substructure if an optimal solution&lt;br /&gt;&amp;nbsp;to the problem contains optimal solutions to the sub-problems."&lt;br /&gt;&lt;br /&gt;以下列出一些例子來討論：&lt;br /&gt;例一&amp;nbsp;&amp;nbsp; 0-1 knapsack problem : 假設有 n 種&lt;strong&gt;礦石&lt;/strong&gt;，以 1,2...n 代表這 n 種礦石，&lt;br /&gt;第 i 種重量是 w[i] ，價值是 v[i]，限定載重上限為 W 的情形下，&lt;br /&gt;怎樣拿會最有價值？&lt;br /&gt;&lt;br /&gt;例二&amp;nbsp;&amp;nbsp; fractional knapsack problem : 假設有 n 種&lt;strong&gt;礦石粉末&lt;/strong&gt;，以 1,2...n 代表這 n 種礦石，&lt;br /&gt;第 i 種重量是 w[i] ，價值是 v[i]，限定載重上限為 W 的情形下，&lt;br /&gt;怎樣拿會最有價值？&lt;br /&gt;&lt;br /&gt;這兩種問題，都有 Optimal substructure 的特性 ----- 假設最有價值的裝法 載重是 W，&lt;br /&gt;則裝入礦石 j 後，對於剩下的 n-1 種礦石 ( 就是 j 已拿光後 ) 最有價值的載重 &lt;br /&gt;剩下 W-W[j]&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;fractional knapsack problem 可以用 Greedy 找到 Opt. ：&lt;/strong&gt;&lt;br /&gt;因為當每次選擇 價值/重量 比最高的礦石粉 j 時，可以確定把 j 拿完，&lt;br /&gt;是最好地選擇。若 j 拿完還有多餘的載重量，就選擇 價值/重量 比&lt;br /&gt;次高的礦石粉，此時 所作的 greedy selection 就是符合 global Opt. 的選擇。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;0-1 knapsack problem 無法用 Greedy 找到 Opt. ：&lt;/strong&gt;&lt;br /&gt;反例 ：考慮三種礦石，都只有一個：&lt;br /&gt;&amp;nbsp;v[1]=60 ,&amp;nbsp; w[1]=10&lt;br /&gt;&amp;nbsp;v[2]=100, w[2]=20&lt;br /&gt;&amp;nbsp;v[3]=120, w[3]=30&lt;br /&gt;&amp;nbsp;upper weight W= 50&lt;br /&gt;&lt;br /&gt;1 的 價值/重量 比最高，選取 1 剩下可載重 40，但是選 1 不會得到 Opt.&lt;br /&gt;Opt. 是選 2+3, total value =220&lt;br /&gt;&lt;strong&gt;但是 0-1 knapsack problem 可以用 Dynamic 找到 Opt.&lt;/strong&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;另外，有漂亮的數學證明， 符合 matroid 結構的問題，可以用 greedy 得到 Opt.&lt;br /&gt;（ matroid 是比較深的主題，有空再來研究吧！）&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/8646454779089790212-6640460428282975258?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/6640460428282975258/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2011/04/greedy-straegy-abstract_12.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/6640460428282975258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/6640460428282975258'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2011/04/greedy-straegy-abstract_12.html' title='greedy straegy abstract'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-3428378731403166282</id><published>2011-03-28T08:44:00.001-07:00</published><updated>2011-03-28T08:46:25.988-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux programming'/><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>simple &amp; clean daemon code</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;This blog is original from here: [ &lt;a target='_blank' href='http://www.ucdot.org/article.pl?sid=03/12/12/0317219&amp;amp;mode=thread'&gt;uCdot&lt;/a&gt; ]&lt;br/&gt;&lt;br/&gt;Here the little trick is :&lt;br/&gt;Use option '-D' as a 'differentiate mark' of daemon process&lt;br/&gt;from the parent process.  &lt;br/&gt;   &lt;br/&gt;The second time it self exec(), means the daemon process&lt;br/&gt;starting with -D option, which make it goes to the 'else' block :&lt;br/&gt;&lt;br/&gt;It's a Clean and Simple example!&lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=a8b52747-2063-895d-9e8e-ebadaef40580' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-3428378731403166282?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/3428378731403166282/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2011/03/simple-clean-daemon-code.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/3428378731403166282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/3428378731403166282'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2011/03/simple-clean-daemon-code.html' title='simple &amp;amp; clean daemon code'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-3734910517220680574</id><published>2011-03-12T01:18:00.001-08:00</published><updated>2011-03-12T01:18:32.923-08:00</updated><title type='text'>uClinux 新手筆記</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;如果想要知道一些概念，這篇是很好的總整理：&lt;br/&gt;[ &lt;a target='_blank' href='http://www.linuxjournal.com/article/7221'&gt;uClinux for Linux Programmers&lt;/a&gt; ]&lt;br/&gt;&lt;br/&gt;大致上的摘要是這樣：&lt;br/&gt;  uClinux 給沒有 MMU 的 CPU 使用，因此不支援原來 &lt;br/&gt;  Linux 的 Virtual Memory (VM) 環境。&lt;br/&gt;&lt;br/&gt;  沒有 VM，process 不能於 run time 時期增加 process &lt;br/&gt;  address space，所以 brk/sbrk() 無法被實做，&lt;br/&gt;  也不能用 tmpfs，因為它依賴於 VM 的支援。&lt;br/&gt;&lt;br/&gt;  沒有 VM，每一支 uClinux app 都要在 run time 時由系統來作 relocation。&lt;br/&gt;  而且是 sequential &amp;amp;&amp;amp; contiguous. 的排在 file system 內，一次就得載入&lt;br/&gt;  整個程式 於連續的 physical memory 上，所以只能用 romfs。&lt;br/&gt;&lt;br/&gt;  傳統的 power of 2 memory allocation 機制在這裡會造成許多浪費&lt;br/&gt; （例如要 33k 會給 64k），所以可選其他的 memory allocation 機制&lt;br/&gt;  ，例如 page_alloc2 或 kmalloc2。&lt;br/&gt;  page_alloc2 以 4k 為單位分配 （例如要 33k 會給 36k）&lt;br/&gt;  kmalloc2 以 8k 為判斷，大於 8k 的需求從 free memory 的底部拿，&lt;br/&gt;  小於 8k 的從 free memory 的起始處拿。這樣的好處是減少由&lt;br/&gt;  短暫而多次的 allocation --- 如網路程式的 buffer --- 引起的碎片問題。&lt;br/&gt;&lt;br/&gt;  沒有 VM，對應用程式來說，就沒有 dynamic stack 可用，一旦程式超出&lt;br/&gt;  stack 範圍，會引發不可預期的結果。程式要自己知道需要多大的 stack，&lt;br/&gt;  在 compile time 就必須決定好。&lt;br/&gt;  heap 也不能使用 VM 機制，所以 uClinux 使用了 kernel free memory&lt;br/&gt;  當作一個大的 system memory pool.&lt;br/&gt;  &lt;br/&gt;  對於應用程式與程序來說，uClinux 沒有提供 fork()；只提供替代的 vfork()，&lt;br/&gt;  有別於 fork()，&lt;b&gt;使用 vfork() 會使得 parent process suspend 直到 &lt;br/&gt;  child process  結束 或 執行 exec() 為止&lt;/b&gt;。&lt;br/&gt;  fork() 發生後，parent &amp;amp; child process 有各自的資源 （address space 與 stack），&lt;br/&gt;  parent &amp;amp; child process 沒有任何共用的東西。&lt;br/&gt;  反觀 vfork() ，它會使得 child process 與 parent process 共用 stack。&lt;br/&gt;  因此 vfork() 後，parent process suspend 了，若此時 child process 從現在的 &lt;br/&gt;  stack frame 返回上層，則會影響到 parent  process stack --- &lt;br/&gt;  應用程式必須自行注意，確保不會發生這種情形！（心得：難怪&lt;br/&gt;  網路上有人建議 busybox API 加上 fork_and_exit()）！&lt;br/&gt;  另外，child process 也必須使用 _exit() 而不能用 exit() ，&lt;br/&gt;  原因也是因為 stack 共用。&lt;br/&gt;&lt;br/&gt;  沒有 VM，uClinux 的程式只能使用 flat executable format (bFLT)，&lt;br/&gt;  這有兩種型態：&lt;br/&gt;  一、code text &amp;amp; data 都是 relocatable&lt;br/&gt;  二、Compile 出 PIC 碼 (Position Independent Code)&lt;br/&gt;         只有部份 data 需要 relocation 即可。&lt;br/&gt;  其中第二項衍生出 XIP (eXecute In Place) ，就是程式可以直接在 ROM&lt;br/&gt;  上面執行的方式，因為 ROM 是 read only，可以被多個 instance share 使用。&lt;br/&gt;&lt;br/&gt;  因為 romfs 上面的程式是 contiguously 排放的，這使得 romfs 是唯一可支援&lt;br/&gt;  XIP 的 file system。&lt;br/&gt;  從這裡可推出這樣的關係：做出 XIP 系統 需要 compiler 支援 PIC 碼。目前&lt;br/&gt;  只有 m68k &amp;amp; ARM 有這樣的 gcc compiler.&lt;br/&gt;&lt;br/&gt;  編出 bFLT 的程式，其實就是先編出 ELF 格式，再由 linker 轉換。只要&lt;br/&gt;  compile 選項使用 -Wl,-elf2flt 即可作到。另外例如 -Wl,-elf2flt=s16384 這樣&lt;br/&gt;  可以指定 stack 為 16k，toolchain default stack is 4k。（心得：有時 &lt;br/&gt;  default 是不夠的）&lt;br/&gt;&lt;br/&gt;  再來談到 shared library，僅僅想用gcc -shared 選項，無法幫你在 bFLT &lt;br/&gt;  格式中製作  shared library。（心得：下面有 Analog Device 網站上&lt;br/&gt;  的好文詳細描述如何製作 shared library for uClinux）&lt;br/&gt;  這裡只提一個重要概念，shared  library 必須是 XIP ，否則在每個&lt;br/&gt;  uClinux application 都會產生一份 copy --- 這種情形比 static linking&lt;br/&gt;  還要糟糕！&lt;br/&gt;&lt;br/&gt;  結論：伴隨著 NOMMU，uClinux 衍生出這些 與 Linux 的不同處&lt;br/&gt;             uClinux 應用程式開發者，需要自行注意。&lt;br/&gt;摘要（完）&lt;br/&gt;&lt;br/&gt;[ &lt;a href='http://www.beyondlogic.org/uClinux/bflt.htm' target='_blank'&gt;認識 bFLT&lt;/a&gt; ]，當然增加概念，但是對於開發程式，沒有直接幫助。&lt;br/&gt;&lt;br/&gt;另外，下面這幾篇好文，並沒有排在 google 的前面，但是對於在 uClinux &lt;br/&gt;下開發程式， 極有幫助，特此紀錄之。&lt;br/&gt;1.  &lt;a href='http://docs.blackfin.uclinux.org/doku.php?id=toolchain:executable_file_formats' target='_blank'&gt;Executable file formats &lt;/a&gt;&lt;br/&gt;2.  &lt;a href='https://docs.blackfin.uclinux.org/doku.php?id=toolchain:elf2flt' target='_blank'&gt;elf2flt 的說明&lt;/a&gt;&lt;br/&gt;3.  &lt;a target='_blank' href='http://www.ucdot.org/article.pl?sid=02/08/28/0434210&amp;amp;mode=thread'&gt;用 flthdr (flat header)工具來看 bFLT 檔案&lt;/a&gt;&lt;br/&gt;4.  &lt;a href='http://docs.blackfin.uclinux.org/doku.php?id=toolchain:creating_libraries' target='_blank'&gt;Creating Libries&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;一些 uClinux mailing list 的摘要: &lt;br/&gt;[&lt;a href='http://www.mail-archive.com/uclinux-dev@uclinux.org/msg05929.html' target='_blank'&gt; Problems building for uClinux&lt;/a&gt; ]: Jamie Lokier 有教讀者一些 narrow down problem 的方法，很實用！&lt;br/&gt;還有遇到 error: no memory region specified for loadable section `.plt` 的現象，是因為 linker 遇到 .plt .got ，使其無法 link 成 BFLT program--- 這個 error 在 porting  program for uClinux 時很常遇到.&lt;br/&gt;&lt;br/&gt;1. BFLT program 的製作 ，其實就是 compile 出 elf 後，再用 elf2flt  轉換成 BFLT format program，一般都用 CFLAGS += -elf2flt 告訴 compiler 在 link time 時幫我們轉換。&lt;br/&gt;&lt;br/&gt;2. 若您的程式有自己的 lib ，而且是 static link 的方式，則 lib 先只是作成 elf ，然後 archive 起來 ，用 ranlib 做出 library index （方便 linking ，可有可無），等到和 program linking 時才使用 elf2flt  轉換成 BFLT.&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=cc01f380-06b5-8150-998a-6b0d1fb2d519' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-3734910517220680574?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/3734910517220680574/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2011/03/uclinux.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/3734910517220680574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/3734910517220680574'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2011/03/uclinux.html' title='uClinux 新手筆記'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-3719509595849011740</id><published>2011-03-11T01:09:00.001-08:00</published><updated>2011-03-11T01:14:41.834-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='arm'/><category scheme='http://www.blogger.com/atom/ns#' term='linux programming'/><category scheme='http://www.blogger.com/atom/ns#' term='serial'/><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>linux serial port programming : CLOCAL 的設定</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;先來看 Carrier Detect (CD) signal line 的意義。&lt;br/&gt;節錄自 "Serial Communication / Mark Nelson" 一書 :&lt;br/&gt;"Unfortunatly, before the era of intelligent modems, some terminals &lt;br/&gt;or other DTE equipment were designed to treat a modem as unusable &lt;br/&gt;without CD. Devices such as these would not send or receive &lt;br/&gt;characters to a modem that had CD low. Because of these anachronisms,&lt;br/&gt;&lt;font color='#cc0000'&gt;most modems built today can keep CD high at all times, whether or not &lt;br/&gt;a carrier has been established. &lt;/font&gt;&lt;br/&gt;Because these feature is sometimes the default mode of operation, &lt;br/&gt;using CD for accurate detection of carrier presence is somewhat risky. &lt;br/&gt;However, &lt;font color='#cc0000'&gt;most users should be able to configure their modems so as to &lt;br/&gt;disable this troublesome behavior&lt;/font&gt;."&lt;br/&gt;&lt;br/&gt;中文口白一下：以前時代，CD 是 modem (DCE 端) 用來告訴 終端機 (DTE 端) 說：&lt;br/&gt;我有連到對方喔！但是後續的 modem (DCE) 有的已經不照這種約定了---&lt;br/&gt;不管有沒有跟遠端連線，一律拉 CD 起來。&lt;br/&gt;所以 DTE 根據 CD 判斷 DCE 有無與對方連線的方式，已經不可靠了。&lt;br/&gt;所以現在 DTE 必須可以 configure設定，&lt;font color='#006600'&gt;不要再看這個不可靠的 CD signal.&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;怎樣 configure ? Linux serial driver 提供這樣的 flag --- termios 屬性若有設定 &lt;br/&gt;CLOCAL ，在 2.6.28 generic_serial.c ::&lt;br/&gt;uart_change_speed():&lt;br/&gt;{    ...&lt;br/&gt;    if (termios-&amp;gt;c_cflag &amp;amp; CLOCAL)&lt;br/&gt;        state-&amp;gt;info-&amp;gt;flags &amp;amp;= ~UIF_CHECK_CD;&lt;br/&gt;    ...&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;那 UIF_CHECK_CD 有何作用呢？&lt;br/&gt;&lt;br/&gt;uart_handle_dcd_change(struct uart_port *port, unsigned int status) &lt;br/&gt;{  ... &lt;br/&gt;    if (info-&amp;gt;flags &amp;amp; UIF_CHECK_CD) {&lt;br/&gt;        if (status)&lt;br/&gt;            wake_up_interruptible(&amp;amp;info-&amp;gt;port.open_wait);&lt;br/&gt;        else if (info-&amp;gt;port.tty)&lt;br/&gt;            tty_hangup(info-&amp;gt;port.tty);&lt;br/&gt;    }&lt;br/&gt;    ...&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;也就是說，有 UIF_CHECK_CD 時，就 wake up 正在等待 open 的 process，&lt;br/&gt;或是 hangup tty，這些都是在 CD signal change 時本來預定的動作。&lt;br/&gt;  &lt;br/&gt;所以在這裡，&lt;font color='#006600'&gt;設定 CLOCAL 可以 "遮蔽" 對於 CD 訊號的判斷。&lt;/font&gt;&lt;br/&gt;若您的應用程式 open serial port 時，忘記設定 CLOCAL，&lt;br/&gt;就會照者書上所說的操作定義 --- 因為 DTE 發現 DCE 的 CD 不見了，&lt;br/&gt;就 hang up tty 了。&lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&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/8646454779089790212-3719509595849011740?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/3719509595849011740/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2011/03/linux-serial-port-programming-clocal.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/3719509595849011740'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/3719509595849011740'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2011/03/linux-serial-port-programming-clocal.html' title='linux serial port programming : CLOCAL 的設定'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-8656570639201383870</id><published>2011-01-24T00:10:00.001-08:00</published><updated>2011-01-24T00:10:53.598-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='setup'/><category scheme='http://www.blogger.com/atom/ns#' term='environment'/><title type='text'>Difference between .bash_profile and .bashrc Files</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;以下內容是從&lt;a href='http://www.debianadmin.com/difference-between-bash_profile-and-bashrc-files.html' target='_blank'&gt;這裏&lt;/a&gt;節錄出來的：&lt;br/&gt;&lt;br/&gt;.bash_profile is executed for login shells, while .bashrc is executed for interactive non-login shells.&lt;br/&gt;&lt;br/&gt;就是說，當你使用 login console 或用 ssh login 時， &lt;font color='#cc0000'&gt;&lt;b&gt;.bash_profile&lt;/b&gt;&lt;/font&gt; 會被調用。&lt;br/&gt;如果只是在 GNOME, KDE 或 emacs 裏面，打開一個 shell command 時，&lt;b&gt;&lt;font color='#cc0000'&gt; &lt;/font&gt;&lt;font color='#cc0000' face='monospace'&gt;.bashrc&lt;/font&gt;&lt;font color='#cc0000'&gt; &lt;/font&gt;&lt;/b&gt;會被調用。&lt;br/&gt;&lt;br/&gt;那麼作 global 設定時，就是這兩種情形分別對應到&lt;font color='#cc0000'&gt; &lt;b&gt;/etc/profile&lt;/b&gt;&lt;/font&gt; 與&lt;font color='#cc0000'&gt;&lt;b&gt; /etc/bash.bashrc&lt;/b&gt;&lt;/font&gt; 啦！ &lt;br/&gt;其中，若是需要在 login 時，也希望 bashrc 被調用，就可以在 profile 裏面 source bashrc.&lt;br/&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/8646454779089790212-8656570639201383870?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/8656570639201383870/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2011/01/difference-between-bashprofile-and.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/8656570639201383870'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/8656570639201383870'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2011/01/difference-between-bashprofile-and.html' title='Difference between .bash_profile and .bashrc Files'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-1242164083861570573</id><published>2011-01-23T20:08:00.001-08:00</published><updated>2011-01-24T00:14:21.365-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='setup'/><title type='text'>git 更改遠端資訊 的指令</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;為了轉移到新的伺服器，git 的 repository 要搬到新位置，所以 local 端的 repository 指標要換掉，下列指令依序就是轉換的步驟：&lt;br/&gt;&lt;br/&gt;#&amp;gt; git remote -v&lt;br/&gt;顯示目前指向哪些遠端的 repository? （URL 格式）&lt;br/&gt;&lt;br/&gt;#&amp;gt; git remote rm origin&lt;br/&gt;移除 URL 資訊&lt;br/&gt;&lt;br/&gt;#&amp;gt; git remote add origin git@&lt;i&gt;git-server&lt;/i&gt;:&lt;i&gt;project_name&lt;/i&gt;&lt;br/&gt;改變 URL 資訊，指向新位置 （若是用 gitosis ，就可以直接建立新的遠端 repository ，否則遠端的新增的 repository 必須先用 git init 或 git init --bare 處理過）&lt;br/&gt;（目前為止，都還沒有對 remote repository 產生任何影響）&lt;br/&gt;&lt;br/&gt;#&amp;gt; git push origin master&lt;br/&gt;把 local repository 更新到 remote 端（這裡，才實際的更新了 remote repository）&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/8646454779089790212-1242164083861570573?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/1242164083861570573/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2011/01/git.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/1242164083861570573'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/1242164083861570573'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2011/01/git.html' title='git 更改遠端資訊 的指令'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-2805554575184772377</id><published>2011-01-23T07:22:00.001-08:00</published><updated>2011-01-23T07:22:12.027-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='install'/><category scheme='http://www.blogger.com/atom/ns#' term='setup'/><category scheme='http://www.blogger.com/atom/ns#' term='environment'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Install sun-java5-* in debian squeeze</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Debian Squeeze 已經把 sun-java5-* （亦即 java 1.5 ）拿掉了，統統換成了 sun-java6-* （亦即 java 1.6）「註：這裡 * 代表 jre, bin, jdk, demo 等等部份」。&lt;br/&gt;可是 Android 開發環境會檢查 java 環境，仍然需要 java 1.5 ，怎麼辦呢？&lt;br/&gt;可以用 dpkg --force-depends 強制安裝 sun-java5-*  ，方法如下：&lt;br/&gt;&lt;br/&gt;1. 首先下載 Lenny 版本的 package :&lt;br/&gt;sun-java5-bin_1.5.0-22-0lenny1_i386.deb&lt;br/&gt;sun-java5-jre_1.5.0-22-0lenny1_all.deb&lt;br/&gt;sun-java5-demo_1.5.0-22-0lenny1_i386.deb&lt;br/&gt;sun-java5-jdk_1.5.0-22-0lenny1_i386.deb&lt;br/&gt;&lt;br/&gt;2  因為 bin 依賴於 jre , jre 依賴於 bin, jdk 依賴於 demo, demo 依賴於 jdk 。&lt;br/&gt;所以用強制 depends 選項（把依賴關係列為 warning 而非 error ）就可以順利安裝，指令為：&lt;br/&gt;#&amp;gt; dpkg --force-depends -i  sun-java5-bin_1.5.0-22-0lenny1_i386.deb\&lt;br/&gt;  sun-java5-jre_1.5.0-22-0lenny1_all.deb\&lt;br/&gt;  sun-java5-demo_1.5.0-22-0lenny1_i386.deb\&lt;br/&gt;  sun-java5-jdk_1.5.0-22-0lenny1_i386.deb&lt;br/&gt;&lt;br/&gt;3. 切換內定 java version :&lt;br/&gt;#&amp;gt; sudo update-java-alternatives -s java-1.5.0-sun &lt;br/&gt;如果出現一堆跟 firefox plugin 的錯誤訊息，像這樣：&lt;br/&gt;update-alternatives: error: alternative /usr/lib/jvm/java-1.5.0-sun/jre/&lt;font color='#000099'&gt;plugin&lt;/font&gt;/i386/ns7/libjavaplugin_oji.so for &lt;font color='#000099'&gt;firefox-javaplugin.so&lt;/font&gt; not registered, not setting.&lt;br/&gt;...&lt;br/&gt;不用管它，因為我們 compile Android 時應該不會用到 firefox 的 java plugin。&lt;br/&gt;&lt;br/&gt;4. 驗證 java version ：&lt;br/&gt;#&amp;gt; javac -version &lt;br/&gt;應該就可以看到 java 1.5 的訊息了！&lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=7c35ea4b-4aaf-850e-b9a6-a87073a8fb28' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-2805554575184772377?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/2805554575184772377/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2011/01/install-sun-java5-in-debian-squeeze.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/2805554575184772377'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/2805554575184772377'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2011/01/install-sun-java5-in-debian-squeeze.html' title='Install sun-java5-* in debian squeeze'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-5850081291600122009</id><published>2010-11-26T16:55:00.001-08:00</published><updated>2010-12-04T04:16:42.814-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='install'/><category scheme='http://www.blogger.com/atom/ns#' term='setup'/><category scheme='http://www.blogger.com/atom/ns#' term='environment'/><title type='text'>忽然想要列印 man page 怎麼辦？</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;老 Unix 玩家應該覺得很簡單，但對於新手的我還是要紀錄一下：&lt;br/&gt;1. 先由命令查閱要列印的 man page 再哪裡？ 例如 ：&lt;br/&gt;tom@glest:~/temp$ man -w groff&lt;br/&gt;/usr/share/man/man1/groff.1.gz&lt;br/&gt;2. 原來是有壓縮的，知道後就可以印了：&lt;br/&gt;tom@glest:~/temp$ zcat `man -w groff` | groff -m man -T ps - | lpr&lt;br/&gt;&lt;br/&gt;這裡 groff 是排版用的指令，輸入格式為 man page ，輸出格式為 ps 。&lt;br/&gt;That's it !&lt;br/&gt;&lt;br/&gt;p.s. 當然你的 lpr 要正確才行，如果有裝好 cups，下列命令就可以看到系統印表機狀態：&lt;br/&gt;tom@glest:~/temp$ iceweasel http://localhost:631/admin&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=57f117d3-342f-884b-87cb-05c081522295' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-5850081291600122009?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/5850081291600122009/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2010/11/man-page.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/5850081291600122009'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/5850081291600122009'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2010/11/man-page.html' title='忽然想要列印 man page 怎麼辦？'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-5301370458848989353</id><published>2010-11-19T01:12:00.001-08:00</published><updated>2010-12-17T14:59:12.795-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>一些 C preprocessor 的用法</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;在 wireshark source 裡面，看到有些奇怪的 C 語言寫法 : 查不到定義的 _U_。在這裡當備忘錄記一下：&lt;br/&gt;hostname$ cat foo.c&lt;br/&gt;int  foo(int a _U_, int b _U_, int c)&lt;br/&gt;{&lt;br/&gt;    return c + 17;&lt;br/&gt;}&lt;br/&gt;#hostname$ gcc &lt;b&gt;-D_U_=&lt;/b&gt;  -c -O2 -Wall -W foo.c&lt;br/&gt;  foo.c: In function `foo':&lt;br/&gt;  foo.c:2: warning: unused parameter `a'&lt;br/&gt;  foo.c:2: warning: unused parameter `b'&lt;br/&gt;&lt;br/&gt;上面定義 _U_  為"什麼東東都沒有" ，結果出現 compiler warning.&lt;br/&gt;&lt;br/&gt;#hostname$ gcc &lt;b&gt;-D_U_="__attribute((unused))"&lt;/b&gt; -c -O2 -Wall -W foo.c&lt;br/&gt;#hostname$ gcc --version&lt;br/&gt;2.95.1f&lt;br/&gt;&lt;br/&gt;這裡 _U_　被定義為 attribute of "suppress unused variable warning"，所以就沒有 compiler warning 了！&lt;br/&gt;那為何不使用的參數不拿掉呢？ 不知道耶！ 猜想是為了將來需要時不用動到很多 callers 就可以修改 function code 吧！&lt;br/&gt;&lt;br/&gt;    &lt;hr/&gt;   &lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;br/&gt;&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=3b44483b-8f59-81d1-b424-c7ce6052fd61' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-5301370458848989353?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/5301370458848989353/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2010/11/c-preprocessor_19.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/5301370458848989353'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/5301370458848989353'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2010/11/c-preprocessor_19.html' title='一些 C preprocessor 的用法'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-2334240082967259481</id><published>2010-08-26T03:07:00.001-07:00</published><updated>2010-09-14T01:15:31.091-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><category scheme='http://www.blogger.com/atom/ns#' term='setup'/><category scheme='http://www.blogger.com/atom/ns#' term='environment'/><title type='text'>emacsclient font configurations</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;font color='#cc0000'&gt;This text applies to version after Emacs 23.1&lt;/font&gt;&lt;br/&gt;&lt;font color='#cc0000'&gt;&lt;font color='#cc0000'&gt;首先，我們可以把下列一行加入&lt;/font&gt; &lt;font color='#000000'&gt;&lt;b&gt;&lt;font face='monospace'&gt;~/.bashrc&lt;/font&gt;&lt;/b&gt;&lt;/font&gt; &lt;/font&gt;&lt;br/&gt;&lt;font face='monospace'&gt;&lt;b&gt;  alias ex='emacsclient -a "" -c "$@"'&lt;/b&gt;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;解釋一下：&lt;br/&gt;當我們使用 emacsclient 時，必須有一個 emacs server 啟動才可以用。&lt;br/&gt;emacsclient 的參數有一個 -a "" 表示萬一 emacs server 沒有啟動，&lt;br/&gt;就使用 `alternate editor' ，它可以是 vi, pico ... ，若是空字串 ("") ，表示 `那就叫一個 emacs server 起來好了'.&lt;br/&gt;另外 參數 -c 表示 `create a new frame' 而不是用 server 的 frame.&lt;br/&gt;至於後面要打開的檔案（可以一次指定開多個檔案來編輯），就用 bash 提供的 $@ 來代入即可。&lt;br/&gt;&lt;br/&gt;&lt;font color='#cc0000'&gt;第二，設定字型&lt;/font&gt;，因為 emacs server 可以在 X 之前就啟動了，因此，&lt;br/&gt;很合理的，它不理會你指定在 X 環境下的字型。&lt;br/&gt;現在的 X 環境下有兩種字體系統：核心字體系統與 Xft 字體系統。Xft 有許多優良的特性（向量，反鋸齒等），&lt;br/&gt;所以 Emacs 23.1 開始支援 Xft as its font base. (see &lt;a target='_blank' href='http://www.emacswiki.org/emacs/XftGnuEmacs#toc11'&gt;XftGnuEmacs&lt;/a&gt;).&lt;br/&gt;只要在你的  &lt;b&gt;&lt;font face='monospace'&gt;~/.Xresources&lt;/font&gt;&lt;/b&gt; 指定就好，例如，我們打算用 DejaVu Sans Mono 字型 ：&lt;br/&gt;&lt;b&gt;&lt;font face='monospace'&gt;    Emacs.FontBackend: xft&lt;br/&gt;    Emacs.font: DejaVu Sans Mono-14&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;（謎：怎樣查出這個字型呢？ M-x describe-font 然後給個 mono 讓它 match 出完整的字型敘述） &lt;br/&gt;&lt;br/&gt;&lt;font color='#cc0000'&gt;第三，設定 frame 的特性&lt;/font&gt;，我們希望打開 frame 時，是黑底白字，不要 tool bar, 不要 scroll bar ...&lt;br/&gt;這些都與預設值不同，該怎麼設定呢？&lt;br/&gt;emacs 的 default-frame-alist 裡面紀錄了 `新開一個 frame 所需的參數'，設定這個就對了！&lt;br/&gt;在你的 &lt;b&gt;&lt;font face='monospace'&gt;~/.emacs&lt;/font&gt;&lt;/b&gt; 內這樣指定&lt;br/&gt;&lt;font face='monospace'&gt;&lt;b&gt;(let ((frame '((left . 0)&lt;br/&gt;               (top . 0)&lt;br/&gt;               (width . 110) &lt;br/&gt;               (height . 30) &lt;br/&gt;               (tool-bar-lines . nil)&lt;br/&gt;               (vertical-scroll-bars . nil)&lt;br/&gt;               (background-color . "black")&lt;br/&gt;               (foreground-color . "white")           &lt;br/&gt;)))&lt;br/&gt;  (setq default-frame-alist frame)&lt;br/&gt;  (setq initial-frame-alist frame)&lt;/b&gt;&lt;/font&gt;&lt;br/&gt;)&lt;br/&gt;&lt;br/&gt;說明一下，[ &lt;a target='_blank' href='http://www.gnu.org/software/emacs/manual/html_node/elisp/Frame-Parameters.html#Frame-Parameters'&gt;GNU Emacs 手冊&lt;/a&gt; ]查得到所有的 frame parameters。&lt;br/&gt;第一次開啟的 frame（應該是 server frame)  參數會參考 `initial-frame-alist' ，往後開啟 frames（emacsclient frame）都會參考 `default-frame-alist' .&lt;br/&gt;&lt;br/&gt;完工了！記得重新開啟 X 讓 .Xresources 生效啊啊～&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=c8c3fd5a-c036-8a3f-a5f8-3e871728bc44' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-2334240082967259481?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/2334240082967259481/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2010/08/emacs-2311-environment-configurations.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/2334240082967259481'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/2334240082967259481'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2010/08/emacs-2311-environment-configurations.html' title='emacsclient font configurations'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-1184614984352680479</id><published>2010-08-17T03:30:00.001-07:00</published><updated>2010-08-17T03:39:06.356-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='install'/><category scheme='http://www.blogger.com/atom/ns#' term='setup'/><category scheme='http://www.blogger.com/atom/ns#' term='environment'/><title type='text'>lpr and cups troubleshooting</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Bad situation encountered :&lt;br/&gt;系統是 Debian/Testing.&lt;br/&gt;透過 browser 瀏覽 http://localhost:631 可以透過 CUPS 管理印表機，目前我系統是安裝 CUPS 1.4.4。&lt;br/&gt;使用其中的 Administration | Maintenance -&amp;gt; Print Self Test Page 可以順利印出測試頁面。&lt;br/&gt;但是 emacs 裡面要列印時，就出問題了: 使用 print buffer 命令根本沒反應！&lt;br/&gt;&lt;br/&gt;Troubleshooting :&lt;br/&gt;因為 emacs 使用 `lpr' 指令作列印動作 --- 改用 `lpr' 指令試著列印一個文字檔 --- 也失效。&lt;br/&gt;用 `lpq' 觀察 printing jobs 發現都在 spool 上，卻沒有送到 printer 。&lt;br/&gt;觀察 debian 套件關係，原因是 cups-bsd-1.4.4-2 沒有裝，反倒是 lpr-2008.05 套件有裝上，這兩個是 conflict 的套件，因為都有提供 `lpr' 等指令。&lt;br/&gt;但是前者提供 printing commands (i.e. `lpr') interactive with the CUPS. 必須裝這個套件而不是 `lpr-2008.05' 套件&lt;br/&gt;這次裝錯套件的現象，可能是以前 upgrade 時沒有仔細看就同意用 lpr 套件來取代。&lt;br/&gt;移除 `lpr-2008-05' 並裝上 `cups-bsd-1.4.4-2' ，重新啟動 cupsd 還不夠；可能是我還有 daemon 沒有重起，或是 debian 套件系統沒有正確的 post processing，就沒有去追究了。&lt;br/&gt;試著重新開機， work !&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=d511cdc5-9b94-8453-8307-727be91bd466' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-1184614984352680479?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/1184614984352680479/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2010/08/lpr-and-cups-troubleshooting.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/1184614984352680479'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/1184614984352680479'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2010/08/lpr-and-cups-troubleshooting.html' title='lpr and cups troubleshooting'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-1805144454573851164</id><published>2010-07-13T01:54:00.000-07:00</published><updated>2010-07-13T01:54:00.251-07:00</updated><title type='text'>如何賠掉時間和錢</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;轉錄好文章：[&lt;a href='http://blogs.ipevo.com.tw/post/784051684' target='_blank'&gt; 如何賠掉時間和錢&lt;/a&gt; ]&lt;br/&gt;從今以後，要常常審視有效的工作時間，減少其他雜事----&lt;br/&gt;尤其現在的工作電腦，都能上網，很容易分心！常常體醒自己，正在&lt;b&gt;有效率&lt;/b&gt;的工作嗎？&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=7dea014a-a374-823e-a774-dcd1d81b4cea' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-1805144454573851164?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/1805144454573851164/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2010/07/blog-post_13.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/1805144454573851164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/1805144454573851164'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2010/07/blog-post_13.html' title='如何賠掉時間和錢'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-3608357151279743263</id><published>2010-07-13T01:43:00.000-07:00</published><updated>2010-07-13T01:43:00.901-07:00</updated><title type='text'>ASN.1 的 TYPE-IDENTIFIER.&amp;Type 語法</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;遇到一個 ASN.1 語法敘述，查到在討論群有人問一樣的問題：&lt;a target='_blank' href='http://www.mail-archive.com/asn1@oss.com/msg00858.html'&gt;[ASN.1] TYPE-IDENTIFIER.&amp;amp;Type是甚麼意思&lt;/a&gt;？ 	&lt;div id='msgcontent'&gt;&lt;small&gt;      		&lt;/small&gt;&lt;div class='msgHead'&gt;&lt;small&gt; 			&lt;/small&gt;&lt;pre&gt;例如：&lt;br /&gt;X ::= SEQUENCE&lt;br /&gt;{&lt;br /&gt;   a INTEGER,      -- stuff...&lt;br /&gt;   b BOOLEAN&lt;br /&gt;}&lt;br /&gt;Z ::= SEQUENCE &lt;br /&gt;       y TYPE-IDENTIFIER.&amp;amp;Type (X)&lt;br /&gt;}&lt;br /&gt;則表示 "y" MUST be of type "X" only. 意思同於&lt;br /&gt;Z ::= SEQUENCE &lt;br /&gt;{&lt;br /&gt;     y OCTET STRING (CONTAINING X)&lt;br /&gt;}&lt;br /&gt;這種表示法適用表示於當資料 y 以 PER Encode 後的狀態。舉例說明：&lt;br /&gt;T.38 Annex A ---ASN.1 Notation 可見到&lt;br /&gt;UDPTLPacket ::= SEQUENCE&lt;br /&gt;{&lt;br /&gt;   seq-number  INTEGER (0..65535),&lt;br /&gt;   primary-ifp-packet   TYPE-IDENTIFIER.&amp;amp;Type(IFPPacket),&lt;br /&gt;   error-recovery CHOICE&lt;br /&gt;   {&lt;br /&gt;      secondary-ifp-packets SEQUENCE OF TYPE-IDENTIFIER.&amp;amp;Type(IFPPacket),&lt;br /&gt;      fec-info   SEQUENCE&lt;br /&gt;      {&lt;br /&gt;         fec-npackets  INTEGER,&lt;br /&gt;         fec-data   SEQUENCE OF OCTET STRING&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;我們限定 primary-ifp-packet 必須是經過 PER Encode 之後的 IFPPacket, 還有&lt;br /&gt;secondary-ifp-packets 也是連續的 PER Encode 過的 octets stream. 唯有用&lt;br /&gt;"TYPE-IDENTIFIER.&amp;amp;Type" 語法，才能表示出來。&lt;br /&gt;更多的說明，可參考：&lt;br /&gt;"Communications Between Heterogenus Systems" by Oliver Dubuisson, or&lt;br /&gt;"ASN.1 Complete" by John Larmouth&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=07903546-b329-8e49-9e2c-633b7e729c71' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-3608357151279743263?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/3608357151279743263/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2010/07/asn1-type-identifier.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/3608357151279743263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/3608357151279743263'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2010/07/asn1-type-identifier.html' title='ASN.1 的 TYPE-IDENTIFIER.&amp;amp;Type 語法'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-614680946143616211</id><published>2010-05-26T21:58:00.001-07:00</published><updated>2010-06-10T23:28:00.046-07:00</updated><title type='text'>[轉貼]用gcc 自製 Library</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;small&gt;By kaineshu&lt;/small&gt;  			&lt;div class='entry'&gt; 				&lt;div class='snap_preview'&gt;&lt;p&gt;轉自 PTT LinuxDev&lt;/p&gt; &lt;p&gt;–&lt;/p&gt; &lt;p&gt;作者: cole945 (躂躂..) 看板: LinuxDev&lt;/p&gt; &lt;p&gt;標題: [心得] 用gcc 自製Library&lt;/p&gt; &lt;p&gt;時間: Sun Nov 5 04:15:45 2006&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;Library可分成三種，static、shared與dynamically loaded。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;1. Static libraries&lt;/p&gt; &lt;p&gt; &lt;/p&gt;    &lt;p&gt;Static 程式庫用於靜態連結，簡單講是把一堆object檔用ar(archiver)包裝集合起來，檔名以`.a’ 結尾。優點是執行效能通常會比後兩者快，而且因為是靜態連結，所以不易發生執行時找不到library或版本錯置而無法執行的問題。缺點則是檔案較大，維護度較低；例如library如果發現bug需要更新，那麼就必須重新連結執行檔。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;1.1 編譯&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;編譯方式很簡單，先例用`-c’ 編出object 檔，再用ar 包起來即可。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;____ hello.c ____&lt;/p&gt; &lt;p&gt;#include &lt;stdio.h/&gt;&lt;/p&gt; &lt;p&gt;void hello(){ printf(“Hello “); }&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;____ world.c ____&lt;/p&gt; &lt;p&gt;#include &lt;stdio.h/&gt;&lt;/p&gt; &lt;p&gt;void world(){ printf(“world.”); }&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;____ mylib.h ____&lt;/p&gt; &lt;p&gt;void hello();&lt;/p&gt; &lt;p&gt;void world();&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;$ gcc -c hello.c world.c /* 編出hello.o 與world.o */&lt;/p&gt; &lt;p&gt;$ ar rcs libmylib.a hello.o world.o /* 包成limylib.a */&lt;/p&gt; &lt;p&gt; &lt;/p&gt;  &lt;p&gt;這樣就可以建出一個檔名為libmylib.a 的檔。輸出的檔名其實沒有硬性規定，但如果想要配合gcc 的’-l’ 參數來連結，一定要以`lib’ 開頭，中間是你要的library名稱，然後緊接著`.a’ 結尾。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;1.2 使用&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;____ main.c ____&lt;/p&gt; &lt;p&gt;#include “mylib.h”&lt;/p&gt; &lt;p&gt;int main() {&lt;/p&gt; &lt;p&gt;hello();&lt;/p&gt; &lt;p&gt;world();&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;使用上就像與一般的object 檔連結沒有差別。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;$ gcc main.c libmylib.a&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;也可以配合gcc 的`-l’ 參數使用&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;$ gcc main.c -L. -lmylib&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;-L 參數用來指定要搜尋程式庫的目錄，`.' 表示搜尋現在所在的目錄。通常預設會搜/usr/lib 或/lib 等目錄。&lt;/p&gt; &lt;p&gt;-l  參數用來指定要連結的程式庫，'mylib' 表示要與mylib進行連結&lt;/p&gt; &lt;p&gt;，他會搜尋library名稱前加`lib'後接`.a'的檔案來連結。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;$ ./a.out&lt;/p&gt; &lt;p&gt;Hello world.&lt;/p&gt; &lt;p&gt;2. Shared libraries&lt;/p&gt; &lt;p&gt; &lt;/p&gt;   &lt;p&gt;Shared library 會在程式執行起始時才被自動載入。因為程式庫與執行檔是分離的，所以維護彈性較好。有兩點要注意，shared library是在程式起始時就要被載入，而不是執行中用到才載入，而且在連結階段需要有該程式庫才能進行連結。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;首先有一些名詞要弄懂，soname、real name與linker name。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;  &lt;p&gt;soname 用來表示是一個特定library 的名稱，像是libmylib.so.1 。前面以`lib' 開頭，接著是該library 的名稱，然後是`.so' ，接著是版號，用來表名他的介面；如果介面改變時，就會增加版號來維護相容度。&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;real name 是實際放有library程式的檔案名稱，後面會再加上minor 版號與release 版號，像是libmylib.so.1.0.0 。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;    &lt;p&gt;一般來說，版號的改變規則是(印象中在APress-Difinitive Guide to GCC中有提到，但目前手邊沒這本書)，最尾碼的release版號用於程式內容的修正，介面完全沒有改變。中間的minor用於有新增加介面，但相舊介面沒改變，所以與舊版本相容。最前面的version版號用於原介面有移除或改變，與舊版不相容時。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;linker name是用於連結時的名稱，是不含版號的soname ，如: libmylib.so。&lt;/p&gt;  &lt;p&gt;通常linker name與real name是用ln 指到對應的real name ，用來提供彈性與維護性。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;2.1 編譯&lt;/p&gt; &lt;p&gt;shared library的製作過程較複雜。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;$ gcc -c -fPIC hello.c world.c&lt;/p&gt; &lt;p&gt; &lt;/p&gt;  &lt;p&gt;編譯時要加上-fPIC 用來產生position-independent code。也可以用-fpic參數。(不太清楚差異，只知道-fPIC 較通用於不同平台，但產生的code較大，而且編譯速度較慢)。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;$ gcc -shared -Wl,-soname,libmylib.so.1 -o libmylib.so.1.0.0 \&lt;/p&gt; &lt;p&gt;hello.o world.o&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;-shared 表示要編譯成shared library&lt;/p&gt; &lt;p&gt;-Wl 用於參遞參數給linker，因此-soname與libmylib.so.1會被傳給linker處理。&lt;/p&gt; &lt;p&gt;-soname用來指名soname 為limylib.so.1&lt;/p&gt; &lt;p&gt;library會被輸出成libmylib.so.1.0.0 (也就是real name)&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;若不指定soname 的話，在編譯結連後的執行檔會以連時的library檔名為soname，並載入他。否則是載入soname指定的library檔案。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;可以利用objdump 來看library 的soname。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;$ objdump -p libmylib.so | grep SONAME&lt;/p&gt; &lt;p&gt;SONAME libmylib.so.1&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;若不指名-soname參數的話，則library不會有這個欄位資料。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;在編譯後再用ln 來建立soname 與linker name 兩個檔案。&lt;/p&gt; &lt;p&gt;$ ln -s libmylib.so.1.0.0 libmylib.so&lt;/p&gt; &lt;p&gt;$ ln -s libmylib.so.1.0.0 libmylib.so.1&lt;/p&gt; &lt;p&gt;2.2 使用&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;與使用static library 同。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;$ gcc main.c libmylib.so&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;以上直接指定與libmylib.so 連結。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;或用&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;$ gcc main.c -L. -lmylib&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;linker會搜尋libmylib.so 來進行連結。&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;如果目錄下同時有static與shared library的話，會以shared為主。使用-static 參數可以避免使用shared連結。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;$ gcc main.c -static -L. -lmylib&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;此時可以用ldd 看編譯出的執行檔與shared程式庫的相依性&lt;/p&gt; &lt;p&gt;$ldd a.out&lt;/p&gt; &lt;p&gt;linux-gate.so.1 =&amp;gt; (0xffffe000)&lt;/p&gt; &lt;p&gt;[1;33mlibmylib.so.1 =&amp;gt; not found[m&lt;/p&gt; &lt;p&gt;libc.so.6 =&amp;gt; /lib/libc.so.6 (0xb7dd6000)&lt;/p&gt; &lt;p&gt;/lib/ld-linux.so.2 (0xb7f07000)&lt;/p&gt;   &lt;p&gt; &lt;/p&gt;&lt;p&gt;輸出結果顯示出該執行檔需要libmylib.so.1 這個shared library。會顯示not found 因為沒指定該library所在的目錄，所找不到該library。因為編譯時有指定-soname參數為libmylib.so.1 的關係，所以該執行檔會&lt;/p&gt;  &lt;p&gt;載入libmylib.so.1。否則以libmylib.so連結，執行檔則會變成要求載入libmylib.so&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;$ ./a.out&lt;/p&gt; &lt;p&gt;./a.out: error while loading shared libraries: [1;33mlibmylib.so.1[m:&lt;/p&gt; &lt;p&gt;cannot open shared object file: No such file or directory&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;因為找不到libmylib.so.1 所以無法執行程式。&lt;/p&gt; &lt;p&gt;有幾個方式可以處理。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;a. 把libmylib.so.1 安裝到系統的library目錄，如/usr/lib下&lt;/p&gt; &lt;p&gt;b. 設定/etc/ld.so.conf ，加入一個新的library搜尋目錄，並執行ldconfig&lt;/p&gt; &lt;p&gt;更新快取&lt;/p&gt; &lt;p&gt;c. 設定LD_LIBRARY_PATH 環境變數來搜尋library&lt;/p&gt; &lt;p&gt;這個例子是加入目前的目錄來搜尋要載作的library&lt;/p&gt; &lt;p&gt;$ LD_LIBRARY_PATH=. ./a.out&lt;/p&gt; &lt;p&gt;Hello world.&lt;/p&gt; &lt;p&gt;3. Dynamically loaded libraries&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;Dynamicaaly loaded libraries 才是像windows 所用的DLL ，在使用到&lt;/p&gt;  &lt;p&gt;時才載入，編譯連結時不需要相關的library。動態載入庫常被用於像plug-ins的應用。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;3.1 使用方式&lt;/p&gt; &lt;p&gt;動態載入是透過一套dl function來處理。&lt;/p&gt; &lt;p&gt;#include &lt;dlfcn.h/&gt;&lt;/p&gt; &lt;p&gt;void *dlopen(const char *filename, int flag);&lt;/p&gt; &lt;p&gt;開啟載入filename 指定的library。&lt;/p&gt; &lt;p&gt;void *dlsym(void *handle, const char *symbol);&lt;/p&gt; &lt;p&gt;取得symbol 指定的symbol name在library被載入的記憶體位址。&lt;/p&gt; &lt;p&gt;int dlclose(void *handle);&lt;/p&gt; &lt;p&gt;關閉dlopen開啟的handle。&lt;/p&gt; &lt;p&gt;char *dlerror(void);&lt;/p&gt; &lt;p&gt;傳回最近所發生的錯誤訊息。&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;____ dltest.c ____&lt;/p&gt; &lt;p&gt;#include &lt;stdio.h/&gt;&lt;/p&gt; &lt;p&gt;#include &lt;stdlib.h/&gt;&lt;/p&gt; &lt;p&gt;#include &lt;dlfcn.h/&gt;&lt;/p&gt; &lt;p&gt;int main() {&lt;/p&gt; &lt;p&gt;void *handle;&lt;/p&gt; &lt;p&gt;void (*f)();&lt;/p&gt; &lt;p&gt;char *error;&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;/* 開啟之前所撰寫的libmylib.so 程式庫*/&lt;/p&gt; &lt;p&gt;handle = dlopen("./libmylib.so", RTLD_LAZY);&lt;/p&gt; &lt;p&gt;if( !handle ) {&lt;/p&gt; &lt;p&gt;fputs( dlerror(), stderr);&lt;/p&gt; &lt;p&gt;exit(1);&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;/* 取得hello function 的address */&lt;/p&gt; &lt;p&gt;f = dlsym(handle, "hello");&lt;/p&gt; &lt;p&gt;if(( error=dlerror())!=NULL) {&lt;/p&gt; &lt;p&gt;fputs(error, stderr);&lt;/p&gt; &lt;p&gt;exit(1);&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;/* 呼叫該function */&lt;/p&gt; &lt;p&gt;f();&lt;/p&gt; &lt;p&gt;dlclose(handle);&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;編譯時要加上-ldl 參數來與dl library 連結&lt;/p&gt; &lt;p&gt;$ gcc dltest.c -ldl&lt;/p&gt; &lt;p&gt;結果會印出Hello 字串&lt;/p&gt; &lt;p&gt;$ ./a.out&lt;/p&gt; &lt;p&gt;Hello&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;關於dl的詳細內容請參閱man dlopen&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;Creating a shared and static library with the gnu compiler [gcc]&lt;/p&gt; &lt;p&gt;&lt;a href='http://www.adp-gmbh.ch/cpp/gcc/create_lib.html'&gt;http://www.adp-gmbh.ch/cpp/gcc/create_lib.html&lt;/a&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;Program Library HOWTO&lt;/p&gt; &lt;p&gt;&lt;a href='http://tldp.org/HOWTO/Program-Library-HOWTO/index.html'&gt;http://tldp.org/HOWTO/Program-Library-HOWTO/index.html&lt;/a&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;APress – Definitive Guide to GCC&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;–&lt;/p&gt; &lt;p&gt;※發信站: 批踢踢實業坊(ptt.cc)&lt;/p&gt; &lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=444b40be-a975-8e58-bb17-5a85834a380a' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-614680946143616211?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/614680946143616211/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2010/05/gcc-library.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/614680946143616211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/614680946143616211'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2010/05/gcc-library.html' title='[轉貼]用gcc 自製 Library'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-4957095758194886036</id><published>2010-05-20T21:12:00.001-07:00</published><updated>2011-03-28T08:20:40.699-07:00</updated><title type='text'>emacs and program tracing</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;div class='post-header'&gt;  &lt;/div&gt;  使用 emacs tracing pogram 之時，陸續發現幾個方便的按鍵，因為沒什麼系統性，又怕忘記，只好開個 blog 來紀錄:&lt;br/&gt;&lt;br/&gt;&lt;b&gt;&lt;font face='monospace'&gt;C-M-p&lt;br/&gt;C-M-n&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;   如同 Visual C++ 的括號追蹤，游標可以來回跳至成對的括號位置。&lt;br/&gt;   小技巧，遇到&lt;b&gt;&lt;font face='monospace'&gt; {&lt;/font&gt;&lt;/b&gt; 時，游標要放在括號的位置上&lt;br/&gt;                 遇到&lt;font face='monospace'&gt;&lt;b&gt; }&lt;/b&gt;&lt;/font&gt; 時，游標要放在括號的右邊一格&lt;br/&gt;&lt;br/&gt;&lt;b&gt;C-c C-p&lt;/b&gt;&lt;br/&gt;&lt;b&gt;C-c C-n&lt;/b&gt;&lt;br/&gt;   從游標處往上找，移至最近的 #ifdef   &lt;br/&gt;   從游標處往下找，移至最近的 #endif 後面一格&lt;br/&gt;&lt;br/&gt;&lt;b&gt;C-c C-u&lt;/b&gt;&lt;br/&gt;   移至上一層的 #ifdef &lt;br/&gt;[ Note ] C-c 是 mode specific command 之意，在此例就是 C mode&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;font face='monospace'&gt;&lt;b&gt;C-x C-b &lt;/b&gt;&lt;/font&gt;&lt;br/&gt;   列出 buffers list&lt;br/&gt;&lt;br/&gt;&lt;b&gt;&lt;font face='monospace'&gt;C-x C-→&lt;br/&gt;C-x C-←&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;   跳至前後一個 buffer &lt;br/&gt;&lt;br/&gt;&lt;b&gt;&lt;font face='monospace'&gt;C-x C-q &lt;/font&gt;&lt;/b&gt;&lt;br/&gt;   toggle buffer read only&lt;br/&gt;&lt;br/&gt;&lt;b&gt;&lt;font face='monospace'&gt;M-%&lt;/font&gt;&lt;/b&gt; &lt;i&gt;string&lt;/i&gt; &lt;b&gt;&lt;font face='monospace'&gt;RET&lt;/font&gt;&lt;/b&gt; &lt;i&gt;new-string&lt;/i&gt; &lt;b&gt;&lt;font face='monospace'&gt;RET&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;   Replace string with new-string&lt;br/&gt;&lt;br/&gt;&lt;b&gt;&lt;font face='monospace'&gt;C-M-%&lt;/font&gt;&lt;/b&gt; &lt;i&gt;gregexp&lt;/i&gt; &lt;b&gt;&lt;font face='monospace'&gt;RET&lt;/font&gt;&lt;/b&gt; &lt;i&gt;new-string&lt;/i&gt; &lt;b&gt;&lt;font face='monospace'&gt;RET&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;   Replace some matches for &lt;var&gt;regexp&lt;/var&gt; with &lt;var&gt;newstring&lt;/var&gt;.&lt;br/&gt;&lt;br/&gt;&lt;b&gt;&lt;font face='monospace'&gt;C-h a [RET]&lt;/font&gt;&lt;/b&gt; &lt;i&gt;apropos-key&lt;/i&gt;&lt;br/&gt;   可以用某些 key word 找出命令。例如讓 &lt;i&gt;apropos-key&lt;/i&gt; 為 &lt;b&gt;&lt;font face='monospace'&gt;`window`&lt;/font&gt;&lt;/b&gt; 就會找出含有 &lt;b&gt;&lt;font face='monospace'&gt;`window`&lt;/font&gt;&lt;/b&gt; 字串的命令。&lt;br/&gt;&lt;br/&gt;&lt;font face='monospace'&gt;&lt;b&gt;C-x {&lt;/b&gt;&lt;/font&gt;&lt;br/&gt;&lt;font color='#000000' face='monospace'&gt;  buffer window 水平變大&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;&lt;font face='monospace'&gt;&lt;b&gt;C-x }&lt;/b&gt;&lt;/font&gt;&lt;br/&gt;   &lt;font color='#000000'&gt;&lt;font face='monospace'&gt;buffer window 水平變小&lt;/font&gt;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;&lt;b&gt;&lt;font face='monospace'&gt;C-x z&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;   &lt;font color='#000000'&gt;&lt;font face='monospace'&gt;重複上一個指令動作，緊接著直接按 z 就可再重複&lt;br/&gt;&lt;br/&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face='monospace'&gt;C-h i&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;   可以在 emacs 裡面看 info pages, 進去後，按 [&lt;b&gt;&lt;font face='monospace'&gt;m]emacs &lt;/font&gt;&lt;font face='monospace'&gt;[RET]&lt;/font&gt;&lt;/b&gt; 可以跳進 emacs info 閱讀。（其實就是在emacs里邊閱讀 info pages）&lt;br/&gt;例如：在 &lt;br/&gt;(emacs)Top:: &amp;gt; *Note Keyboard Macros:: &amp;gt; Save Keyboard Macro 一節，&lt;br/&gt;可以找到有關設定 macro 的方法。&lt;br/&gt;&lt;br/&gt;&lt;b&gt;&lt;font face='monospace'&gt;M-n 餵給命令所需參數&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;   &lt;font color='#000000'&gt;&lt;font face='monospace'&gt;以 C-v （往上捲動，內容往下）這命令為例，內定的參數是捲動一整頁，若給它前面加參數1，像這樣：&lt;br/&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color='#000000'&gt;&lt;font face='monospace'&gt;     &lt;b&gt;M-1 C-v &lt;/b&gt;&lt;br/&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color='#000000'&gt;&lt;font face='monospace'&gt; 就只會往上捲一行了。參數也可以是負數喔！例如這樣按：&lt;br/&gt;    按住 "Alt" 然後按 "-" "1" 然後放開 "Alt" 就是輸入參數 -1 的意思，mini-buffer 表示為&lt;br/&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color='#000000'&gt;&lt;font face='monospace'&gt;     &lt;b&gt;M- M-1&lt;/b&gt;&lt;/font&gt;&lt;/font&gt;&lt;br/&gt;  用在剛剛的命令就成了 ：&lt;font color='#000000'&gt;&lt;font face='monospace'&gt;&lt;b&gt;M- M-1 C-v&lt;/b&gt;&lt;/font&gt;&lt;/font&gt; "往下捲動一行" 了。&lt;br/&gt;  OK, 亂玩一下，恰好有個命令是往下捲動一頁 &lt;font color='#000000'&gt;&lt;font face='monospace'&gt;&lt;b&gt;M-v&lt;br/&gt; 所以 M- M-1 C-v 效果等於 M-1 M-v，都會往下捲動一行&lt;br/&gt; &lt;/b&gt;另外 &lt;b&gt;C-u&lt;/b&gt; 是輸入參數 4 的意思&lt;b&gt;&lt;br/&gt;&lt;/b&gt; &lt;b&gt;C-u C-v&lt;/b&gt; 往上捲 4 行，&lt;b&gt;C-u C-u C-v&lt;/b&gt; 表示會捲 16 行喔&lt;b&gt;&lt;br/&gt;&lt;br/&gt;&lt;/b&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face='monospace'&gt;C-s C-w ... C-s&lt;br/&gt;&lt;/font&gt;&lt;/b&gt;&lt;font face='monospace'&gt;  尋找 String, 中間的 C-w&lt;/font&gt;&lt;b&gt;&lt;font face='monospace'&gt; &lt;/font&gt;&lt;/b&gt;&lt;font face='monospace'&gt;可以從游標處往後選字，直到你要尋找的字整個進來為止，接著按 C-s 就可以望下開始找了！超好用！ &lt;/font&gt;&lt;b&gt;&lt;font face='monospace'&gt;&lt;br/&gt;&lt;br/&gt;M-x set-buffer-file-coding-system RET unix&lt;br/&gt;or&lt;br/&gt;C-x  &amp;lt;RET&amp;gt;  f  unix  &amp;lt;RET&amp;gt;&lt;br/&gt;&lt;/font&gt;&lt;/b&gt;&lt;font face='monospace'&gt;    把 Dos 文字格式(\r\n)轉為 Unix文字格式(\n)&lt;/font&gt;&lt;b&gt;&lt;font face='monospace'&gt;&lt;br/&gt;&lt;br/&gt;M-x delete-trailing-whitespace &amp;lt;RET&amp;gt;&lt;br/&gt;&lt;/font&gt;&lt;/b&gt;&lt;font face='monospace'&gt;    移除多餘的行尾空白，符合 Linux Coding Style&lt;/font&gt;&lt;b&gt;&lt;font face='monospace'&gt;&lt;br/&gt;&lt;br/&gt;&lt;/font&gt;&lt;/b&gt;下面是我的 .emacs 內容：&lt;br/&gt;&lt;br/&gt;; auto complete&lt;br/&gt;(add-to-list 'load-path "~/.emacs.d/")&lt;br/&gt;(require 'auto-complete-config)&lt;br/&gt;(add-to-list 'ac-dictionary-directories "~/.emacs.d/ac-dict")&lt;br/&gt;(ac-config-default)&lt;br/&gt;&lt;br/&gt;; edit properties&lt;br/&gt;(modify-frame-parameters nil '((wait-for-wm . nil)))&lt;br/&gt;(setq scroll-margin 0 scroll-conservatively 10000 )&lt;br/&gt;(global-font-lock-mode "t")&lt;br/&gt;;(require 'hl-line)&lt;br/&gt;;(global-hl-line-mode t)&lt;br/&gt;(transient-mark-mode t)&lt;br/&gt;(setq ring-bell-function 'ignore)&lt;br/&gt;;(require 'paren)&lt;br/&gt;;(show-paren-mode 1)&lt;br/&gt;(setq c-default-style "linux")&lt;br/&gt;;(setq c-basic-offset 4)&lt;br/&gt;&lt;br/&gt;(which-function-mode "t")&lt;br/&gt;&lt;br/&gt;(require 'color-theme)&lt;br/&gt;(color-theme-initialize)&lt;br/&gt;(color-theme-hober)&lt;br/&gt;&lt;br/&gt;(load-file "/usr/share/emacs/site-lisp/xcscope.el")&lt;br/&gt;(require 'xcscope)&lt;br/&gt;&lt;br/&gt;(setq cscope-do-not-update-database "t")&lt;br/&gt;(setq cscope-set-initial-directory "./")&lt;br/&gt;(autoload 'gtags-mode "gtags" "" t)&lt;br/&gt;&lt;br/&gt;(setq ecb-tip-of-the-day nil)&lt;br/&gt;&lt;br/&gt;; key bindings &lt;br/&gt;;bind C-&amp;gt; to 'M-x enlarge-window'&lt;br/&gt;(global-set-key (kbd "C-.") (quote enlarge-window))&lt;br/&gt;;bind C-&amp;lt; to 'M-x shrink-window'&lt;br/&gt;(global-set-key (kbd "C-,") (quote shrink-window))&lt;br/&gt;;set &amp;lt;M-f11&amp;gt; as 'scroll-other-window-up-one-line'&lt;br/&gt;(fset 'scroll-other-window-up-one-line "\2551\226")&lt;br/&gt;;set &amp;lt;f11&amp;gt; as 'scroll-other-window-down-one-line'&lt;br/&gt;(fset 'scroll-other-window-down-one-line "\261\226")&lt;br/&gt;&lt;br/&gt;;(global-set-key [f5] 'cscope-find-this-file)&lt;br/&gt;;(global-set-key [f6] 'cscope-find-this-symbol)&lt;br/&gt;;(global-set-key [f7] 'cscope-pop-mark)&lt;br/&gt;;(global-set-key [f8] 'cscope-find-global-definition)&lt;br/&gt;;(global-set-key [f9] 'cscope-find-global-definition-no-prompting)&lt;br/&gt;;(global-set-key [M-up] 'cscope-prev-symbol)'gtags-find-rtag)&lt;br/&gt;;(global-set-key [M-down] 'cscope-next-symbol)&lt;br/&gt;&lt;br/&gt;(global-set-key "\C-cgA" 'gtags-visit-rootdir)&lt;br/&gt;(global-set-key "\C-cgr" 'gtags-find-rtag)&lt;br/&gt;(global-set-key "\C-cgs" 'gtags-find-symbol)&lt;br/&gt;&lt;br/&gt;(global-set-key [f5] 'gtags-find-file)&lt;br/&gt;(global-set-key [f6] 'gtags-find-with-grep)&lt;br/&gt;(global-set-key [f7] 'gtags-pop-stack)&lt;br/&gt;(global-set-key [f8] 'gtags-find-tag)&lt;br/&gt;(global-set-key [f9] 'gtags-find-tag-from-here)&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;(global-set-key [M-f11] 'scroll-other-window-up-one-line)&lt;br/&gt;(global-set-key [f11] 'scroll-other-window-down-one-line)&lt;br/&gt;(global-set-key [C-f12] 'ecb-activate)&lt;br/&gt;(global-set-key [f12] 'ecb-toggle-ecb-windows)&lt;br/&gt;(global-set-key [C-f1] 'color-theme-select)&lt;br/&gt;&lt;br/&gt;(setq c-mode-hook '(lambda () (gtags-mode 1) (auto-complete-mode 1)))&lt;br/&gt;&lt;br/&gt;(let ((frame '((left . 0)&lt;br/&gt;           (top . 0)&lt;br/&gt;           (width . 110) &lt;br/&gt;           (height . 28) &lt;br/&gt;           (tool-bar-lines . nil)&lt;br/&gt;           (vertical-scroll-bars . nil)&lt;br/&gt;           (background-color . "black")&lt;br/&gt;           (foreground-color . "white")          &lt;br/&gt;)))&lt;br/&gt;  (setq default-frame-alist frame)&lt;br/&gt;  (setq initial-frame-alist frame)&lt;br/&gt;)&lt;br/&gt;&lt;br/&gt;;(defun my-font-face ()&lt;br/&gt;;  (custom-set-faces&lt;br/&gt;;   '(default ((t (:inherit nil :stipple nil :background "black" :foreground "white" :inverse-video nil :box nil :strike-through nil :overline nil :underline nil :slant normal :weight normal :height 138 :width normal :foundry "unknown" :family "DejaVu Sans Mono"))))&lt;br/&gt;;   '(ecb-tag-header-face ((t (:background "midnight blue"))))&lt;br/&gt;;   '(ecb-default-highlight-face ((((class color) (background dark)) (:background "#28FF46FF66FF"))))&lt;br/&gt;;))&lt;br/&gt;&lt;br/&gt;(custom-set-variables&lt;br/&gt;  ;; custom-set-variables was added by Custom.&lt;br/&gt;  ;; If you edit it by hand, you could mess it up, so be careful.&lt;br/&gt;  ;; Your init file should contain only one such instance.&lt;br/&gt;  ;; If there is more than one, they won't work right.&lt;br/&gt; '(display-time-mode t)&lt;br/&gt; '(ecb-options-version "2.32")&lt;br/&gt; '(show-paren-mode t))&lt;br/&gt;&lt;br/&gt;&lt;m-f11&gt;&lt;f11&gt;&lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;/f11&gt;&lt;/m-f11&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=61ba3b09-db0e-8e7d-a374-a40c105d9677' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-4957095758194886036?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/4957095758194886036/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2010/05/emacs-and-program-tracing.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/4957095758194886036'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/4957095758194886036'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2010/05/emacs-and-program-tracing.html' title='emacs and program tracing'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-2681409099305551896</id><published>2010-03-25T03:39:00.001-07:00</published><updated>2010-03-25T03:39:49.707-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='commands'/><title type='text'>轉載:10 個最酷的 Linux 單行命令</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;這是來自 [&lt;a href='http://linuxtoy.org/archives/top-10-one-liners.html' target='_blank'&gt;Linux TOY :10 個最酷的 Linux 單行命令&lt;/a&gt; ] 的文章，十個我只知道三個&lt;br/&gt;，有趣的收藏！&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=ae83bb80-d8cd-829c-b842-ee99d077769a' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-2681409099305551896?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/2681409099305551896/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2010/03/10-linux.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/2681409099305551896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/2681409099305551896'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2010/03/10-linux.html' title='轉載:10 個最酷的 Linux 單行命令'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-781274934614841153</id><published>2010-03-13T06:42:00.001-08:00</published><updated>2010-04-20T01:08:00.084-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='commands'/><title type='text'>find 配合 regex</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;在目錄下想要找所有的 .cxx  與 .h 檔 ，然後餵給 cscope.files 怎麼打呢？&lt;br/&gt;[&lt;a href='http://www.lslnet.com/linux/f/docs1/i06/big5136451.htm' target='_blank'&gt;這篇&lt;/a&gt;]解說得很好，在 find 下配合 -regex 應該這樣找 cxx 與 h 檔 ：&lt;br/&gt;&lt;b&gt;&lt;font face='monospace'&gt;find ./ -regex ".*\.\(cxx\|h\)" -print &amp;gt; cscope.files&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;其中 -regex 表示之後用 regex pattern 來尋找, `find` 是用與 `emacs` 相同的 regex 規則&lt;br/&gt;所以後面這麼多反斜線&lt;b&gt; &lt;font face='monospace'&gt;`\'&lt;/font&gt;&lt;/b&gt;  都是因為 emacs regex specifiers 需要用反斜線當 Escape 字元。 &lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=7bfafe03-79e5-814b-9453-c5e34367f379' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-781274934614841153?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/781274934614841153/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2010/03/find-regex.html#comment-form' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/781274934614841153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/781274934614841153'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2010/03/find-regex.html' title='find 配合 regex'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-2786640390866541942</id><published>2009-12-21T18:51:00.001-08:00</published><updated>2009-12-23T23:04:42.517-08:00</updated><title type='text'>libopenh323 and libopal conflict</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;前陣子為了編譯 t38modem 所以需要 libopenh323 當作 library，(header files 需要 libopenh323-dev)&lt;br/&gt;後來發現 the successor of OpenH323 project --- OPAL project (Open Phone Abstraction Library)&lt;br/&gt;但是在 Debian sqeeze 上，這兩組有些衝突，原因是底層的 libpt 版本需求不同造成的，目前我沒有去解決（或強制把 "依賴" libpt-1.10.10 的部份以 libpt-2.6.5 取代，沒有試過不知道！）衝突關係如下列：&lt;br/&gt;&lt;br/&gt;compile libopal-3.6.6 source get  from [ &lt;a href='http://www.opalvoip.org/' target='_blank'&gt;here&lt;/a&gt; ], needs libpt-2.6.5&lt;br/&gt;&lt;br/&gt;libopal-3.6.6&lt;br/&gt;depends on &lt;br/&gt;libpt-2.6.5&lt;br/&gt;&lt;br/&gt;&lt;font color='#993300'&gt;header files in : &lt;/font&gt;&lt;br/&gt;libopal-dev-3.6.6&lt;br/&gt;depends on &lt;br/&gt;libpt-dev-2.6.5-1&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;compile t38modem&lt;br/&gt;needs &lt;br/&gt;libopenh323-dev: /usr/share/openh323/openh323u.mak&lt;br/&gt;&lt;br/&gt;libopenh323-dev &lt;br/&gt;depends on&lt;br/&gt;libpt-1.10.10-dev  &amp;lt;-- &lt;font color='#ff0000'&gt;conflict&lt;/font&gt; libpt-dev-2.6.5-1&lt;br/&gt;libopenh323-1.18&lt;br/&gt;    &lt;br/&gt;&lt;br/&gt;libopenh323-1.18&lt;br/&gt;depends on &lt;br/&gt;libpt-1.10.10 ← &lt;font color='#ff0000'&gt;conflict&lt;/font&gt; libpt-2.6.5&lt;br/&gt;&lt;br/&gt;結論：&lt;br/&gt;所以目前 compile 使用 OpenH323 的 source 與使用 OPAL 的 source 無法同時 compile ，必需把相關的 libpt 重裝（一個用 2.6.5, 另一個用 1.10.10) #Technorati 標籤: &lt;a rel='tag' href='http://technorati.com/tag/OPAL' class='performancingtags'&gt;OPAL&lt;/a&gt;, &lt;a rel='tag' href='http://technorati.com/tag/OpenH323' class='performancingtags'&gt;OpenH323&lt;/a&gt;, &lt;a rel='tag' href='http://technorati.com/tag/libopal' class='performancingtags'&gt;libopal&lt;/a&gt;, &lt;a rel='tag' href='http://technorati.com/tag/libopenh323' class='performancingtags'&gt;libopenh323&lt;/a&gt;, &lt;a rel='tag' href='http://technorati.com/tag/libpt' class='performancingtags'&gt;libpt&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=b3a1ff83-100b-8e4b-b21f-5664ff004b6a' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-2786640390866541942?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/2786640390866541942/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/12/libopenh323-and-libopal-conflict.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/2786640390866541942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/2786640390866541942'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/12/libopenh323-and-libopal-conflict.html' title='libopenh323 and libopal conflict'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-1269906549398947544</id><published>2009-12-13T19:19:00.000-08:00</published><updated>2010-04-20T01:15:49.601-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='install'/><category scheme='http://www.blogger.com/atom/ns#' term='setup'/><category scheme='http://www.blogger.com/atom/ns#' term='environment'/><title type='text'>Debian 升級 testing (sqeeze) 與 ATI X1450 的 driver 問題</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Asus A8J 大約是兩三年前的華碩主流筆電之一，獨立顯卡採用  ATI X1450.&lt;br/&gt;Debian Lenny 下有提供 ATI propietary driver (non-free) :&lt;br/&gt;kernel driver（要 3D 加速，需要 kernel driver ) : fglrx-modules-2.6.26-* 等，driver source : fglrx-kernel-src &lt;br/&gt;for openGL lib : fglrx-glx &lt;br/&gt;根據這篇 [ &lt;a href='http://wiki.archlinux.org/index.php/ATI' target='_blank'&gt;arch linux ATI&lt;/a&gt; ] [&lt;a href='http://en.wikipedia.org/wiki/Comparison_of_ATI_Graphics_Processing_Units' target='_blank'&gt;ref 1&lt;/a&gt;] 知道，X1450 的 code name 為 (RV515, 即 r5xx  系列)&lt;br/&gt;&lt;br/&gt;Debian 系統升級到  testing 後，kernel driver 套件變成 : fglrx-source ， 且改為支援 r6xx-r7xx 而已，也就是說 ATI 官方 driver 不再支援 r5xx 系列，&lt;br/&gt;但是這些不被支援的系列的 spec 已經  release 給 open source 社群。所以目前升級後的  xorg 7.4 裡面的  xserver-xorg-video-ati 套件，可以支援 r5xx 系列。&lt;br/&gt;xorg.conf 已經不需要了，xorg 會自動偵測掛載  radeon driver。&lt;br/&gt;&lt;br/&gt;glxgears 的數據為 &lt;br/&gt;1598 frames in 5.0 seconds = 319.450 FPS  &lt;br/&gt;1613 frames in 5.0 seconds = 322.503 FPS  ( 本blog時間測)&lt;br/&gt;&lt;br/&gt;6097 frames in 5.0 seconds = 1219.223 FPS  &lt;br/&gt;6014 frames in 5.0 seconds = 1202.697 FPS  ( 2010年4月20測)&lt;br/&gt;&lt;br/&gt;跟使用 ATI propietary ~1200 FPS 比較起來，稍稍等待 open source 社群是值得的，&lt;br/&gt;時間會證明 open source community 提供的 code 效能，總會超越 propietary code 的，並且更穩定。&lt;br/&gt;Technorati 標籤: &lt;a rel='tag' href='http://technorati.com/tag/Debian%20Testing' class='performancingtags'&gt;Debian Testing&lt;/a&gt;, &lt;a rel='tag' href='http://technorati.com/tag/sqeeze' class='performancingtags'&gt;sqeeze&lt;/a&gt;, &lt;a rel='tag' href='http://technorati.com/tag/r5xx' class='performancingtags'&gt;r5xx&lt;/a&gt;, &lt;a rel='tag' href='http://technorati.com/tag/3D' class='performancingtags'&gt;3D&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=402a112a-657b-8d85-a8e4-08a61c994978' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-1269906549398947544?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/1269906549398947544/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/12/debian-testing-sqeeze-ati-x1450-driver.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/1269906549398947544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/1269906549398947544'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/12/debian-testing-sqeeze-ati-x1450-driver.html' title='Debian 升級 testing (sqeeze) 與 ATI X1450 的 driver 問題'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-5848194138472709644</id><published>2009-12-07T23:33:00.001-08:00</published><updated>2009-12-08T18:33:42.402-08:00</updated><title type='text'>製作 beagle board kernel v2.6.29-58cf2f1</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;約四個月前，在網路上找到了一篇 [ &lt;a href='http://global.freifunk.net/?q=item/building_a_custom_debian_kernel_for_the_beagleboard' target='_blank'&gt;building a customed kernel for beagle board&lt;/a&gt; ] ，但是事過境遷，該篇 blog 已經不存在。有位對岸的大哥把步驟給節錄下來了[ &lt;a href='http://hi.baidu.com/wadeswb/blog/item/12bd4c19c8da5d0e34fa41f1.html' target='_blank'&gt;制作beagleboard的kernel&lt;/a&gt;  ] ，為了避免以後有類似情形，這裡再節錄一遍過程：&lt;br/&gt;&lt;br/&gt;Retrieve the GIT checkout:&lt;br/&gt;&lt;br/&gt;    git clone git://git2.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git&lt;br/&gt;    cd linux-omap-2.6/&lt;br/&gt;    git checkout 58cf2f1 -b v2.6.29-58cf2f1&lt;br/&gt;    git archive --format=tar --prefix=v2.6.29-58cf2f1/ v2.6.29-58cf2f1 | gzip &amp;gt; ../v2.6.29-58cf2f1.tar.gz&lt;br/&gt;    git checkout master&lt;br/&gt;    git branch v2.6.29-58cf2f1 -D&lt;br/&gt;    cd ..&lt;br/&gt;&lt;br/&gt;Download kernel diffs and kernel config:&lt;br/&gt;&lt;br/&gt;    wget http://rcn-ee.homeip.net:81/dl/omap/beagle/v2.6.29-58cf2f1-oer34/v2.6.29-58cf2f1-oer34.diff&lt;br/&gt;    wget http://rcn-ee.homeip.net:81/dl/omap/beagle/v2.6.29-58cf2f1-oer34/defconfig&lt;br/&gt;&lt;br/&gt;Extract Kernel Source&lt;br/&gt;&lt;br/&gt;    tar -xf v2.6.29-58cf2f1.tar.gz&lt;br/&gt;    cd v2.6.29-58cf2f1/&lt;br/&gt;&lt;br/&gt;Apply Patch&lt;br/&gt;&lt;br/&gt;    patch -p1 &amp;lt; ../v2.6.29-58cf2f1-oer34.diff&lt;br/&gt;&lt;br/&gt;Copy Defconfig&lt;br/&gt;&lt;br/&gt;    cp ../defconfig .config&lt;br/&gt;&lt;br/&gt;Configure the kernel (requires libncurses5-dev installed)&lt;br/&gt;&lt;br/&gt;    make menuconfig&lt;br/&gt;&lt;br/&gt;Build, Cross-Compiling:&lt;br/&gt;&lt;br/&gt;    make CROSS_COMPILE=arm-linux-gnu- uImage&lt;br/&gt;&lt;br/&gt;A few moments later, you can find your new kernel in the ‘arch/arm/boot/’ directory.&lt;br/&gt;&lt;br/&gt;Make modules:&lt;br/&gt;&lt;br/&gt;    make CROSS_COMPILE=arm-linux-gnu- modules&lt;br/&gt;&lt;br/&gt;    make CROSS_COMPILE=arm-linux-gnu- modules_install&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=103a91b2-a759-85fa-9327-f89bbb3c4884' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-5848194138472709644?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/5848194138472709644/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/12/beagle-board-kernel-v2629-58cf2f1_07.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/5848194138472709644'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/5848194138472709644'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/12/beagle-board-kernel-v2629-58cf2f1_07.html' title='製作 beagle board kernel v2.6.29-58cf2f1'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-5309884737072910152</id><published>2009-12-03T07:05:00.001-08:00</published><updated>2009-12-03T17:55:09.255-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>sparse type checking</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;因為 compiler 只能檢查 syntax.&lt;br/&gt;Linus 為了檢查程式的 semantics ，創造出 sparse. 在 [ &lt;a target='_blank' href='http://www.linuxjournal.com/article/7272'&gt;Linux Journal "Linus &amp;amp; Lunatics"&lt;/a&gt; ] 這篇文章提到了他當初的想法：&lt;br/&gt;&lt;br/&gt;相關的 code 在 compiler.h 可以看得到 (kernel source 2.6.28 )&lt;br/&gt;&lt;br/&gt;#ifdef __CHECKER__&lt;br/&gt;# define __user        __attribute__((noderef, address_space(1)))&lt;br/&gt;# define __kernel    /* default address space */&lt;br/&gt;# define __safe        __attribute__((safe))&lt;br/&gt;# define __force    __attribute__((force))&lt;br/&gt;# define __nocast    __attribute__((nocast))&lt;br/&gt;# define __iomem    __attribute__((noderef, address_space(2)))&lt;br/&gt;# define __acquires(x)    __attribute__((context(x,0,1)))&lt;br/&gt;# define __releases(x)    __attribute__((context(x,1,0)))&lt;br/&gt;# define __acquire(x)    __context__(x,1)&lt;br/&gt;# define __release(x)    __context__(x,-1)&lt;br/&gt;# define __cond_lock(x,c)    ((c) ? ({ __acquire(x); 1; }) : 0)&lt;br/&gt;extern void __chk_user_ptr(const volatile void __user *);&lt;br/&gt;extern void __chk_io_ptr(const volatile void __iomem *);&lt;br/&gt;#else&lt;br/&gt;# define __user&lt;br/&gt;# define __kernel&lt;br/&gt;# define __safe&lt;br/&gt;# define __force&lt;br/&gt;# define __nocast&lt;br/&gt;# define __iomem&lt;br/&gt;# define __chk_user_ptr(x) (void)0&lt;br/&gt;# define __chk_io_ptr(x) (void)0&lt;br/&gt;# define __builtin_warning(x, y...) (1)&lt;br/&gt;# define __acquires(x)&lt;br/&gt;# define __releases(x)&lt;br/&gt;# define __acquire(x) (void)0&lt;br/&gt;# define __release(x) (void)0&lt;br/&gt;# define __cond_lock(x,c) (c)&lt;br/&gt;#endif&lt;br/&gt;&lt;br/&gt;平常 gcc compile 時，不定義 __CHECKER__，所以這裡的許多 macros 就得到空定義 (程式碼 #else 部份)&lt;br/&gt;那麼使用 sparse 時，就定義 __CHECKER__ ，(程式碼 #ifdef 部份) 舉例來說 第一行:&lt;br/&gt;&lt;br/&gt;# define __user        __attribute__((noderef, address_space(1)))&lt;br/&gt;&lt;br/&gt;使得 sparse 檢查 __user 定義的變數，是否落在 user space，例如用在 copy_to_user() ：&lt;br/&gt;&lt;br/&gt;unsigned long&lt;br/&gt;copy_to_user(void __user *to, const void *from, unsigned long n) &lt;br/&gt;{...}&lt;br/&gt;&lt;br/&gt;compiler 是不會知道 "to" 的變數是不是正確！但是 sparse 檢查時，若發現 to 所指的不是在 user space 裡，就會發出 warning&lt;br/&gt;&lt;b&gt;因此這些 attributes 是給 sparse 用的，在 gcc 文件裡面查不到這些 attributes&lt;/b&gt; (是的，不要怪 gcc 文件寫不好...)&lt;br/&gt;&lt;br/&gt;另外這篇 [&lt;a target='_blank' href='http://haoyeren.blog.sohu.com/115430836.html'&gt; linux 內核中 compiler.h 文件的分析&lt;/a&gt; ] 還解釋了 __acquire / __release 必須成對使用，否則 sparse 會發出 warning.&lt;br/&gt;&lt;br/&gt;Linus 真神人也，可以讓 kernel source 藉由 sparse 工具來檢查 program semantic !!Technorati 標籤: &lt;a class='performancingtags' href='http://technorati.com/tag/sparse' rel='tag'&gt;sparse&lt;/a&gt;, &lt;a class='performancingtags' href='http://technorati.com/tag/c%20type%20checking' rel='tag'&gt;c type checking&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=d592f152-a112-86e7-839c-4a31b844f069' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-5309884737072910152?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/5309884737072910152/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/12/sparse-type-checking.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/5309884737072910152'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/5309884737072910152'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/12/sparse-type-checking.html' title='sparse type checking'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-2459681251002702830</id><published>2009-11-25T09:14:00.001-08:00</published><updated>2009-11-25T09:14:18.462-08:00</updated><title type='text'>意外的快樂</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;出社會以來，因為家中經濟需要援助，一直都沒有存下甚麼錢。一直到了結婚，也就順勢把所有的收入交給了老婆，接著添了一個弟弟。所以有些年輕時候想要完成的夢，就一直擱著。排一排順序，大概是這樣：&lt;br/&gt;1 最想變成 open source 的 hacker ，為某些 project 貢獻程式碼。當然，基本功還在練習，所以還沒到那個火侯可以當 hacker ...&lt;br/&gt;2  一直想帶親愛的另一半，去美國玩。常出國的人，是不會理解這種渴望的...，有小朋友的父母，更是難排出時間與金錢（費用不訾啊...）&lt;br/&gt;3. 希望有朝一日，圍棋可以上段。 這個夢想本來是四十歲的生日願望，結果沒有達成。因為要扛一家之計，很多時間需要支配到別處，也就擺著了。&lt;br/&gt;&lt;br/&gt;承蒙老婆大人的體貼，跟圍棋老師約了時間，叫我去下指導棋。天啊，一對一耶！&lt;font color='#cc0000'&gt;這可是有錢人才這樣玩吧！&lt;/font&gt;&lt;br/&gt;本來想上完一堂，應付應付就好，不要讓圍棋老師以為咱們家老婆大人沒信用。&lt;br/&gt;但是奇妙的心理變化發生了....&lt;font color='#cc0000'&gt;.我整晚在棋院都好興奮&lt;/font&gt;，&lt;font color='#cc0000'&gt;我竟然有機會實現，十幾年來的夢想之一&lt;/font&gt;，老師說我有機會上段耶！！！&lt;br/&gt;&lt;br/&gt;&lt;b&gt;這是第一次 感覺到，我把錢拿來花在 "實現自己夢想" 上，好快樂！！！&lt;br/&gt;這是第一次 體會到，老婆以前學鋼琴，說她很快樂，是甚麼滋味...&lt;br/&gt;這是十年來第一次，覺得自己活得很有成就感&lt;/b&gt;...&lt;br/&gt;&lt;br/&gt;快樂的感覺，一直在心中徘迴，老婆大人，謝謝您！&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=914dbd8f-43fc-8ae1-bde1-c531e57bb445' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-2459681251002702830?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/2459681251002702830/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/11/blog-post.html#comment-form' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/2459681251002702830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/2459681251002702830'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/11/blog-post.html' title='意外的快樂'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-3020592227162474880</id><published>2009-11-18T19:33:00.000-08:00</published><updated>2010-03-19T15:55:12.131-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><category scheme='http://www.blogger.com/atom/ns#' term='setup'/><category scheme='http://www.blogger.com/atom/ns#' term='environment'/><title type='text'>Emacs 捲動的設定</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Emacs 內定的捲動方式為一次半頁，這樣看起來跳動很大，有些不習慣。修改 .emacs 加入下面設定，可以變成『自然捲』...&lt;br/&gt;(setq scroll-margin 0 scroll-conservatively 10000 )&lt;br/&gt;&lt;br/&gt;另外，想定義新的 macro 並且紀錄於 .emacs 以供下次使用，可以這樣作，&lt;br/&gt;(以 scroll other window (up/down) one line 這個動作為例) ：&lt;br/&gt;&lt;br/&gt;C-x (      定義新的 macro&lt;br/&gt;M 1 C-M-v   我們的新 command --- scroll other window down one line&lt;br/&gt;C-x )     結束 macro 定義&lt;br/&gt;&lt;br/&gt;給它取一個名字：&lt;br/&gt;M-x name-last-kbd-macro [Enter]&lt;br/&gt;打入自取名稱 ，例如 scroll-other-window-down-one-line [Enter]&lt;br/&gt;&lt;br/&gt;打開 ~/.emacs 準備加入這個新定義：&lt;br/&gt;M-x insert-kbd-macro&lt;br/&gt;打入剛剛取的名稱  scroll-other-window-down-one-line [Enter] 就會出現&lt;br/&gt;(fset 'scroll-other-window-down-one-line&lt;br/&gt;   "\261\226")&lt;br/&gt;然後定義一個 hotkey 例如 F11 給它：&lt;br/&gt;(define-key global-map [f11] 'scroll-other-window-down-one-line)&lt;br/&gt;&lt;br/&gt;以後按 F11 就會 scroll down other window.&lt;br/&gt;&lt;br/&gt;為了對稱，做了一個 scroll other window up one line ，最後在 .emacs 裡長成這樣：&lt;br/&gt;&lt;br/&gt;...&lt;br/&gt;(fset 'scroll-other-window-up-one-line&lt;br/&gt;   "\2551\226")&lt;br/&gt;(define-key global-map [M-f11] 'scroll-other-window-up-one-line)&lt;br/&gt;(fset 'scroll-other-window-down-one-line&lt;br/&gt;   "\261\226")&lt;br/&gt;(define-key global-map [f11] 'scroll-other-window-down-one-line)&lt;br/&gt;...&lt;br/&gt;&lt;br/&gt;Technorati 標籤: &lt;a rel='tag' href='http://technorati.com/tag/emacs' class='performancingtags'&gt;emacs&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=765bdb14-9ae9-88b3-8da6-c4f4e9a20601' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-3020592227162474880?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/3020592227162474880/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/11/emacs.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/3020592227162474880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/3020592227162474880'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/11/emacs.html' title='Emacs 捲動的設定'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-4384775013179016596</id><published>2009-11-13T07:50:00.001-08:00</published><updated>2009-11-24T19:32:03.924-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='install'/><category scheme='http://www.blogger.com/atom/ns#' term='setup'/><category scheme='http://www.blogger.com/atom/ns#' term='environment'/><title type='text'>eclipse + CDT for C++ Development</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;這篇說明 eclipse 的設定，為了怕設定的部份翻譯不好，乾脆用英文寫...&lt;br/&gt;&lt;br/&gt;Since `cscope + ecb + emacs' is my favorite development tool, there is no need for "eclipse", while not all people get used to `emacs' conveniently. Here we introduce another good IDE for C/C++ developemnt --- Eclipse !!&lt;br/&gt;&lt;br/&gt;1. From [ &lt;a href='http://www.eclipse.org/downloads/' target='_blank'&gt;http://www.eclipse.org/downloads/&lt;/a&gt; ] download `Eclipse IDE for Java EE...' or `Eclipse IDE for Java...' or `Eclipse IDE for C/C++...', I download the eclipse-jee-galileo-linux-gtk.tar.gz  , extract,  then add path (where you untar eclipse ) to ~/.bashrc such that when I type `eclipse' command so that it can be brought up (Yes, its green software).&lt;br/&gt;&lt;br/&gt;2. Install the CDT plugin : (If you use `Eclipse IDE for C/C++' , please skip this step)&lt;br/&gt;In eclipse menu, goto (Help | Install New Software ...) then type this html page:&lt;br/&gt;http://download.eclipse.org/tools/cdt/releases/galileo&lt;br/&gt;(note : CDT need &amp;gt; eclipse 3.5 or up )&lt;br/&gt;then update. The CDT component will then be installed.&lt;br/&gt;&lt;br/&gt;3. Create C++ project :&lt;br/&gt;In eclipse menu, goto "File | New | Project...|C++":&lt;br/&gt;   a. Fill "Project Name". &lt;br/&gt;   b. Select Makefile Project | Empty Project.  &lt;font color='#ff0000'&gt;&amp;lt;--- yes, choose `Empty Project' for the external Makefile case !!&lt;/font&gt;&lt;br/&gt;   c. Select Linux GCC at the right side.&lt;br/&gt;   d. Press the "Finish" button.&lt;br/&gt;then you have created an empty project in eclipse.&lt;br/&gt;&lt;br/&gt;4. Import external sources/Makefile to project:&lt;br/&gt;Right click on the project name, select "import...":&lt;br/&gt;choose "General | File System" , click "Next" button, then "browse" to your source path, (of,course, you can filter out unnecessary files ) then press "Finish".&lt;br/&gt;&lt;br/&gt;5. Goto "Project | properties| C/C++ Build", in the right "Build Location" field,&lt;font color='#ff0000'&gt; press the "workspace" button&lt;/font&gt;, and given your project path , for e.g. ${workspace_loc:/test/home/tom/external_open_source}. (&lt;font color='#333300'&gt;I was fooling around here for 6 hours --- before I learn to press the "workspace" button&lt;/font&gt;)&lt;br/&gt;&lt;br/&gt;Then press "OK", the project will be built. But in our `external_open_source' project, we need use `make opt' as the building command ---goto "Project |Proties" , in "C/C++ Build", &lt;br/&gt;a. select the "Behavior" tab, &lt;br/&gt;b. uncheck "Build on resource save(Auot build)", &lt;br/&gt;c. modify "Build (Incremental build)" to "opt", &lt;br/&gt;d. then press "OK" to finish. &lt;br/&gt;&lt;br/&gt;Now, you should build the `external_open_source'  sucessfully, instead of the 'No rule to make target `opt' error message !&lt;br/&gt;&lt;br/&gt;ps. In Debian Lenny, make sure to use &lt;br/&gt;&lt;br/&gt;$update-alternatives --config java&lt;br/&gt;&lt;br/&gt;to configure your default java to `java-6(5)-sun' instead of `java-gcj' , the Eclipse will NOT start with `java-gcj' as the default java environment:&lt;br/&gt;&lt;br/&gt;  Selection    Alternative&lt;br/&gt;-----------------------------------------------&lt;br/&gt;              1    /usr/bin/gij-4.3&lt;br/&gt;              2    /usr/lib/jvm/java-gcj/jre/bin/java&lt;br/&gt;*+          3    /usr/lib/jvm/java-6-sun/jre/bin/java&lt;br/&gt;&lt;br/&gt;Press enter to keep the default[*], or type selection number: 3&lt;br/&gt; &lt;br/&gt;Technorati 標籤: &lt;a rel='tag' href='http://technorati.com/tag/eclipse' class='performancingtags'&gt;eclipse&lt;/a&gt;, &lt;a rel='tag' href='http://technorati.com/tag/CDT' class='performancingtags'&gt;CDT&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=556a58e0-c236-84e4-aedc-e78b02dfbf7c' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-4384775013179016596?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/4384775013179016596/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/11/eclipse-cdt-for-c-development.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/4384775013179016596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/4384775013179016596'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/11/eclipse-cdt-for-c-development.html' title='eclipse + CDT for C++ Development'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-1956102018958725161</id><published>2009-10-16T01:02:00.001-07:00</published><updated>2009-11-17T18:22:38.119-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='setup'/><title type='text'>Tips for setup the android-x86 build system</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Of course , you will find the [&lt;a href='http://www.android-x86.org/getsourcecode'&gt;Android-x86 : Get Source&lt;/a&gt;] site useful..&lt;br/&gt;On a newly install Debian Lenny machine, we may encounter the following situations:.&lt;br/&gt;&lt;br/&gt;1. where is my "repo"?&lt;br/&gt;Ans: the `repo' is not a Debian package, this [&lt;a href='http://source.android.com/download'&gt;Android download&lt;/a&gt;] teach us how to download/setup the `repo' script.&lt;br/&gt;&lt;br/&gt;2.  I want to built-in a module, how to do it ? &lt;br/&gt;Ans: Take DM9601 network card as an example.&lt;br/&gt;First copy my_defconfig under {android-x86}/kernel/arch/x86/configs/android-x86_defconfig, then &lt;br/&gt;modify my_deconfig:&lt;br/&gt;CONFIG_DM9601=y&lt;br/&gt;&lt;br/&gt;Finally following the [&lt;a href='http://www.android-x86.org/documents/customizekernel' target='_blank'&gt;customized kernel&lt;/a&gt;] to build android-x86:&lt;br/&gt;&lt;font color='#000000'&gt;#&amp;gt;&lt;code&gt;make iso_img TARGET_PRODUCT=eeepc TARGET_KERNEL_CONFIG=my_defconfig&lt;/code&gt;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;3. I want to use user account instead of root to build the source, how to do it without problem ?&lt;br/&gt;Ans: During the build, there are 2 commands `e2fsck' `tune2fs' needs root privilege,&lt;br/&gt;now let you user_account can also use them.&lt;br/&gt;under the root:&lt;br/&gt;#&amp;gt; link -s  /sbin/e2fsck  /usr/bin/e2fsck&lt;br/&gt;#&amp;gt; link -s  /sbin/tune2fs  /usr/bin/tune2fs&lt;br/&gt;#&amp;gt; visudo&lt;br/&gt;let user `tom' to use these 2 commands&lt;br/&gt;Cmnd_Alias FS=/sbin/tune2fs,\&lt;br/&gt;       /sbin/e2fsck&lt;br/&gt;tom     ALL=NOPASSWD: FS&lt;br/&gt;&lt;br/&gt;4. During the build, compiler complain about the java , what happened? &lt;br/&gt;Ans: This is probably caused by using the incorrect java compiler...&lt;br/&gt;Please note that Android-1.6 can accept the java-6-sun as its compile environment, use &lt;br/&gt;#&amp;gt;update-java-alternatives -s java-6-sun&lt;br/&gt;to select the compiler environment provided by sun java.&lt;br/&gt;&lt;br/&gt;That's all.Technorati 標籤: &lt;a rel='tag' href='http://technorati.com/tag/android-x86' class='performancingtags'&gt;android-x86&lt;/a&gt;, &lt;a rel='tag' href='http://technorati.com/tag/build%20source' class='performancingtags'&gt;build source&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=9acedcc1-669d-8ede-937b-9f0aa8d00a5d' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-1956102018958725161?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/1956102018958725161/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/10/setup-android-x86-build-system.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/1956102018958725161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/1956102018958725161'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/10/setup-android-x86-build-system.html' title='Tips for setup the android-x86 build system'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-4911391157327153971</id><published>2009-10-15T23:40:00.001-07:00</published><updated>2009-10-15T23:40:19.527-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='new survey'/><title type='text'>The T.38 and open source</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;style type='text/css'&gt; 	 	&lt;/style&gt;  &lt;p&gt;&lt;font face='AR PL UMing HK, serif'&gt;Abstracted from:&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face='AR PL UMing HK, serif'&gt;&lt;a href='http://www.voxgratia.net/blog/archives/2005/08/fax_facts.html'&gt;http://www.voxgratia.net/blog/archives/2005/08/fax_facts.html&lt;/a&gt;&lt;/font&gt;&lt;/p&gt; &lt;p style='margin-bottom: 0cm;'&gt;&lt;font face='AR PL UMing HK, serif'&gt;1.T.38 should not be confused with the similar-sounding T.37 which uses a totally different approach. Whereas T.38 is intended for realtime fax transmision using an encapsulated T.30 data stream, T.37 is intended for "store and forward" applications. It requires the fax data to be converted into TIFF format and then encoded using base64 into a text message and then transmitted using SMTP. &lt;/font&gt; &lt;/p&gt; &lt;p style='margin-bottom: 0cm;'&gt;&lt;br/&gt;&lt;/p&gt; &lt;p style='margin-bottom: 0cm;'&gt;&lt;font face='AR PL UMing HK, serif'&gt;2.T.38 solves most of the problems with sending fax over an IP network. A T.38 fax call uses 20% of the bandwidth than the modulated audio approach because it is now a stream of bits at an average speed of 14400 bps rather than a stream of audio samples at 64000 bps. &lt;/font&gt; &lt;/p&gt; &lt;p style='margin-bottom: 0cm;'&gt;&lt;br/&gt;&lt;/p&gt; &lt;p style='margin-bottom: 0cm;'&gt;&lt;font face='AR PL UMing HK, serif'&gt;3. Asterisk supports T.38 fax pass-through, origination and termination. It does&lt;/font&gt;&lt;/p&gt; &lt;p style='margin-bottom: 0cm;'&gt; &lt;font face='AR PL UMing HK, serif'&gt;not support gateway operation.&lt;/font&gt;&lt;/p&gt; &lt;p style='margin-bottom: 0cm;'&gt;&lt;br/&gt;&lt;/p&gt; &lt;p style='margin-bottom: 0cm;'&gt;&lt;font face='AR PL UMing HK, serif'&gt;4.Asterisk &lt;strong&gt;1.6&lt;/strong&gt; support G.711 and T.38 FAX origination and termination. T.38 gateway features are still in development. &lt;/font&gt; &lt;/p&gt; &lt;p style='margin-bottom: 0cm;'&gt;&lt;br/&gt;&lt;/p&gt; &lt;p style='margin-bottom: 0cm;'&gt;&lt;font face='AR PL UMing HK, serif'&gt;5 more of T.38 open source informations:&lt;/font&gt;&lt;/p&gt; &lt;p style='margin-bottom: 0cm;'&gt;&lt;font face='AR PL UMing HK, serif'&gt;&lt;a href='http://www.voip-info.org/wiki/view/T.38'&gt;http://www.voip-info.org/wiki/view/T.38&lt;/a&gt;&lt;/font&gt;&lt;/p&gt; &lt;p style='margin-bottom: 0cm;'&gt;&lt;br/&gt;&lt;/p&gt; &lt;p style='margin-bottom: 0cm;'&gt;&lt;font face='AR PL UMing HK, serif'&gt;6.more of Asterisk T.38:&lt;/font&gt;&lt;/p&gt; &lt;p style='margin-bottom: 0cm;'&gt;&lt;font face='AR PL UMing HK, serif'&gt;&lt;a href='http://www.voip-info.org/tiki-index.php?page=Asterisk%20T.38'&gt;http://www.voip-info.org/tiki-index.php?page=Asterisk%20T.38&lt;/a&gt;&lt;/font&gt;&lt;/p&gt; &lt;p style='margin-bottom: 0cm;'&gt;&lt;br/&gt;&lt;/p&gt; &lt;p style='margin-bottom: 0cm;'&gt;&lt;font face='AR PL UMing HK, serif'&gt;7.What is &lt;a href='http://www.voip-info.org/wiki/view/T38modem'&gt;T38modem&lt;/a&gt; ? &lt;/font&gt; &lt;/p&gt; &lt;ul&gt;&lt;li&gt;&lt;p style='margin-bottom: 0cm;'&gt;&lt;font face='AR PL UMing HK, serif'&gt;It 	is not a modem. &lt;/font&gt; 	&lt;/p&gt; 	&lt;/li&gt;&lt;li&gt;&lt;p style='margin-bottom: 0cm;'&gt;&lt;font face='AR PL UMing HK, serif'&gt;From 	a FAX application's view point (e.g. HylaFAX) T38modem looks like a 	class 1 FAX modem pool. &lt;/font&gt; 	&lt;/p&gt; 	&lt;/li&gt;&lt;li&gt;&lt;p style='margin-bottom: 0cm;'&gt;&lt;font face='AR PL UMing HK, serif'&gt;From 	an IP network view point it's a H.323 endpoint with T.38 FAX 	support. Recent versions also support SIP. &lt;/font&gt; 	&lt;/p&gt; 	&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;font face='AR PL UMing HK, serif'&gt;From your view point it's 	a gateway between a fax application and an IP network. &lt;/font&gt; 	&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt; &lt;p style='margin-bottom: 0cm;'&gt;&lt;font face='AR PL UMing HK, serif'&gt;8.Open source components:&lt;/font&gt;&lt;/p&gt; &lt;ul&gt;&lt;li&gt;&lt;p style='margin-bottom: 0cm;'&gt;&lt;font face='AR PL UMing HK, serif'&gt;t38modem 	: as the modem pool of Hylafax, t38modem serves as the T.38 gateway 	for the T.38 machine&lt;/font&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt; &lt;ul&gt;&lt;li&gt;&lt;p style='margin-bottom: 0cm;'&gt;&lt;font face='AR PL UMing HK, serif'&gt;asterisk 	: (Fax) machine with T.38 capability, currently, the T.38 gateway 	feature is under development&lt;/font&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt; &lt;p style='margin-bottom: 0cm;'&gt;  &lt;/p&gt; Technorati 標籤: &lt;a rel='tag' href='http://technorati.com/tag/T.38' class='performancingtags'&gt;T.38&lt;/a&gt;, &lt;a rel='tag' href='http://technorati.com/tag/Fax%20over%20IP' class='performancingtags'&gt;Fax over IP&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=ae1dcb55-21de-81ba-9402-fe020fb618ba' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-4911391157327153971?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/4911391157327153971/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/10/t38-and-open-source.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/4911391157327153971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/4911391157327153971'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/10/t38-and-open-source.html' title='The T.38 and open source'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-5348649080590782850</id><published>2009-10-15T07:04:00.001-07:00</published><updated>2009-10-15T07:04:28.385-07:00</updated><title type='text'>珍貴的 quirk check script</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;裝了新機器後，發現需要調校休眠的部份! &lt;br/&gt;驚！平日所依賴的網站[&lt;a href='http://people.freedesktop.org/%7Ehughsient/quirk/quirk-suspend-index.html'&gt;HAL Sleep Quirks&lt;/a&gt;]不見了，在舊機器上找到了以前下載過的 script ，乾脆貼出來，以後可以用...&lt;br/&gt;&lt;br/&gt;#!/bin/sh&lt;br/&gt;##!/bin/sh&lt;br/&gt;#&lt;br/&gt;# SuspendQuirks, copyright Richard Hughes 2007&lt;br/&gt;# created  : 29-07-2007&lt;br/&gt;# modified : 29-07-2007&lt;br/&gt;&lt;br/&gt;# updated: 2007-08-04 Thomas Perl &amp;lt;thp at perli.net&amp;gt;&lt;br/&gt;# Added support for Debian distro, fix for xorg.conf commented-out drivers&lt;br/&gt;&lt;br/&gt;supported_distro=""&lt;br/&gt;unload_modules=""&lt;br/&gt;quirks=""&lt;br/&gt;arch="`uname -i`"&lt;br/&gt;&lt;br/&gt;abort ()&lt;br/&gt;{&lt;br/&gt;    echo "CRITICAL ERROR: $1"&lt;br/&gt;    exit 1&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;warn ()&lt;br/&gt;{&lt;br/&gt;    echo "WARNING: $1"&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;add_quirk ()&lt;br/&gt;{&lt;br/&gt;    quirks="$quirks\npm-suspend $1"&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;add_module ()&lt;br/&gt;{&lt;br/&gt;    if [ -z "$unload_modules" ]; then&lt;br/&gt;        unload_modules="$1"&lt;br/&gt;    else&lt;br/&gt;        unload_modules="$1 $unload_modules"&lt;br/&gt;    fi&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;echo -e "Checking your system...\n"&lt;br/&gt;&lt;br/&gt;#find distro&lt;br/&gt;if [ -e /etc/redhat-release ]; then&lt;br/&gt;    supported_distro="redhat"&lt;br/&gt;fi&lt;br/&gt;if [ -e /etc/mandriva-release ]; then&lt;br/&gt;    supported_distro="mandriva"&lt;br/&gt;fi&lt;br/&gt;if [ -e /etc/debian_version ]; then&lt;br/&gt;        supported_distro="debian"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check distro&lt;br/&gt;if [ -z "$supported_distro" ]; then&lt;br/&gt;    abort "No supported distro"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check quirks are installed&lt;br/&gt;if [ -z "`lshal | grep quirk`" ]; then&lt;br/&gt;    warn "You have no quirks!"&lt;br/&gt;    #IBM&lt;br/&gt;    if [ "`hal-get-property --udi /org/freedesktop/Hal/devices/computer --key system.hardware.vendor`" = "IBM" ]; then&lt;br/&gt;        add_quirk "--quirk-s3-bios --quirk-s3-mode"&lt;br/&gt;    fi&lt;br/&gt;    #LENOVO&lt;br/&gt;    if [ "`hal-get-property --udi /org/freedesktop/Hal/devices/computer --key system.hardware.vendor`" = "LENOVO" ]; then&lt;br/&gt;        add_quirk "--quirk-s3-bios --quirk-s3-mode"&lt;br/&gt;    fi&lt;br/&gt;    #Intel&lt;br/&gt;    if [ -n "`cat /etc/X11/xorg.conf | grep intel`" ]; then&lt;br/&gt;        add_quirk "--quirk-vbemode-restore"&lt;br/&gt;        add_quirk "--quirk-vbe-post"&lt;br/&gt;    fi&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check kernel capabilities&lt;br/&gt;if [ -n "`uname -r | grep 3194`" ]; then&lt;br/&gt;    abort "Do not use the default Fedora 7 GOLD kernel. It's broken. Use a kernel from updates!"&lt;br/&gt;fi&lt;br/&gt;if [ -n "`uname -r | grep xen`" ]; then&lt;br/&gt;    abort "Do not use a XEN kernel. It will not suspend!"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check kernel capabilities&lt;br/&gt;if [ -z "`cat /sys/power/state | grep mem`" ]; then&lt;br/&gt;    abort "Kernel does not support suspend!"&lt;br/&gt;fi&lt;br/&gt;if [ -z "`cat /sys/power/state | grep disk`" ]; then&lt;br/&gt;    warn "Kernel does not support hibernate!"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check pm-utils is correct arch&lt;br/&gt;if [ $arch = "i386" ]; then&lt;br/&gt;    if [ -n "`rpm -q pm-utils | grep athlon`" ]; then&lt;br/&gt;        abort "pm-utils is the wrong arch!"&lt;br/&gt;    fi&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check HAL has got the right value&lt;br/&gt;if [ "hal-get-property --udi /org/freedesktop/Hal/devices/computer --key power_management.can_suspend" = "false" ]; then&lt;br/&gt;    abort "HAL does not detect suspend!"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for no consolekit in GNOME&lt;br/&gt;if [ -n "`ps aux | grep gnome-session | grep -v grep`" ]; then&lt;br/&gt;    if [ -z "`ps aux | grep console-kit-daemon | grep -v grep`" ];then&lt;br/&gt;        abort "ConsoleKit is not running. Suggest 'chkconfig ConsoleKit on' and reboot" &lt;br/&gt;    fi&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for nvidia binary graphics&lt;br/&gt;if [ -n "`cat /etc/X11/xorg.conf | grep '^\s*[^#]*nvidia'`" ]; then&lt;br/&gt;    abort "Using nvidia binary driver. This is not supported!"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for ati binary graphics&lt;br/&gt;if [ -n "`cat /etc/X11/xorg.conf | grep '^\s*[^#]*fglrx'`" ]; then&lt;br/&gt;    abort "Using ATI binary driver. This is not supported!"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for old intel graphics&lt;br/&gt;if [ -n "`cat /etc/X11/xorg.conf | grep '^\s*[^#]*i810'`" ]; then&lt;br/&gt;    abort "Using old 'i810' non-modesetting intel driver. Try using 'intel' driver!"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for broadcom networking&lt;br/&gt;if [ -n "`/sbin/lsmod | grep b44`" ]; then&lt;br/&gt;    add_module "b44"&lt;br/&gt;    warn "Using broadcom network driver."&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for ndiswrapper&lt;br/&gt;if [ -n "`/sbin/lsmod | grep ndiswrapper`" ]; then&lt;br/&gt;    add_module "ndiswrapper"&lt;br/&gt;    warn "Using ndiswrapper network driver."&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for 915resolution&lt;br/&gt;if [ -e /usr/bin/915resolution ]; then&lt;br/&gt;    warn "Do not use 915resolution with the new intel driver!"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for suspend&lt;br/&gt;if [ -e /usr/bin/suspend ]; then&lt;br/&gt;    abort "Do not use suspend2, it's unsupported!"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for old intel networking&lt;br/&gt;if [ -n "`ps aux | grep ipw3945 | grep -v grep`" ]; then&lt;br/&gt;    abort "Use the mac80211 based iwl3945 driver instead. ipw3945d is closed source sometimes hangs on resume."&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for iwl3945&lt;br/&gt;if [ -n "`/sbin/lsmod | grep iwl3945`" ]; then&lt;br/&gt;    add_module "iwl3945"&lt;br/&gt;    warn "iwl3945 is usually okay for suspend - but it might be worth trying unloading it."&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for kvm&lt;br/&gt;if [ -n "`/sbin/lsmod | grep kvm`" ]; then&lt;br/&gt;    add_module "kvm"&lt;br/&gt;    warn "KVM will not suspend in kernels less than 2.6.23, but should work okay in later kernels."&lt;br/&gt;fi&lt;br/&gt;if [ -n "`/sbin/lsmod | grep kvm_intel`" ]; then&lt;br/&gt;    add_module "kvm_intel"&lt;br/&gt;fi&lt;br/&gt;if [ -n "`/sbin/lsmod | grep kvm_athlon`" ]; then&lt;br/&gt;    add_module "kvm_athlon"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;echo&lt;br/&gt;&lt;br/&gt;if [ -z "$unload_modules" ] &amp;amp;&amp;amp; [ -z "$quirks" ]; then&lt;br/&gt;    echo "Suspend should work!"&lt;br/&gt;else&lt;br/&gt;    echo "Suggestions:"&lt;br/&gt;    echo&lt;br/&gt;    if [ -n "$unload_modules" ]; then&lt;br/&gt;        echo -e "Add 'SUSPEND_MODULES=\"$unload_modules\"' to /etc/pm/config.d/unload_modules!\n"&lt;br/&gt;    fi&lt;br/&gt;    if [ -n "$quirks" ]; then&lt;br/&gt;        echo -n "You might want to try the following pm-suspend entries:"&lt;br/&gt;        echo -e $quirks&lt;br/&gt;    fi&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;echo&lt;br/&gt;&lt;br/&gt;exit 0&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;# SuspendQuirks, copyright Richard Hughes 2007&lt;br/&gt;# created  : 29-07-2007&lt;br/&gt;# modified : 29-07-2007&lt;br/&gt;&lt;br/&gt;# updated: 2007-08-04 Thomas Perl &amp;lt;thp at perli.net&amp;gt;&lt;br/&gt;# Added support for Debian distro, fix for xorg.conf commented-out drivers&lt;br/&gt;&lt;br/&gt;supported_distro=""&lt;br/&gt;unload_modules=""&lt;br/&gt;quirks=""&lt;br/&gt;arch="`uname -i`"&lt;br/&gt;&lt;br/&gt;abort ()&lt;br/&gt;{&lt;br/&gt;    echo "CRITICAL ERROR: $1"&lt;br/&gt;    exit 1&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;warn ()&lt;br/&gt;{&lt;br/&gt;    echo "WARNING: $1"&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;add_quirk ()&lt;br/&gt;{&lt;br/&gt;    quirks="$quirks\npm-suspend $1"&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;add_module ()&lt;br/&gt;{&lt;br/&gt;    if [ -z "$unload_modules" ]; then&lt;br/&gt;        unload_modules="$1"&lt;br/&gt;    else&lt;br/&gt;        unload_modules="$1 $unload_modules"&lt;br/&gt;    fi&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;echo -e "Checking your system...\n"&lt;br/&gt;&lt;br/&gt;#find distro&lt;br/&gt;if [ -e /etc/redhat-release ]; then&lt;br/&gt;    supported_distro="redhat"&lt;br/&gt;fi&lt;br/&gt;if [ -e /etc/mandriva-release ]; then&lt;br/&gt;    supported_distro="mandriva"&lt;br/&gt;fi&lt;br/&gt;if [ -e /etc/debian_version ]; then&lt;br/&gt;        supported_distro="debian"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check distro&lt;br/&gt;if [ -z "$supported_distro" ]; then&lt;br/&gt;    abort "No supported distro"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check quirks are installed&lt;br/&gt;if [ -z "`lshal | grep quirk`" ]; then&lt;br/&gt;    warn "You have no quirks!"&lt;br/&gt;    #IBM&lt;br/&gt;    if [ "`hal-get-property --udi /org/freedesktop/Hal/devices/computer --key system.hardware.vendor`" = "IBM" ]; then&lt;br/&gt;        add_quirk "--quirk-s3-bios --quirk-s3-mode"&lt;br/&gt;    fi&lt;br/&gt;    #LENOVO&lt;br/&gt;    if [ "`hal-get-property --udi /org/freedesktop/Hal/devices/computer --key system.hardware.vendor`" = "LENOVO" ]; then&lt;br/&gt;        add_quirk "--quirk-s3-bios --quirk-s3-mode"&lt;br/&gt;    fi&lt;br/&gt;    #Intel&lt;br/&gt;    if [ -n "`cat /etc/X11/xorg.conf | grep intel`" ]; then&lt;br/&gt;        add_quirk "--quirk-vbemode-restore"&lt;br/&gt;        add_quirk "--quirk-vbe-post"&lt;br/&gt;    fi&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check kernel capabilities&lt;br/&gt;if [ -n "`uname -r | grep 3194`" ]; then&lt;br/&gt;    abort "Do not use the default Fedora 7 GOLD kernel. It's broken. Use a kernel from updates!"&lt;br/&gt;fi&lt;br/&gt;if [ -n "`uname -r | grep xen`" ]; then&lt;br/&gt;    abort "Do not use a XEN kernel. It will not suspend!"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check kernel capabilities&lt;br/&gt;if [ -z "`cat /sys/power/state | grep mem`" ]; then&lt;br/&gt;    abort "Kernel does not support suspend!"&lt;br/&gt;fi&lt;br/&gt;if [ -z "`cat /sys/power/state | grep disk`" ]; then&lt;br/&gt;    warn "Kernel does not support hibernate!"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check pm-utils is correct arch&lt;br/&gt;if [ $arch = "i386" ]; then&lt;br/&gt;    if [ -n "`rpm -q pm-utils | grep athlon`" ]; then&lt;br/&gt;        abort "pm-utils is the wrong arch!"&lt;br/&gt;    fi&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check HAL has got the right value&lt;br/&gt;if [ "hal-get-property --udi /org/freedesktop/Hal/devices/computer --key power_management.can_suspend" = "false" ]; then&lt;br/&gt;    abort "HAL does not detect suspend!"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for no consolekit in GNOME&lt;br/&gt;if [ -n "`ps aux | grep gnome-session | grep -v grep`" ]; then&lt;br/&gt;    if [ -z "`ps aux | grep console-kit-daemon | grep -v grep`" ];then&lt;br/&gt;        abort "ConsoleKit is not running. Suggest 'chkconfig ConsoleKit on' and reboot" &lt;br/&gt;    fi&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for nvidia binary graphics&lt;br/&gt;if [ -n "`cat /etc/X11/xorg.conf | grep '^\s*[^#]*nvidia'`" ]; then&lt;br/&gt;    abort "Using nvidia binary driver. This is not supported!"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for ati binary graphics&lt;br/&gt;if [ -n "`cat /etc/X11/xorg.conf | grep '^\s*[^#]*fglrx'`" ]; then&lt;br/&gt;    abort "Using ATI binary driver. This is not supported!"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for old intel graphics&lt;br/&gt;if [ -n "`cat /etc/X11/xorg.conf | grep '^\s*[^#]*i810'`" ]; then&lt;br/&gt;    abort "Using old 'i810' non-modesetting intel driver. Try using 'intel' driver!"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for broadcom networking&lt;br/&gt;if [ -n "`/sbin/lsmod | grep b44`" ]; then&lt;br/&gt;    add_module "b44"&lt;br/&gt;    warn "Using broadcom network driver."&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for ndiswrapper&lt;br/&gt;if [ -n "`/sbin/lsmod | grep ndiswrapper`" ]; then&lt;br/&gt;    add_module "ndiswrapper"&lt;br/&gt;    warn "Using ndiswrapper network driver."&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for 915resolution&lt;br/&gt;if [ -e /usr/bin/915resolution ]; then&lt;br/&gt;    warn "Do not use 915resolution with the new intel driver!"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for suspend&lt;br/&gt;if [ -e /usr/bin/suspend ]; then&lt;br/&gt;    abort "Do not use suspend2, it's unsupported!"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for old intel networking&lt;br/&gt;if [ -n "`ps aux | grep ipw3945 | grep -v grep`" ]; then&lt;br/&gt;    abort "Use the mac80211 based iwl3945 driver instead. ipw3945d is closed source sometimes hangs on resume."&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for iwl3945&lt;br/&gt;if [ -n "`/sbin/lsmod | grep iwl3945`" ]; then&lt;br/&gt;    add_module "iwl3945"&lt;br/&gt;    warn "iwl3945 is usually okay for suspend - but it might be worth trying unloading it."&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;#check for kvm&lt;br/&gt;if [ -n "`/sbin/lsmod | grep kvm`" ]; then&lt;br/&gt;    add_module "kvm"&lt;br/&gt;    warn "KVM will not suspend in kernels less than 2.6.23, but should work okay in later kernels."&lt;br/&gt;fi&lt;br/&gt;if [ -n "`/sbin/lsmod | grep kvm_intel`" ]; then&lt;br/&gt;    add_module "kvm_intel"&lt;br/&gt;fi&lt;br/&gt;if [ -n "`/sbin/lsmod | grep kvm_athlon`" ]; then&lt;br/&gt;    add_module "kvm_athlon"&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;echo&lt;br/&gt;&lt;br/&gt;if [ -z "$unload_modules" ] &amp;amp;&amp;amp; [ -z "$quirks" ]; then&lt;br/&gt;    echo "Suspend should work!"&lt;br/&gt;else&lt;br/&gt;    echo "Suggestions:"&lt;br/&gt;    echo&lt;br/&gt;    if [ -n "$unload_modules" ]; then&lt;br/&gt;        echo -e "Add 'SUSPEND_MODULES=\"$unload_modules\"' to /etc/pm/config.d/unload_modules!\n"&lt;br/&gt;    fi&lt;br/&gt;    if [ -n "$quirks" ]; then&lt;br/&gt;        echo -n "You might want to try the following pm-suspend entries:"&lt;br/&gt;        echo -e $quirks&lt;br/&gt;    fi&lt;br/&gt;fi&lt;br/&gt;&lt;br/&gt;echo&lt;br/&gt;&lt;br/&gt;exit 0&lt;br/&gt;&lt;br/&gt;這是個都不確定的年代，保留著的這份 script 彌足珍貴&lt;br/&gt;標籤: &lt;a rel='tag' href='http://technorati.com/tag/quirk' class='performancingtags'&gt;quirk&lt;/a&gt;, &lt;a rel='tag' href='http://technorati.com/tag/suspend' class='performancingtags'&gt;suspend&lt;/a&gt;, &lt;a rel='tag' href='http://technorati.com/tag/resume' class='performancingtags'&gt;resume&lt;/a&gt;, &lt;a rel='tag' href='http://technorati.com/tag/script' class='performancingtags'&gt;script&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=fe4f3a1f-f1c3-8180-8448-ca8ce7274514' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-5348649080590782850?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/5348649080590782850/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/10/quirk-check-script_251.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/5348649080590782850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/5348649080590782850'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/10/quirk-check-script_251.html' title='珍貴的 quirk check script'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-9138260818023711098</id><published>2009-09-14T00:27:00.001-07:00</published><updated>2009-09-15T23:20:17.659-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='environment'/><title type='text'>Suspend, Hibernate and Resume 的問題</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;這類問題因為 BIOS , H/W 每台機器不一樣，可能出問題的部份不一定相同，通常這樣的問題很難有系統的方式去了解原因。&lt;br/&gt;但是這個 [&lt;a href='http://people.freedesktop.org/%7Ehughsient/quirk/quirk-suspend-index.html'&gt;HAL Sleep Quirks&lt;/a&gt;] 網站提供了一個偵測的 script ，幫助我們有系統的釐清原因。&lt;br/&gt;&lt;br/&gt;以下紀錄以 Asus A8J 遇到的現象和解決的步驟：&lt;br/&gt;&lt;br/&gt;安裝 Debian Lenny 後，從 Gnome 選單 |  關機 | 暫停 後，Resume 時會失敗，但是可以從遠端 ssh 回來，所以可能跟顯卡有關...&lt;br/&gt;執行網站上所下載的 quirk-checker.sh ，建議把 iwl3945 無線網路模組先unload，等到 resume 後再 reload，所以 在 /etc/pm/config.d/unload_modules 加上這行：SUSPEND_MODULES="iwl3945"&lt;br/&gt;但這應該不是原因，再進行一次 suspend，還是無法 resume.&lt;br/&gt;&lt;br/&gt;研讀 pm-suspend 的參數說明，發現 --quirk-vbe-post 表示 resume 時可以用 bios 相同方式來 reset graphic device 所以試試看：&lt;br/&gt;以 pm-suspend --quirk-post-vbe 來試驗，果然可以正常恢復...&lt;br/&gt;&lt;br/&gt;現在修改 /usr/share/hal/fdi/information/10freedesktop 下的檔案.... 最有關的應該是 20-video-quirk-pm-asus.fdi :&lt;br/&gt;由 lshal 指令得到，我們的機器&lt;b&gt; &lt;font color='#ff0000'&gt;system.hardware.product=A8JP&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;&lt;match prefix_outof='A6M;Z84F;&amp;lt;font color=&amp;apos;#ff0000&amp;apos;&amp;gt;&amp;lt;b&amp;gt;A8JP&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;' key='system.hardware.product'&gt;找到這一段：&lt;br/&gt;&lt;merge type='bool' key='power_management.quirk.vbe_post'&gt;      &amp;lt;match key="system.hardware.product" prefix_outof="A6M;Z84F"&amp;gt;&lt;br/&gt;&lt;font color='#000000'&gt;        &lt;/font&gt;&lt;font color='#000000'&gt;&amp;lt;merge key="power_management.quirk.vbe_post" type="bool"&amp;gt;true&amp;lt;/merge&amp;gt;&lt;/font&gt;&lt;br/&gt;      &amp;lt;/match&amp;gt;&lt;br/&gt;&lt;br/&gt;改為：&lt;br/&gt;&lt;/merge&gt;&lt;/match&gt;      &amp;lt;match key="system.hardware.product" prefix_outof="A6M;Z84F;&lt;b&gt;&lt;font color='#ff0000'&gt;A8JP&lt;/font&gt;&lt;/b&gt;"&amp;gt;&lt;br/&gt;&lt;font color='#000000'&gt;        &lt;/font&gt;&lt;font color='#000000'&gt;&amp;lt;merge key="power_management.quirk.vbe_post" type="bool"&amp;gt;true&amp;lt;/merge&amp;gt;&lt;/font&gt;&lt;br/&gt;      &amp;lt;/match&amp;gt;&lt;match prefix_outof='A6M;Z84F;&amp;lt;font color=&amp;apos;#ff0000&amp;apos;&amp;gt;&amp;lt;b&amp;gt;A8JP&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;' key='system.hardware.product'&gt;&lt;merge type='bool' key='power_management.quirk.vbe_post'&gt;&lt;br/&gt;      &lt;/merge&gt;&lt;br/&gt;如同紅色粗體這樣加入我們的 product ，表示我們要使用 --quirk-vbe-post 的參數即可&lt;br/&gt;改完後，重新啟動 hal :&lt;br/&gt;#&amp;gt; /etc/init.d/hal restart&lt;br/&gt;現在透過 gnome-power-management 進行 suspend, hibernate 都可以正常 resume 回來了。真高興！&lt;br/&gt;Technorati 標籤: &lt;a class='performancingtags' href='http://technorati.com/tag/suspend%20hibernate%20resume%20power-management' rel='tag'&gt;suspend hibernate resume power-management&lt;/a&gt;&lt;/match&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=f1dff10b-14c8-8433-9406-6f2c96bfd584' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-9138260818023711098?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/9138260818023711098/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/09/suspend-hibernate-and-resume.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/9138260818023711098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/9138260818023711098'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/09/suspend-hibernate-and-resume.html' title='Suspend, Hibernate and Resume 的問題'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-8899269299919160322</id><published>2009-09-03T22:53:00.001-07:00</published><updated>2009-09-07T22:45:56.373-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>kernel 隨手記 --- 類似 oops 的系統訊息</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;void __this_fixmap_does_not_exist(void)&lt;br/&gt;{&lt;br/&gt;    WARN_ON(1);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;在 kernel 裡看到這樣的程式碼，用在哪裡呢？&lt;br/&gt;static __always_inline unsigned long fix_to_virt(const unsigned int idx)&lt;br/&gt;{&lt;br/&gt;    if (idx &amp;gt;= __end_of_fixed_addresses)&lt;br/&gt;        __this_fixmap_does_not_exist();&lt;br/&gt;&lt;br/&gt;    return __fix_to_virt(idx);&lt;br/&gt;}&lt;br/&gt;(這裡為了精簡，把註解給拿掉了。)這是不希望發生 if 為真的情形，那如果發生了，就印出像 oops 的狀態，以方便偵錯！所以關鍵在 WARN_ON(1)，往下追蹤，發現呼叫到 warn_on_slowpath(__FILE__,__LINE__) 來處理，裡面用了幾個好用的技巧：&lt;br/&gt;1.  __builtin_return_address(0) 請 compiler 找出現在 function 的 return address。&lt;br/&gt;2  sprint_symbol() 可以幫忙找出 symbol name , dump_stack() 可以列印現在的 stack 。 &lt;br/&gt;3  這個 WARN_ON() 不像 panic() 會中止系統，理論上，可以用來印出發生問題時的 kernel 狀態 ! 或許在開發 driver 可以用來除錯&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=06a9e384-39e4-8feb-815a-2fc28aadc85d' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-8899269299919160322?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/8899269299919160322/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/09/kernel-oops.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/8899269299919160322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/8899269299919160322'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/09/kernel-oops.html' title='kernel 隨手記 --- 類似 oops 的系統訊息'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-59823306708299895</id><published>2009-08-28T01:26:00.001-07:00</published><updated>2009-09-15T20:44:41.157-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='install'/><category scheme='http://www.blogger.com/atom/ns#' term='setup'/><title type='text'>使用 debootstrap 安裝 Debian 於 USB 大拇哥</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;網路上相關文章很多，但是多半有"手工"打許多指令的步驟，不適合懶人使用。&lt;br/&gt;[&lt;a href='http://wiki.flimzy.com/index.php/Install_Debian_on_USB' target='_blank'&gt; Install Debian on USB&lt;/a&gt; ]這篇Wiki前半部直到 Configure Locales 的部份做完，寫得很簡明，接下來是該作者自己的 Casper package 安裝，就不用再繼續 follow up 了。&lt;br/&gt;&lt;br/&gt;所以歸納一下步驟如下：&lt;br/&gt;1.  準備好 partition 以安裝 debian。這視個人的大拇哥規劃而定，以下假設裝在 /dev/sdb2（sda 是本機上的硬碟)&lt;br/&gt;以下用 /dev/sd{D}{N} 表示，請自行代換之。&lt;br/&gt;&lt;br/&gt;2.  準備好檔案系統 ，並且 mount 到 /mnt&lt;br/&gt;#&amp;gt; mkfs.ext3 /dev/sd{D}{N}&lt;br/&gt;#&amp;gt; mount /dev/sd{D}{N} /mnt&lt;br/&gt;&lt;br/&gt;3.   重頭戲來了，從 /etc/apt/sources.list 找一個 mirror site 這裡用 http://debian.nctu.edu.tw/debian/ (要含有斜線)&lt;br/&gt;#&amp;gt; debootstrap lenny /mnt http://debian.nctu.edu.tw/debian/&lt;br/&gt;     接下來會一直抓 package 來安裝，泡盃咖啡去...&lt;br/&gt;&lt;br/&gt;4   準備兩個設定檔，一個在裝 kernel 時會用到，另一個是 sources.list，可以直接使用 host 的 /etc/apt/sources.list &lt;br/&gt;#&amp;gt; mkdir -p /mnt/etc/apt&lt;br/&gt;#&amp;gt; echo "do_initrd=yes" &amp;gt; /mnt/etc/kernel-img.conf&lt;br/&gt;#&amp;gt; cp /etc/apt/sources.list  /mnt/etc/apt/&lt;br/&gt;&lt;br/&gt;5   準備 fstab 給新系統 (/etc/inittab 則不需煩惱，debootstrap 會 setup inittab)&lt;br/&gt;#&amp;gt; echo "/dev/sd{D}{N}  /  ext3  defaults,errors=remount-ro 0" &amp;gt; /mnt/etc/fstab&lt;br/&gt;#&amp;gt; echo "proc /mnt/proc  proc  none 0 0" &amp;gt;&amp;gt; /mnt/etc/fstab&lt;br/&gt;#&amp;gt; mount proc /mnt/proc  -t  proc&lt;br/&gt;&lt;br/&gt;6   接下來用 chroot 切換到新的系統去，&lt;br/&gt;#&amp;gt; chroot /mnt&lt;br/&gt;&lt;font color='#000099'&gt;請注意：經過這步驟，接下來，所有的指令都是下給新系統的了！&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;7   先設定好 locale 並且把從 host 繼承的 locale 先設空&lt;br/&gt;#&amp;gt; apt-get update&lt;br/&gt;#&amp;gt; apt-get install locales&lt;br/&gt;#&amp;gt; dpkg-reconfigure locales&lt;br/&gt;#&amp;gt; export LANG=&lt;br/&gt;#&amp;gt; export LANGUAGE=&lt;br/&gt;localepurge 是個可裝可不裝的套件，若要省空間，可以這時候裝起來&lt;br/&gt;#&amp;gt; apt-get install localepurge&lt;br/&gt;將來裝套件時 localepurge 可幫忙 free 一些不需要的 locales 資料&lt;br/&gt;&lt;br/&gt;8   然後安裝 kernel image，遇到問題都選 y&lt;br/&gt;#&amp;gt; apt-get install linux-image-2.6.26-2-686&lt;br/&gt;&lt;br/&gt;9 裝 grub package&lt;br/&gt;#&amp;gt; apt-get install grub&lt;br/&gt;&lt;br/&gt;10 將 grub 裝到 MBR :&lt;br/&gt;#&amp;gt; exit&lt;br/&gt;&lt;font color='#000099'&gt;請注意：接下來，我們又回到 host 了！&lt;/font&gt;&lt;br/&gt;#&amp;gt; grub-install --root-directory=/mnt --no-floppy --recheck /dev/sd{D}&lt;br/&gt;#&amp;gt; cat &amp;gt; /mnt/boot/grub/menu.lst &amp;lt;&amp;lt; EOF&lt;br/&gt;title        Debian GNU/Linux, kernel 2.6.26-2-686&lt;br/&gt;root        (&lt;font color='#ff0000'&gt;hd0,1&lt;/font&gt;)&lt;br/&gt;kernel        /boot/vmlinuz-2.6.26-2-686 root=/dev/sd{D}{N} ro &lt;br/&gt;initrd        /boot/initrd.img-2.6.26-2-686&lt;br/&gt;EOF&lt;br/&gt;這裡把 (hd1,1) 換成了 (hd0,1)  。因為若是用  usb 開機的話，grub 把大拇哥當第一顆硬碟 (hd0)， 直到進了 kernel 才又跟 host 所認知的一樣---回到 sdb。&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;11 打完收工&lt;br/&gt;#&amp;gt; umount /mnt/proc&lt;br/&gt;#&amp;gt; umount /mnt&lt;br/&gt;&lt;br/&gt;這樣就有一個可用的 Debian on USB 了！&lt;br/&gt;後記：grub 安裝時，如果抱怨找不到 grub drive 或 stage1 的問題，[&lt;a href='http://ubuntuforums.org/showthread.php?t=224351'&gt;這裡&lt;/a&gt;]有解答&lt;br/&gt;Technorati 標籤: &lt;a class='performancingtags' href='http://technorati.com/tag/install' rel='tag'&gt;install&lt;/a&gt;, &lt;a class='performancingtags' href='http://technorati.com/tag/setup' rel='tag'&gt;setup&lt;/a&gt;, &lt;a class='performancingtags' href='http://technorati.com/tag/debootstrap' rel='tag'&gt;debootstrap&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=baa72be8-8dc4-822c-85a0-015eb45343d2' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-59823306708299895?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/59823306708299895/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/08/debootstrap-debian-usb.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/59823306708299895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/59823306708299895'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/08/debootstrap-debian-usb.html' title='使用 debootstrap 安裝 Debian 於 USB 大拇哥'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-3213725285875820989</id><published>2009-08-24T20:51:00.001-07:00</published><updated>2009-08-24T20:51:32.533-07:00</updated><title type='text'>serial port 測試 driver 讀不到 data!</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;span class='postbody'&gt;這一段是在摩托的問題，後來自行解決了，貼過來&lt;br/&gt;&lt;br/&gt;在 2.6.28 下，把 CONFIG_SERIAL_8250 = m （可以卸載) ，kernel 重編安裝後開機 &lt;br/&gt;開機後有看到 ttyS0 硬體存在: &lt;br/&gt;00:0c: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A &lt;br/&gt;然後把 8250_pnp, 8250, serial_core 卸載， &lt;br/&gt;看到卸載訊息: &lt;br/&gt;serial 00:0c: disabled &lt;br/&gt;現在載入自己的測試 driver ，起始部份長這樣: &lt;br/&gt; &lt;br/&gt;static int __init modem_init(void) &lt;br/&gt;{ &lt;br/&gt;        int ret; &lt;br/&gt; &lt;br/&gt;        printk("modem_init()\n"); &lt;br/&gt;        if (!request_region(MODEM_IO_BASE , 8, "serial")) &lt;br/&gt;                ret = -EBUSY; &lt;br/&gt;         &lt;br/&gt;        printk("MSR = %x\n", inb(MSR)); &lt;br/&gt;        printk("IER =0x%X \n", inb(IER)); &lt;br/&gt;... &lt;br/&gt;} &lt;br/&gt; &lt;br/&gt;載入後 request_region() 成功，但是之後讀到的 register 值都是 0xFF &lt;br/&gt;找過 8250.c 很多地方，都沒頭緒，為何 kernel 的 8250 driver 可以動，自己的測試 driver 就讀不到 port data ?&lt;br/&gt;================================================================&lt;br/&gt;&lt;/span&gt;&lt;span class='postbody'&gt;解決了，在此把原因整理一下，以後有人遇到這種問題不用卡在這裡～～ 以下是參考kernel version 2.6.28 所得的結果。 &lt;br/&gt;若只把 kernel 的 8250.ko 模組載入，該模組一樣無法讀到 serial port， &lt;br/&gt;必須一起載入 8250_pnp.ko 才可以，所以關鍵就在 8250_pnp.c 裡面---&amp;gt; &lt;br/&gt;從 serial8250_pnp_init() 開始追...有一天會呼叫到 pnp_start_dev()，這裡面呼叫了pnp_acpi_set_resources() 然後進入一大包的 ACPI 的動作（至此無力再繼續，希望後續動作有高手指點...）， &lt;br/&gt;&lt;br/&gt;&lt;div id='__ss_1902453' style='width: 477px; text-align: left;'&gt;&lt;a title='Serial Pnp' href='http://www.slideshare.net/tomjpsun/serial-pnp' style='margin: 12px 0pt 3px; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; display: block; text-decoration: underline;'&gt;Serial Pnp&lt;/a&gt;&lt;div class='youtube-video'&gt;&lt;object width='477' height='510' style='margin: 0px;'&gt;&lt;param value='http://static.slidesharecdn.com/swf/ssplayerd.swf?doc=serialpnp-090824224335-phpapp01&amp;amp;stripped_title=serial-pnp' name='movie'&gt; &lt;/param&gt;&lt;param value='true' name='allowFullScreen'&gt; &lt;/param&gt;&lt;param value='always' name='allowScriptAccess'&gt; &lt;/param&gt;&lt;embed width='477' height='510' allowfullscreen='true' allowscriptaccess='always' type='application/x-shockwave-flash' src='http://static.slidesharecdn.com/swf/ssplayerd.swf?doc=serialpnp-090824224335-phpapp01&amp;amp;stripped_title=serial-pnp'&gt; &lt;/embed&gt;  &lt;/object&gt;&lt;/div&gt;&lt;div style='font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;'&gt;View more &lt;a href='http://www.slideshare.net/' style='text-decoration: underline;'&gt;documents&lt;/a&gt; from &lt;a href='http://www.slideshare.net/tomjpsun' style='text-decoration: underline;'&gt;tomjpsun&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;br/&gt;&lt;br/&gt;ok，拉回來 pnp_start_dev() 這邊，繼續會印出  &lt;br/&gt;"serial 00:06 activated" ，其中數字是 bus 編號，每台機器不盡相同。 &lt;br/&gt;經過了這步驟(pnp_acpi_set_resources())，ACPI 幫你打開 port 了，就可以用了（～～竟然跟 ACPI 有關耶，所以在 embedded 環境下，若是 ACPI 不管這裡的話，就不會有開版所提的問題產生了） &lt;br/&gt; &lt;br/&gt;實驗：把之前的 test driver 模仿 8250_pnp.c 的作法，宣告一個 pnp_device_id table &amp;amp; pnp_driver ： &lt;br/&gt; &lt;br/&gt;static const struct pnp_device_id pnp_dev_table[] = { &lt;br/&gt;        {       "ANYDEVS",              0       }, &lt;br/&gt;        {       "",                     0       } &lt;br/&gt;}; &lt;br/&gt; &lt;br/&gt; &lt;br/&gt;static struct pnp_driver test_pnp_driver = { &lt;br/&gt;        .name           = "serial", &lt;br/&gt;        .probe          = test_pnp_probe, &lt;br/&gt;        .remove         = __devexit_p(test_pnp_remove), &lt;br/&gt;        .id_table       = pnp_dev_table, &lt;br/&gt;}; &lt;br/&gt; &lt;br/&gt;這裡用 "ANYDEVS" 是要讓 device probe 的過程中 match_device() 能夠成功，match 成功後，pnp 系統才會呼叫我們的 test_pnp_probe() ，此時的 serial port 已經被 ACPI enable 了。 &lt;br/&gt;所以在這裡面開始使用 serial port 就沒問題了。 &lt;br/&gt; &lt;br/&gt;到這裡可告一個段落，只是後續的疑問是：ACPI 到底用甚麼方式來 enable serial port 呢？有待各位大大的指點了...&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=08ab5697-9a6b-888e-b224-5fa6d3e999b7' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-3213725285875820989?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/3213725285875820989/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/08/serial-port-driver-data.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/3213725285875820989'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/3213725285875820989'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/08/serial-port-driver-data.html' title='serial port 測試 driver 讀不到 data!'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-6483079249267760361</id><published>2009-08-04T22:54:00.001-07:00</published><updated>2009-08-04T22:54:29.259-07:00</updated><title type='text'>buildroot-2009.05 config file</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;#&lt;br/&gt;# Automatically generated make config: don't edit&lt;br/&gt;# Tue Jun  9 19:35:42 2009&lt;br/&gt;#&lt;br/&gt;BR2_HAVE_DOT_CONFIG=y&lt;br/&gt;BR2_VERSION="2009.05"&lt;br/&gt;# BR2_alpha is not set&lt;br/&gt;BR2_arm=y&lt;br/&gt;# BR2_armeb is not set&lt;br/&gt;# BR2_avr32 is not set&lt;br/&gt;# BR2_cris is not set&lt;br/&gt;# BR2_ia64 is not set&lt;br/&gt;# BR2_i386 is not set&lt;br/&gt;# BR2_m68k is not set&lt;br/&gt;# BR2_mips is not set&lt;br/&gt;# BR2_mipsel is not set&lt;br/&gt;# BR2_nios2 is not set&lt;br/&gt;# BR2_powerpc is not set&lt;br/&gt;# BR2_sh is not set&lt;br/&gt;# BR2_sh64 is not set&lt;br/&gt;# BR2_sparc is not set&lt;br/&gt;# BR2_sparc64 is not set&lt;br/&gt;# BR2_x86_64 is not set&lt;br/&gt;# BR2_generic_arm is not set&lt;br/&gt;# BR2_arm7tdmi is not set&lt;br/&gt;# BR2_arm610 is not set&lt;br/&gt;# BR2_arm710 is not set&lt;br/&gt;# BR2_arm720t is not set&lt;br/&gt;# BR2_arm920t is not set&lt;br/&gt;# BR2_arm922t is not set&lt;br/&gt;# BR2_arm926t is not set&lt;br/&gt;# BR2_arm10t is not set&lt;br/&gt;# BR2_arm1136jf_s is not set&lt;br/&gt;# BR2_arm1176jz_s is not set&lt;br/&gt;BR2_arm1176jzf_s=y&lt;br/&gt;# BR2_sa110 is not set&lt;br/&gt;# BR2_sa1100 is not set&lt;br/&gt;# BR2_xscale is not set&lt;br/&gt;# BR2_iwmmxt is not set&lt;br/&gt;BR2_ARM_TYPE="ARM1176JZF_S"&lt;br/&gt;# BR2_ARM_OABI is not set&lt;br/&gt;BR2_ARM_EABI=y&lt;br/&gt;BR2_ARCH="arm"&lt;br/&gt;BR2_ENDIAN="LITTLE"&lt;br/&gt;BR2_GCC_TARGET_TUNE="arm1176jzf-s"&lt;br/&gt;BR2_GCC_TARGET_ARCH="armv6zk"&lt;br/&gt;BR2_GCC_TARGET_ABI="aapcs-linux"&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Target options&lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Project Options&lt;br/&gt;#&lt;br/&gt;BR2_PROJECT="uclibc"&lt;br/&gt;BR2_HOSTNAME="uclibc"&lt;br/&gt;BR2_BANNER="Welcome to Buildroot"&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Preset Devices&lt;br/&gt;#&lt;br/&gt;# BR2_TARGET_AMD is not set&lt;br/&gt;# BR2_TARGET_ARMLTD is not set&lt;br/&gt;# BR2_TARGET_ATMEL is not set&lt;br/&gt;# BR2_TARGET_KWIKBYTE is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Generic System Support&lt;br/&gt;#&lt;br/&gt;# BR2_TARGET_GENERIC_ACCESS_POINT is not set&lt;br/&gt;# BR2_TARGET_GENERIC_FIREWALL is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Generic development system requires a toolchain with WCHAR and PROGRAM_INVOCATION support&lt;br/&gt;#&lt;br/&gt;# BR2_TARGET_GENERIC_GETTY is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Build options&lt;br/&gt;#&lt;br/&gt;BR2_WGET="wget --passive-ftp -nd"&lt;br/&gt;BR2_SVN_CO="svn co"&lt;br/&gt;BR2_SVN_UP="svn up"&lt;br/&gt;BR2_GIT="git clone"&lt;br/&gt;BR2_ZCAT="gzip -d -c"&lt;br/&gt;BR2_BZCAT="bzcat"&lt;br/&gt;BR2_TAR_OPTIONS=""&lt;br/&gt;BR2_DL_DIR="$(BASE_DIR)/dl"&lt;br/&gt;BR2_COPYTO=""&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Mirrors and Download locations&lt;br/&gt;#&lt;br/&gt;BR2_PRIMARY_SITE=""&lt;br/&gt;BR2_BACKUP_SITE="http://buildroot.net/downloads/sources/"&lt;br/&gt;BR2_SOURCEFORGE_MIRROR="easynews"&lt;br/&gt;BR2_KERNEL_MIRROR="http://www.kernel.org/pub/"&lt;br/&gt;BR2_GNU_MIRROR="http://ftp.gnu.org/pub/gnu"&lt;br/&gt;BR2_DEBIAN_MIRROR="http://ftp.debian.org"&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Atmel Mirrors&lt;br/&gt;#&lt;br/&gt;BR2_ATMEL_MIRROR="ftp://www.at91.com/pub/buildroot/"&lt;br/&gt;BR2_AT91_PATCH_MIRROR="http://maxim.org.za/AT91RM9200/2.6/"&lt;br/&gt;BR2_STAGING_DIR="/usr/local/arm/buildroot-2009.05"&lt;br/&gt;# BR2_FPU_SUFFIX is not set&lt;br/&gt;BR2_TOPDIR_PREFIX=""&lt;br/&gt;BR2_TOPDIR_SUFFIX=""&lt;br/&gt;BR2_GNU_BUILD_SUFFIX="pc-linux-gnu"&lt;br/&gt;BR2_GNU_TARGET_SUFFIX="linux-uclibcgnueabi"&lt;br/&gt;BR2_JLEVEL=1&lt;br/&gt;# BR2_PREFER_IMA is not set&lt;br/&gt;# BR2_DEPRECATED is not set&lt;br/&gt;BR2_RECENT=y&lt;br/&gt;# BR2_CONFIG_CACHE is not set&lt;br/&gt;# BR2_ENABLE_DEBUG is not set&lt;br/&gt;BR2_STRIP_strip=y&lt;br/&gt;# BR2_STRIP_sstrip is not set&lt;br/&gt;# BR2_STRIP_none is not set&lt;br/&gt;# BR2_OPTIMIZE_0 is not set&lt;br/&gt;# BR2_OPTIMIZE_1 is not set&lt;br/&gt;# BR2_OPTIMIZE_2 is not set&lt;br/&gt;# BR2_OPTIMIZE_3 is not set&lt;br/&gt;BR2_OPTIMIZE_S=y&lt;br/&gt;# BR2_PREFER_STATIC_LIB is not set&lt;br/&gt;# BR2_HAVE_MANPAGES is not set&lt;br/&gt;# BR2_HAVE_INFOPAGES is not set&lt;br/&gt;# BR2_HAVE_DOCUMENTATION is not set&lt;br/&gt;# BR2_HAVE_DEVFILES is not set&lt;br/&gt;BR2_UPDATE_CONFIG=y&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Toolchain&lt;br/&gt;#&lt;br/&gt;BR2_TOOLCHAIN_BUILDROOT=y&lt;br/&gt;# BR2_TOOLCHAIN_EXTERNAL is not set&lt;br/&gt;# BR2_TOOLCHAIN_EXTERNAL_SOURCE is not set&lt;br/&gt;BR2_TOOLCHAIN_SOURCE=y&lt;br/&gt;BR2_EXT_GCC_VERSION_4_1_2=y&lt;br/&gt;BR2_EXT_GCC_VERSION_4_2_1=y&lt;br/&gt;BR2_EXT_GCC_VERSION_4_2_2=y&lt;br/&gt;BR2_EXT_GCC_VERSION_4_2_3=y&lt;br/&gt;BR2_EXT_BINUTILS_VERSION_2_17=y&lt;br/&gt;BR2_EXT_BINUTILS_VERSION_2_18=y&lt;br/&gt;BR2_EXT_UCLIBC_VERSION_0_9_28_3=y&lt;br/&gt;BR2_EXT_UCLIBC_VERSION_0_9_29=y&lt;br/&gt;BR2_EXT_UCLIBC_VERSION_0_9_30=y&lt;br/&gt;BR2_EXT_UCLIBC_VERSION_0_9_30_1=y&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Kernel Header Options&lt;br/&gt;#&lt;br/&gt;# BR2_KERNEL_HEADERS_2_6_23 is not set&lt;br/&gt;# BR2_KERNEL_HEADERS_2_6_24 is not set&lt;br/&gt;# BR2_KERNEL_HEADERS_2_6_25 is not set&lt;br/&gt;# BR2_KERNEL_HEADERS_2_6_26 is not set&lt;br/&gt;# BR2_KERNEL_HEADERS_2_6_27 is not set&lt;br/&gt;# BR2_KERNEL_HEADERS_2_6_28 is not set&lt;br/&gt;BR2_KERNEL_HEADERS_2_6_29=y&lt;br/&gt;# BR2_KERNEL_HEADERS_SNAP is not set&lt;br/&gt;BR2_DEFAULT_KERNEL_HEADERS="2.6.29.4"&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# uClibc Options&lt;br/&gt;#&lt;br/&gt;# BR2_UCLIBC_VERSION_0_9_28_3 is not set&lt;br/&gt;# BR2_UCLIBC_VERSION_0_9_29 is not set&lt;br/&gt;# BR2_UCLIBC_VERSION_0_9_30 is not set&lt;br/&gt;BR2_UCLIBC_VERSION_0_9_30_1=y&lt;br/&gt;# BR2_UCLIBC_VERSION_SNAPSHOT is not set&lt;br/&gt;BR2_UCLIBC_VERSION_STRING="0.9.30.1"&lt;br/&gt;BR2_UCLIBC_CONFIG="toolchain/uClibc/uClibc-0.9.30.config"&lt;br/&gt;# BR2_PTHREAD_DEBUG is not set&lt;br/&gt;# BR2_UCLIBC_PROGRAM_INVOCATION is not set&lt;br/&gt;# BR2_UCLIBC_INSTALL_TEST_SUITE is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Binutils Options&lt;br/&gt;#&lt;br/&gt;# BR2_BINUTILS_VERSION_2_17 is not set&lt;br/&gt;# BR2_BINUTILS_VERSION_2_17_50_0_17 is not set&lt;br/&gt;# BR2_BINUTILS_VERSION_2_18 is not set&lt;br/&gt;# BR2_BINUTILS_VERSION_2_18_50_0_1 is not set&lt;br/&gt;# BR2_BINUTILS_VERSION_2_18_50_0_3 is not set&lt;br/&gt;# BR2_BINUTILS_VERSION_2_18_50_0_6 is not set&lt;br/&gt;# BR2_BINUTILS_VERSION_2_18_50_0_8 is not set&lt;br/&gt;# BR2_BINUTILS_VERSION_2_18_50_0_9 is not set&lt;br/&gt;# BR2_BINUTILS_VERSION_2_19 is not set&lt;br/&gt;BR2_BINUTILS_VERSION_2_19_1=y&lt;br/&gt;BR2_BINUTILS_VERSION="2.19.1"&lt;br/&gt;BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# GCC Options&lt;br/&gt;#&lt;br/&gt;# BR2_GCC_VERSION_3_4_6 is not set&lt;br/&gt;# BR2_GCC_VERSION_4_0_4 is not set&lt;br/&gt;# BR2_GCC_VERSION_4_1_2 is not set&lt;br/&gt;# BR2_GCC_VERSION_4_2_1 is not set&lt;br/&gt;# BR2_GCC_VERSION_4_2_2 is not set&lt;br/&gt;# BR2_GCC_VERSION_4_2_3 is not set&lt;br/&gt;# BR2_GCC_VERSION_4_2_4 is not set&lt;br/&gt;# BR2_GCC_VERSION_4_3_1 is not set&lt;br/&gt;# BR2_GCC_VERSION_4_3_2 is not set&lt;br/&gt;BR2_GCC_VERSION_4_3_3=y&lt;br/&gt;# BR2_GCC_VERSION_4_4_X is not set&lt;br/&gt;BR2_GCC_SUPPORTS_SYSROOT=y&lt;br/&gt;BR2_GCC_SUPPORTS_FINEGRAINEDMTUNE=y&lt;br/&gt;BR2_GCC_VERSION="4.3.3"&lt;br/&gt;BR2_TOOLCHAIN_SYSROOT=y&lt;br/&gt;# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set&lt;br/&gt;BR2_EXTRA_GCC_CONFIG_OPTIONS=""&lt;br/&gt;# BR2_GCC_CROSS_FORTRAN is not set&lt;br/&gt;# BR2_INSTALL_LIBGCJ is not set&lt;br/&gt;# BR2_INSTALL_OBJC is not set&lt;br/&gt;# BR2_INSTALL_FORTRAN is not set&lt;br/&gt;BR2_GCC_SHARED_LIBGCC=y&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Ccache Options&lt;br/&gt;#&lt;br/&gt;# BR2_CCACHE is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Gdb Options&lt;br/&gt;#&lt;br/&gt;BR2_PACKAGE_GDB=y&lt;br/&gt;BR2_PACKAGE_GDB_SERVER=y&lt;br/&gt;BR2_PACKAGE_GDB_HOST=y&lt;br/&gt;# BR2_GDB_VERSION_6_4 is not set&lt;br/&gt;# BR2_GDB_VERSION_6_5 is not set&lt;br/&gt;# BR2_GDB_VERSION_6_6 is not set&lt;br/&gt;# BR2_GDB_VERSION_6_7_1 is not set&lt;br/&gt;BR2_GDB_VERSION_6_8=y&lt;br/&gt;BR2_GDB_VERSION="6.8"&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Common Toolchain Options&lt;br/&gt;#&lt;br/&gt;# BR2_LARGEFILE is not set&lt;br/&gt;# BR2_INET_IPV6 is not set&lt;br/&gt;# BR2_INET_RPC is not set&lt;br/&gt;# BR2_ENABLE_LOCALE is not set&lt;br/&gt;# BR2_USE_WCHAR is not set&lt;br/&gt;# BR2_SOFT_FLOAT is not set&lt;br/&gt;# BR2_USE_SSP is not set&lt;br/&gt;# BR2_PTHREADS_NONE is not set&lt;br/&gt;# BR2_PTHREADS is not set&lt;br/&gt;BR2_PTHREADS_OLD=y&lt;br/&gt;# BR2_PTHREADS_NATIVE is not set&lt;br/&gt;BR2_GCC_CROSS_CXX=y&lt;br/&gt;BR2_INSTALL_LIBSTDCPP=y&lt;br/&gt;BR2_TARGET_OPTIMIZATION="-Os -pipe"&lt;br/&gt;# BR2_ELF2FLT is not set&lt;br/&gt;# BR2_MKLIBS is not set&lt;br/&gt;# BR2_PACKAGE_SSTRIP_TARGET is not set&lt;br/&gt;# BR2_PACKAGE_SSTRIP_HOST is not set&lt;br/&gt;# BR2_ENABLE_MULTILIB is not set&lt;br/&gt;# BR2_VFP_FLOAT is not set&lt;br/&gt;BR2_CROSS_TOOLCHAIN_TARGET_UTILS=y&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Package Selection for the target&lt;br/&gt;#&lt;br/&gt;BR2_PACKAGE_BUSYBOX=y&lt;br/&gt;# BR2_BUSYBOX_VERSION_1_12_X is not set&lt;br/&gt;# BR2_BUSYBOX_VERSION_1_13_X is not set&lt;br/&gt;BR2_BUSYBOX_VERSION_1_14_X=y&lt;br/&gt;# BR2_PACKAGE_BUSYBOX_SNAPSHOT is not set&lt;br/&gt;BR2_BUSYBOX_VERSION="1.14.1"&lt;br/&gt;BR2_PACKAGE_BUSYBOX_FULLINSTALL=y&lt;br/&gt;BR2_PACKAGE_BUSYBOX_CONFIG="package/busybox/busybox-1.13.x.config"&lt;br/&gt;BR2_PACKAGE_BUSYBOX_HIDE_OTHERS=y&lt;br/&gt;# BR2_PACKAGE_BUSYBOX_SKELETON is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# The minimum needed to build a uClibc development system&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_FLEX is not set&lt;br/&gt;# BR2_PACKAGE_GCC_TARGET is not set&lt;br/&gt;# BR2_PACKAGE_MAKE is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Other development stuff&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_AUTOCONF is not set&lt;br/&gt;# BR2_PACKAGE_AUTOMAKE is not set&lt;br/&gt;# BR2_PACKAGE_BISON is not set&lt;br/&gt;# BR2_PACKAGE_CCACHE_TARGET is not set&lt;br/&gt;# BR2_PACKAGE_DISTCC is not set&lt;br/&gt;# BR2_PACKAGE_DMALLOC is not set&lt;br/&gt;# BR2_PACKAGE_FAKEROOT is not set&lt;br/&gt;BR2_HOST_FAKEROOT=y&lt;br/&gt;# BR2_PACKAGE_GETTEXT is not set&lt;br/&gt;# BR2_PACKAGE_LIBINTL is not set&lt;br/&gt;# BR2_PACKAGE_LIBGMP is not set&lt;br/&gt;# BR2_PACKAGE_GPERF is not set&lt;br/&gt;# BR2_PACKAGE_LIBMPFR is not set&lt;br/&gt;# BR2_PACKAGE_LIBTOOL is not set&lt;br/&gt;# BR2_PACKAGE_M4 is not set&lt;br/&gt;# BR2_PACKAGE_MPATROL is not set&lt;br/&gt;# BR2_PACKAGE_OPROFILE is not set&lt;br/&gt;# BR2_PACKAGE_PKG_CONFIG is not set&lt;br/&gt;# BR2_PACKAGE_READLINE is not set&lt;br/&gt;# BR2_PACKAGE_PCRE is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Other stuff&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_AT is not set&lt;br/&gt;# BR2_PACKAGE_BEECRYPT is not set&lt;br/&gt;# BR2_PACKAGE_BERKELEYDB is not set&lt;br/&gt;# BR2_PACKAGE_BSDIFF is not set&lt;br/&gt;# BR2_PACKAGE_CUPS is not set&lt;br/&gt;# BR2_PACKAGE_CUSTOMIZE is not set&lt;br/&gt;# BR2_PACKAGE_FILE is not set&lt;br/&gt;# BR2_PACKAGE_GAMIN is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# icu requires a toolchain with C++ support and WCHAR enabled&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_KEXEC is not set&lt;br/&gt;# BR2_PACKAGE_LIBCONFIG is not set&lt;br/&gt;# BR2_PACKAGE_LIBCONFUSE is not set&lt;br/&gt;# BR2_PACKAGE_LIBDAEMON is not set&lt;br/&gt;# BR2_PACKAGE_LIBELF is not set&lt;br/&gt;# BR2_PACKAGE_LIBEVENT is not set&lt;br/&gt;# BR2_PACKAGE_LIBGCRYPT is not set&lt;br/&gt;# BR2_PACKAGE_LIBGPG_ERROR is not set&lt;br/&gt;# BR2_PACKAGE_LIBICONV is not set&lt;br/&gt;# BR2_PACKAGE_LIBIDN is not set&lt;br/&gt;# BR2_PACKAGE_LIBLOCKFILE is not set&lt;br/&gt;# BR2_PACKAGE_LIBOIL is not set&lt;br/&gt;# BR2_PACKAGE_LIBSYSFS is not set&lt;br/&gt;# BR2_PACKAGE_LOCKFILE_PROGS is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# logrotate     - disabled (requires wchar support)&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_LSOF is not set&lt;br/&gt;# BR2_PACKAGE_LTP-TESTSUITE is not set&lt;br/&gt;# BR2_PACKAGE_LTRACE is not set&lt;br/&gt;# BR2_PACKAGE_MEMSTAT is not set&lt;br/&gt;# BR2_PACKAGE_NG_SPICE_REWORK is not set&lt;br/&gt;# BR2_PACKAGE_POPT is not set&lt;br/&gt;# BR2_PACKAGE_SCREEN is not set&lt;br/&gt;# BR2_PACKAGE_SHARED_MIME_INFO is not set&lt;br/&gt;# BR2_PACKAGE_STARTUP_NOTIFICATION is not set&lt;br/&gt;# BR2_PACKAGE_STRACE is not set&lt;br/&gt;# BR2_PACKAGE_SUDO is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Database&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_MYSQL_CLIENT is not set&lt;br/&gt;# BR2_PACKAGE_SQLITE is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Networking&lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Networking applications&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_ARGUS is not set&lt;br/&gt;# BR2_PACKAGE_AVAHI is not set&lt;br/&gt;# BR2_PACKAGE_AXEL is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# bind requires a toolchain with LARGEFILE support&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_BRIDGE is not set&lt;br/&gt;# BR2_PACKAGE_DNSMASQ is not set&lt;br/&gt;# BR2_PACKAGE_DROPBEAR is not set&lt;br/&gt;# BR2_PACKAGE_ETHTOOL is not set&lt;br/&gt;# BR2_PACKAGE_HASERL is not set&lt;br/&gt;# BR2_PACKAGE_IFPLUGD is not set&lt;br/&gt;# BR2_PACKAGE_IPERF is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# iproute2 requires a toolchain with IPv6 support&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_IPSEC_TOOLS is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# iptables requires a toolchain with LARGEFILE support&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_KISMET is not set&lt;br/&gt;# BR2_PACKAGE_L2TP is not set&lt;br/&gt;# BR2_PACKAGE_LIBCGI is not set&lt;br/&gt;# BR2_PACKAGE_LIBCGICC is not set&lt;br/&gt;# BR2_PACKAGE_LIBCURL is not set&lt;br/&gt;# BR2_PACKAGE_LIBDNET is not set&lt;br/&gt;# BR2_PACKAGE_LIBEXOSIP2 is not set&lt;br/&gt;# BR2_PACKAGE_LIBOSIP2 is not set&lt;br/&gt;# BR2_PACKAGE_LIBPCAP is not set&lt;br/&gt;# BR2_PACKAGE_LIBSOUP is not set&lt;br/&gt;# BR2_PACKAGE_LIBUPNP is not set&lt;br/&gt;# BR2_PACKAGE_LINKS is not set&lt;br/&gt;# BR2_PACKAGE_LRZSZ is not set&lt;br/&gt;# BR2_PACKAGE_MDNSRESPONDER is not set&lt;br/&gt;# BR2_PACKAGE_MIIDIAG is not set&lt;br/&gt;# BR2_PACKAGE_MROUTED is not set&lt;br/&gt;# BR2_PACKAGE_MUTT is not set&lt;br/&gt;# BR2_PACKAGE_NBD is not set&lt;br/&gt;# BR2_PACKAGE_NCFTP is not set&lt;br/&gt;# BR2_PACKAGE_NEON is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# netkitbase requires a toolchain with RPC support&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_NETKITTELNET is not set&lt;br/&gt;# BR2_PACKAGE_NETPLUG is not set&lt;br/&gt;# BR2_PACKAGE_NETSNMP is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# nfs-utils requires a toolchain with 'Enable RPC' selected&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_NTP is not set&lt;br/&gt;# BR2_PACKAGE_OLSR is not set&lt;br/&gt;# BR2_PACKAGE_OPENNTPD is not set&lt;br/&gt;# BR2_PACKAGE_OPENSSH is not set&lt;br/&gt;# BR2_PACKAGE_OPENSSL is not set&lt;br/&gt;# BR2_PACKAGE_OPENVPN is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# portmap requires a toolchain with 'Enable RPC' selected&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_PPPD is not set&lt;br/&gt;# BR2_PACKAGE_RP_PPPOE is not set&lt;br/&gt;# BR2_PACKAGE_PPTP_LINUX is not set&lt;br/&gt;# BR2_PACKAGE_PROFTPD is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# quagga suite&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_QUAGGA_ZEBRA is not set&lt;br/&gt;# BR2_PACKAGE_QUAGGA_BGPD is not set&lt;br/&gt;# BR2_PACKAGE_QUAGGA_RIPD is not set&lt;br/&gt;# BR2_PACKAGE_QUAGGA_RIPNGD is not set&lt;br/&gt;# BR2_PACKAGE_QUAGGA_OSPFD is not set&lt;br/&gt;# BR2_PACKAGE_QUAGGA_WATCHQUAGGA is not set&lt;br/&gt;# BR2_PACKAGE_QUAGGA_ISISD is not set&lt;br/&gt;# BR2_PACKAGE_RSYNC is not set&lt;br/&gt;# BR2_PACKAGE_SAMBA is not set&lt;br/&gt;# BR2_PACKAGE_SOCAT is not set&lt;br/&gt;# BR2_PACKAGE_STUNNEL is not set&lt;br/&gt;# BR2_PACKAGE_TCPDUMP is not set&lt;br/&gt;# BR2_PACKAGE_DHCPDUMP is not set&lt;br/&gt;# BR2_PACKAGE_TFTPD is not set&lt;br/&gt;# BR2_PACKAGE_TN5250 is not set&lt;br/&gt;# BR2_PACKAGE_TTCP is not set&lt;br/&gt;# BR2_PACKAGE_UDPCAST is not set&lt;br/&gt;# BR2_PACKAGE_VPNC is not set&lt;br/&gt;# BR2_PACKAGE_VSFTPD is not set&lt;br/&gt;# BR2_PACKAGE_VTUN is not set&lt;br/&gt;# BR2_PACKAGE_WEBIF is not set&lt;br/&gt;# BR2_PACKAGE_WIRELESS_TOOLS is not set&lt;br/&gt;# BR2_PACKAGE_WPA_SUPPLICANT is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Hardware handling / blockdevices and filesystem maintenance&lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# dbus not available (need expat or libxml2)&lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# dbus-glib needs dbus to be compiled with expat support&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_DEVMEM2 is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# dm requires a toolchain with LARGEFILE support&lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# dmraid requires a toolchain with LARGEFILE support&lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# e2fsprogs requires a toolchain with LARGEFILE support&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_EEPROG is not set&lt;br/&gt;# BR2_PACKAGE_FCONFIG is not set&lt;br/&gt;# BR2_PACKAGE_FIS is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# libfuse requires a toolchain with LARGEFILE support&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_GADGETFS_TEST is not set&lt;br/&gt;# BR2_PACKAGE_HAL is not set&lt;br/&gt;# BR2_PACKAGE_HWDATA is not set&lt;br/&gt;# BR2_PACKAGE_I2C_TOOLS is not set&lt;br/&gt;# BR2_PACKAGE_INPUT_TOOLS is not set&lt;br/&gt;# BR2_PACKAGE_IOSTAT is not set&lt;br/&gt;# BR2_PACKAGE_LIBAIO is not set&lt;br/&gt;# BR2_PACKAGE_LIBRAW1394 is not set&lt;br/&gt;# BR2_PACKAGE_LIBUSB is not set&lt;br/&gt;# BR2_PACKAGE_LM_SENSORS is not set&lt;br/&gt;# BR2_PACKAGE_LVM2 is not set&lt;br/&gt;# BR2_PACKAGE_MDADM is not set&lt;br/&gt;# BR2_PACKAGE_MEMTESTER is not set&lt;br/&gt;# BR2_PACKAGE_MKDOSFS is not set&lt;br/&gt;BR2_PACKAGE_MTD=y&lt;br/&gt;BR2_PACKAGE_MTD_UTILS=y&lt;br/&gt;# BR2_PACKAGE_MTD_20061007 is not set&lt;br/&gt;# BR2_PACKAGE_MTD_20050122 is not set&lt;br/&gt;# BR2_PACKAGE_MTD_UTILS_GIT is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# MTD tools selection&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_MTD_DOCFDISK is not set&lt;br/&gt;# BR2_PACKAGE_MTD_DOC_LOADBIOS is not set&lt;br/&gt;BR2_PACKAGE_MTD_FLASHCP=y&lt;br/&gt;BR2_PACKAGE_MTD_FLASH_ERASE=y&lt;br/&gt;BR2_PACKAGE_MTD_FLASH_ERASEALL=y&lt;br/&gt;BR2_PACKAGE_MTD_FLASH_INFO=y&lt;br/&gt;BR2_PACKAGE_MTD_FLASH_LOCK=y&lt;br/&gt;BR2_PACKAGE_MTD_FLASH_UNLOCK=y&lt;br/&gt;BR2_PACKAGE_MTD_FTL_CHECK=y&lt;br/&gt;BR2_PACKAGE_MTD_FTL_FORMAT=y&lt;br/&gt;BR2_PACKAGE_MTD_JFFS2DUMP=y&lt;br/&gt;BR2_PACKAGE_MTD_MKFSJFFS2=y&lt;br/&gt;# BR2_PACKAGE_MTD_MKFSJFFS is not set&lt;br/&gt;BR2_PACKAGE_MTD_MTD_DEBUG=y&lt;br/&gt;BR2_PACKAGE_MTD_NANDDUMP=y&lt;br/&gt;BR2_PACKAGE_MTD_NANDWRITE=y&lt;br/&gt;# BR2_PACKAGE_MTD_NFTL_FORMAT is not set&lt;br/&gt;# BR2_PACKAGE_MTD_NFTLDUMP is not set&lt;br/&gt;BR2_PACKAGE_MTD_SUMTOOL=y&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# ntfs-3g requires a toolchain with LARGEFILE and WCHAR support&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_PCIUTILS is not set&lt;br/&gt;# BR2_PACKAGE_SETSERIAL is not set&lt;br/&gt;# BR2_PACKAGE_SMARTMONTOOLS is not set&lt;br/&gt;# BR2_PACKAGE_USBMOUNT is not set&lt;br/&gt;# BR2_PACKAGE_USBUTILS is not set&lt;br/&gt;# BR2_PACKAGE_WIPE is not set&lt;br/&gt;# BR2_PACKAGE_XFSPROGS is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Audio and video libraries and applications&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_ALSA_LIB is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# alsa-utils requires a toolchain with LARGEFILE support&lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# asterisk    - disabled (required openssl and mpg123)&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_AUMIX is not set&lt;br/&gt;# BR2_PACKAGE_FLAC is not set&lt;br/&gt;# BR2_PACKAGE_GSTREAMER is not set&lt;br/&gt;# BR2_PACKAGE_LIBID3TAG is not set&lt;br/&gt;# BR2_PACKAGE_LIBMAD is not set&lt;br/&gt;# BR2_PACKAGE_LIBMPD is not set&lt;br/&gt;# BR2_PACKAGE_LIBOGG is not set&lt;br/&gt;# BR2_PACKAGE_LIBSNDFILE is not set&lt;br/&gt;# BR2_PACKAGE_LIBTHEORA is not set&lt;br/&gt;# BR2_PACKAGE_LIBVORBIS is not set&lt;br/&gt;# BR2_PACKAGE_MADPLAY is not set&lt;br/&gt;# BR2_PACKAGE_MPG123 is not set&lt;br/&gt;# BR2_PACKAGE_MPLAYER is not set&lt;br/&gt;# BR2_PACKAGE_SPEEX is not set&lt;br/&gt;# BR2_PACKAGE_FESTIVAL is not set&lt;br/&gt;# BR2_PACKAGE_TAGLIB is not set&lt;br/&gt;# BR2_PACKAGE_VLC is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Graphic libraries and applications (graphic/text)&lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# text rendering libraries&lt;br/&gt;#&lt;br/&gt;BR2_PACKAGE_NCURSES=y&lt;br/&gt;# BR2_PACKAGE_NCURSES_TARGET_PANEL is not set&lt;br/&gt;# BR2_PACKAGE_NCURSES_TARGET_FORM is not set&lt;br/&gt;# BR2_PACKAGE_NCURSES_TARGET_MENU is not set&lt;br/&gt;# BR2_PACKAGE_NCURSES_TARGET_HEADERS is not set&lt;br/&gt;# BR2_PACKAGE_NEWT is not set&lt;br/&gt;# BR2_PACKAGE_SLANG is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# text rendering applications&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_DIALOG is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# graphic libraries&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_DIRECTFB is not set&lt;br/&gt;# BR2_PACKAGE_FBDUMP is not set&lt;br/&gt;# BR2_PACKAGE_IMAGEMAGICK is not set&lt;br/&gt;# BR2_PACKAGE_JPEG is not set&lt;br/&gt;# BR2_PACKAGE_LIBART is not set&lt;br/&gt;# BR2_PACKAGE_LIBPNG is not set&lt;br/&gt;# BR2_PACKAGE_LIBUNGIF is not set&lt;br/&gt;# BR2_PACKAGE_LINUX_FUSION is not set&lt;br/&gt;# BR2_PACKAGE_PIXMAN is not set&lt;br/&gt;# BR2_PACKAGE_SDL is not set&lt;br/&gt;# BR2_PACKAGE_TIFF is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# busybox graphic applications&lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# --&amp;gt; May be broken in busybox&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_FBV is not set&lt;br/&gt;# BR2_PACKAGE_FBSET is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# other GUIs&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_QTOPIA4 is not set&lt;br/&gt;BR2_PACKAGE_XSERVER_none=y&lt;br/&gt;# BR2_PACKAGE_XSERVER_xorg is not set&lt;br/&gt;# BR2_PACKAGE_XSERVER_tinyx is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# xorg requires a toolchain with C++, LOCALE, LARGEFILE and WCHAR support&lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# tinyx requires a toolchain with WCHAR support&lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# X libraries and helper libraries&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_ATK is not set&lt;br/&gt;# BR2_PACKAGE_CAIRO is not set&lt;br/&gt;# BR2_PACKAGE_PANGO is not set&lt;br/&gt;# BR2_PACKAGE_LIBDRM is not set&lt;br/&gt;# BR2_PACKAGE_LIBERATION is not set&lt;br/&gt;# BR2_PACKAGE_LIBGLIB12 is not set&lt;br/&gt;# BR2_PACKAGE_LIBGLIB2 is not set&lt;br/&gt;# BR2_PACKAGE_OPENMOTIF is not set&lt;br/&gt;# BR2_PACKAGE_FONTCONFIG is not set&lt;br/&gt;# BR2_PACKAGE_FREETYPE is not set&lt;br/&gt;# BR2_PACKAGE_TSLIB is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# webkit requires a toolchain with C++ support and WCHAR enabled&lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# X Window managers&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_MATCHBOX is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# X applications&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_ALSAMIXERGUI is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# dillo        - disabled (requires jpeg,libglib12,libgtk12,zlib,libpng and Xorg(7))&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_GQVIEW is not set&lt;br/&gt;# BR2_PACKAGE_GOB2 is not set&lt;br/&gt;# BR2_PACKAGE_LEAFPAD is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# midori        - disabled (requires Xorg(7))&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_PCMANFM is not set&lt;br/&gt;# BR2_PACKAGE_SYLPHEED is not set&lt;br/&gt;# BR2_PACKAGE_TORSMO is not set&lt;br/&gt;# BR2_PACKAGE_X11VNC is not set&lt;br/&gt;# BR2_PACKAGE_XPDF is not set&lt;br/&gt;# BR2_PACKAGE_XSTROKE is not set&lt;br/&gt;# BR2_PACKAGE_XVKBD is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Compressors / decompressors&lt;br/&gt;#&lt;br/&gt;BR2_PACKAGE_LZO=y&lt;br/&gt;# BR2_PACKAGE_LZOP is not set&lt;br/&gt;# BR2_PACKAGE_LZMA_TARGET is not set&lt;br/&gt;# BR2_PACKAGE_LZMA_HOST is not set&lt;br/&gt;BR2_PACKAGE_ZLIB=y&lt;br/&gt;# BR2_PACKAGE_ZLIB_TARGET_HEADERS is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Package managers&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_IPKG is not set&lt;br/&gt;# BR2_PACKAGE_PORTAGE is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Interpreter languages / Scripting&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_LUA is not set&lt;br/&gt;# BR2_PACKAGE_MICROPERL is not set&lt;br/&gt;# BR2_PACKAGE_PYTHON is not set&lt;br/&gt;# BR2_PACKAGE_RUBY is not set&lt;br/&gt;# BR2_PACKAGE_TCL is not set&lt;br/&gt;# BR2_PACKAGE_PHP is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# XML handling&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_EXPAT is not set&lt;br/&gt;# BR2_PACKAGE_EZXML is not set&lt;br/&gt;# BR2_PACKAGE_LIBXML2 is not set&lt;br/&gt;# BR2_PACKAGE_LIBXSLT is not set&lt;br/&gt;# BR2_PACKAGE_XERCES is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Java&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_CLASSPATH is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Games&lt;br/&gt;#&lt;br/&gt;# BR2_PACKAGE_GNUCHESS is not set&lt;br/&gt;# BR2_PACKAGE_MAGICCUBE4D is not set&lt;br/&gt;# BR2_PACKAGE_PRBOOM is not set&lt;br/&gt;# BR2_PACKAGE_RUBIX is not set&lt;br/&gt;# BR2_PACKAGE_VICE is not set&lt;br/&gt;# BR2_PACKAGE_XBOARD is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Target filesystem options&lt;br/&gt;#&lt;br/&gt;BR2_ROOTFS_PREFIX="rootfs"&lt;br/&gt;BR2_ROOTFS_SUFFIX=""&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# filesystem for target device&lt;br/&gt;#&lt;br/&gt;BR2_TARGET_ROOTFS_CRAMFS=y&lt;br/&gt;# BR2_TARGET_ROOTFS_CLOOP is not set&lt;br/&gt;BR2_TARGET_ROOTFS_EXT2=y&lt;br/&gt;BR2_TARGET_ROOTFS_EXT2_BLOCKS=0&lt;br/&gt;BR2_TARGET_ROOTFS_EXT2_INODES=0&lt;br/&gt;BR2_TARGET_ROOTFS_EXT2_RESBLKS=0&lt;br/&gt;BR2_TARGET_ROOTFS_EXT2_SQUASH=y&lt;br/&gt;BR2_TARGET_ROOTFS_EXT2_OUTPUT="$(IMAGE).ext2"&lt;br/&gt;BR2_TARGET_ROOTFS_EXT2_NONE=y&lt;br/&gt;# BR2_TARGET_ROOTFS_EXT2_GZIP is not set&lt;br/&gt;# BR2_TARGET_ROOTFS_EXT2_BZIP2 is not set&lt;br/&gt;# BR2_TARGET_ROOTFS_EXT2_LZMA is not set&lt;br/&gt;BR2_TARGET_ROOTFS_EXT2_COPYTO=""&lt;br/&gt;BR2_TARGET_ROOTFS_JFFS2=y&lt;br/&gt;# BR2_TARGET_ROOTFS_JFFS2_DATAFLASH_1056 is not set&lt;br/&gt;BR2_TARGET_ROOTFS_JFFS2_DATAFLASH_528=y&lt;br/&gt;# BR2_TARGET_ROOTFS_JFFS2_NANDFLASH_2K_128K is not set&lt;br/&gt;# BR2_TARGET_ROOTFS_JFFS2_FLASH_128 is not set&lt;br/&gt;# BR2_TARGET_ROOTFS_JFFS2_FLASH_64 is not set&lt;br/&gt;# BR2_TARGET_ROOTFS_JFFS2_CUSTOM is not set&lt;br/&gt;BR2_TARGET_ROOTFS_JFFS2_PAGESIZE=0x210&lt;br/&gt;BR2_TARGET_ROOTFS_JFFS2_EBSIZE=0x1080&lt;br/&gt;BR2_TARGET_ROOTFS_JFFS2_NOCLEANMARKER=y&lt;br/&gt;# BR2_JFFS2_TARGET_SREC is not set&lt;br/&gt;# BR2_TARGET_ROOTFS_JFFS2_PAD is not set&lt;br/&gt;BR2_TARGET_ROOTFS_JFFS2_LE=y&lt;br/&gt;# BR2_TARGET_ROOTFS_JFFS2_BE is not set&lt;br/&gt;# BR2_TARGET_ROOTFS_JFFS2_SUMMARY is not set&lt;br/&gt;BR2_TARGET_ROOTFS_JFFS2_OUTPUT="$(IMAGE).jffs2"&lt;br/&gt;BR2_TARGET_ROOTFS_JFFS2_COPYTO=""&lt;br/&gt;# BR2_TARGET_ROOTFS_SQUASHFS is not set&lt;br/&gt;# BR2_TARGET_ROOTFS_TAR is not set&lt;br/&gt;BR2_TARGET_ROOTFS_CPIO=y&lt;br/&gt;BR2_TARGET_ROOTFS_CPIO_NONE=y&lt;br/&gt;# BR2_TARGET_ROOTFS_CPIO_GZIP is not set&lt;br/&gt;# BR2_TARGET_ROOTFS_CPIO_BZIP2 is not set&lt;br/&gt;# BR2_TARGET_ROOTFS_CPIO_LZMA is not set&lt;br/&gt;BR2_TARGET_ROOTFS_CPIO_COPYTO=""&lt;br/&gt;BR2_TARGET_ROOTFS_INITRAMFS=y&lt;br/&gt;# BR2_TARGET_ROOTFS_ROMFS is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# bootloader for target device&lt;br/&gt;#&lt;br/&gt;# BR2_TARGET_UBOOT is not set&lt;br/&gt;&lt;br/&gt;#&lt;br/&gt;# Kernel&lt;br/&gt;#&lt;br/&gt;BR2_KERNEL_none=y&lt;br/&gt;# BR2_KERNEL_LINUX_ADVANCED is not set&lt;br/&gt;# BR2_KERNEL_LINUX is not set&lt;br/&gt;# BR2_KERNEL_HURD is not set&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=19e58eb8-3f07-857c-80f5-f2e8488d6e94' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-6483079249267760361?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/6483079249267760361/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/08/buildroot-200905-config-file.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/6483079249267760361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/6483079249267760361'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/08/buildroot-200905-config-file.html' title='buildroot-2009.05 config file'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-5936004531391737351</id><published>2009-08-04T01:01:00.001-07:00</published><updated>2009-09-03T22:26:22.603-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qemu'/><category scheme='http://www.blogger.com/atom/ns#' term='environment'/><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>More on QEMU</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;兩年前在 [&lt;a href='http://blog.roodo.com/use_the_force/archives/2717044.html'&gt;QEMU 安裝與試跑&lt;/a&gt;] 探討了模擬 ARM Versatile 系統。 原以為這樣就會使用 QEMU 了，最近兩天為了模擬 x86 不成功，只好重新拾起 [&lt;a href='http://www.qemu.org/user-doc.html'&gt;QEMU Documentation&lt;/a&gt;] 仔細再 K 一下，補足原本欠缺的觀念，以下紀錄的是該準備的 sources &amp;amp; images ：&lt;br/&gt;&lt;br/&gt;linux-2.6.28 由 [&lt;a href='http://www.kernel.org'&gt;kernel archive&lt;/a&gt;] 下載解壓的，&lt;br/&gt; linux-0.2.img.bz2 由 QEMU Documentation | [&lt;a href='http://www.qemu.org/download.html'&gt;download&lt;/a&gt;] | 下載得到，&lt;br/&gt;bzImage-2.6.28-test 由 linux-2.6.28 編好之後所得，&lt;br/&gt;initrd.img-2.6.28-test.bz2 由 linux-2.6.28 編好安裝模組 (make modules_install) 後，利用 update-initramfs -c -k 2.6.28-test 所得到的&lt;br/&gt;檔案系統 (bunzip2 -c initrd.img-2.6.28-test.bz2 | cpio -idm) &lt;br/&gt;&lt;br/&gt;以下紀錄了幾次錯誤的啟動方式：&lt;br/&gt;#&amp;gt; qemu -kernel bzImage-2.6.28-test &lt;br/&gt;==&amp;gt;A disk image must be given for 'hda' when booting a Linux kernel&lt;br/&gt;(if you really don't want it, use /dev/zero)&lt;br/&gt;#&amp;gt; qemu -kernel bzImage-2.6.28-test -hda /dev/zero&lt;br/&gt;==&amp;gt; booting from Hard Disk &lt;br/&gt;==&amp;gt;failed : not a bootable disk&lt;br/&gt;==&amp;gt; no bootable device&lt;br/&gt;沒頭緒，翻翻線上手冊好了---&lt;br/&gt;在 [&lt;a href='http://www.qemu.org/user-doc.html'&gt;QEMU Documentation&lt;/a&gt;] 3.8 節 Direct Linux Boot 提到：&lt;br/&gt;`...It is very useful for fast Linux kernel testing.&lt;br/&gt;The syntax is : &lt;br/&gt;qemu -kernel arch/i386/boot/bzImage -hda root-2.4.20.img -append "root=/dev/hda" `&lt;br/&gt;&lt;br/&gt;"...Use ‘&lt;samp&gt;-kernel&lt;/samp&gt;’ to provide the Linux kernel image and ‘&lt;samp&gt;-append&lt;/samp&gt;’ to give the kernel command line arguments. The ‘&lt;samp&gt;-initrd&lt;/samp&gt;’ option can be used to provide an INITRD image.&lt;br/&gt;When using the direct Linux boot, &lt;font color='#ff0000'&gt;&lt;b&gt;a disk image for the first hard disk ‘&lt;tt&gt;hda&lt;/tt&gt;’ is required&lt;/b&gt;&lt;/font&gt; because its boot sector is used to launch the Linux kernel..."&lt;br/&gt;&lt;br/&gt;所以我們得準備一個 disk image，也就是剛才下載的 linux-0.2.img，讓 QEMU 透過 disk image 的 boot sector 載入 kernel image，並且傳 kernel parameter "root=/dev/hda" ，告訴 kernel 說 root filesystem 在 disk image 上！&lt;br/&gt;&lt;br/&gt;#&amp;gt;qemu -kernel bzImage-2.6.28-test  -hda linux-0.2.img -append "root=/dev/hda"&lt;br/&gt;&lt;br/&gt;終於成功 ，顯示出的 kernel 為餵進去的 2.6.28-test.，注意 disk image 不能用壓縮的 bz2 or gz ，否則會發生 waiting for root filesystem...的現象...殘念！&lt;br/&gt;&lt;br/&gt;結論：在模擬 x86 上，需要有 disk image (即使不使用 disk image 上的 kernel image 也一樣)，跟模擬 ARM 有所不同。&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=efa2ded9-42ca-8873-a1cb-725fa7ea4bc0' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-5936004531391737351?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/5936004531391737351/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/08/more-on-qemu.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/5936004531391737351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/5936004531391737351'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/08/more-on-qemu.html' title='More on QEMU'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-8144120871069278558</id><published>2009-06-07T09:00:00.001-07:00</published><updated>2009-06-12T03:05:14.629-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='environment'/><title type='text'>Apt-get : NO_PUBKEY / GPG error</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;[&lt;a target='_blank' href='http://en.kioskea.net/faq/sujet-809-debian-apt-get-no-pubkey-gpg-error'&gt;原文出處&lt;/a&gt;] &lt;br/&gt;有時改過 apt source list 後，會發生 GPG error  抱怨某個 key 找不到，把該 key 帶入下列指令就可以解決，背後原理還不知道，（待查）&lt;br/&gt;&lt;pre&gt;gpg --keyserver pgpkeys.mit.edu --recv-key  010908312D230C5F&lt;br /&gt;gpg -a --export 010908312D230C5F | sudo apt-key add -&lt;/pre&gt;其中，把範例中的 key 換成發生問題的 key 就可解決#Technorati 標籤: &lt;a rel='tag' href='http://technorati.com/tag/apt' class='performancingtags'&gt;apt&lt;/a&gt;, &lt;a rel='tag' href='http://technorati.com/tag/gpg%20error' class='performancingtags'&gt;gpg error&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/8646454779089790212-8144120871069278558?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/8144120871069278558/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/06/apt-get-nopubkey-gpg-error.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/8144120871069278558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/8144120871069278558'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/06/apt-get-nopubkey-gpg-error.html' title='Apt-get : NO_PUBKEY / GPG error'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-1687836276453980308</id><published>2009-05-26T00:16:00.000-07:00</published><updated>2009-06-12T03:04:31.526-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>RCU 初步認識</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;從 Paul McKenney 的[&lt;a target='_blank' href='http://www.rdrop.com/users/paulmck/RCU/'&gt;網站&lt;/a&gt;] 有 [&lt;a target='_blank' href='http://lwn.net/Articles/262464/'&gt;RCU 的基本介紹&lt;/a&gt;] 一文，趁著爬文後還有印象，趕快整理一下重點與常見問題：&lt;br/&gt;&lt;b&gt;1. RCU 的需求&lt;/b&gt;：&lt;br/&gt;  RCU (Read Copy Update) 是一種 synchronization 機制，允許多個 reads to occur &lt;b&gt;concurrently&lt;/b&gt; with updates，它本身不使用 lock 機制，在 kernel 內，適合用在 reader 多但 writer 少的資料保護。因為現在的系統多半都有多個 CPUs，RCU 機制允許多個 readers 的 &lt;b&gt;scability&lt;/b&gt; 特性(無限個 readers，而且進入 reader-side critical section 是非常的 low cost)，使得它在這些情形下，比用 lock 有更好的 performance。&lt;br/&gt;&lt;br/&gt;&lt;b&gt;2. RCU 的工作方式及術語&lt;/b&gt;：(資料來源 : [&lt;a href='http://en.wikipedia.org/wiki/Read-copy-update'&gt;RCU Wiki&lt;/a&gt;] )&lt;br/&gt;  RCU 把 update 分成兩個 phase: "removal" and "reclamation". &lt;br/&gt;  &lt;b&gt;Removal phase&lt;/b&gt; 移除某個 data 指標，此時允許多個 readers 繼續進行，readers 可能看到兩種版本的資料(移除該 data 前跟移除後) 因為是更改指標，&lt;font color='#cc0000'&gt;所以只要確保更改指標的動作是 atomic operation &lt;/font&gt;，就不會破壞到資料。&lt;br/&gt;  &lt;b&gt;Reclamation phase&lt;/b&gt; 時，只要確保沒有 reader 會再參考該 data 之後，就可以安全的移除該資料---這涉及兩個條件：&lt;font color='#cc0000'&gt;一、 所有 reader 讀取資料的動作是 link list 的單一方向的拜訪，不回頭。二、 所有的 reader 執行 "reader-side critical section" 內的動作時不能 block 或 preempt&lt;/font&gt;，&lt;font color='#000000'&gt;這樣我們的 reclamation phase 可以簡單的設計成&lt;font face='sans-serif'&gt;：&lt;br/&gt;&lt;br/&gt;void synchronize_rcu(void) {&lt;br/&gt;   int cpu;&lt;br/&gt;   for_each_cpu(cpu);&lt;br/&gt;   run_on(cpu);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;只要令每個 CPU 都輪流完，就可確保下列情形：所有在 synchronize_rcu() 的執行時間之前，所有參考到舊版本(未移除時)的 readers 都保證結束，在這個時間點後，所有的 readers 都將只看到新版本(已移除該 data) 的資料串列了！這段等待所有 CPU 跑完的時間稱作 "Grace Period"，在歷經 grace period 後，我們就可以確定該 data 已經沒有任何的 reader 參考了，可以放心的 free 掉。(即 reclamation).&lt;br/&gt;&lt;br/&gt;剛才所討論的是 delete 的 RCU 動作， add/replace 的 RCU 動作原理也是依此類推。&lt;br/&gt; &lt;br/&gt;3 一些 RCU 的 API :&lt;br/&gt;&lt;br/&gt;假設我們有一片段程式，updater 動作如下:&lt;br/&gt;例一：&lt;br/&gt;  1 struct foo {&lt;br/&gt;  2   int a;&lt;br/&gt;  3   int b;&lt;br/&gt;  4   int c;&lt;br/&gt;  5 };&lt;br/&gt;  6 struct foo *gp = NULL;&lt;br/&gt;  7&lt;br/&gt;  8 /* . . . */&lt;br/&gt;  9&lt;br/&gt; 10 p = kmalloc(sizeof(*p), GFP_KERNEL);&lt;br/&gt; 11 p-&amp;gt;a = 1;&lt;br/&gt; 12 p-&amp;gt;b = 2;&lt;br/&gt; 13 p-&amp;gt;c = 3;&lt;br/&gt; 14 gp = p;&lt;br/&gt;&lt;br/&gt; 這裡不能保證 11-14 行不會被 compiler reorder，所以我們改為：&lt;br/&gt;&lt;br/&gt;  1 p-&amp;gt;a = 1;&lt;br/&gt;  2 p-&amp;gt;b = 2;&lt;br/&gt;  3 p-&amp;gt;c = 3;&lt;br/&gt;  4 &lt;b&gt;rcu_assign_pointer&lt;/b&gt;(gp, p); 裡面加了 memory barrier 保證 pointer assign 發生於 line 1-3 之後.&lt;br/&gt;&lt;br/&gt;&lt;font color='#000000'&gt;同樣的，在 reader 一方，reader 也需要 memory barrier:&lt;/font&gt;&lt;br/&gt;例二：&lt;br/&gt;  1 p = gp;&lt;br/&gt;  2 if (p != NULL) {&lt;br/&gt;  3   do_something_with(p-&amp;gt;a, p-&amp;gt;b, p-&amp;gt;c);&lt;br/&gt;  4 }&lt;br/&gt;在大部分的 arch 下是正確的，但是在 DEC Alpha 還是會有可能 p-&amp;gt;a, p-&amp;gt;b, p-&amp;gt;c 發生得比 fetch p 來得早，&lt;br/&gt;所以應該改成：&lt;br/&gt;例三：&lt;br/&gt;  1 rcu_read_lock();&lt;br/&gt;  2 p = rcu_dereference(gp);&lt;br/&gt;  3 if (p != NULL) {&lt;br/&gt;  4   do_something_with(p-&amp;gt;a, p-&amp;gt;b, p-&amp;gt;c);&lt;br/&gt;  5 }&lt;br/&gt;  6 rcu_read_unlock();&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;這裡 rcu_dereference()裡面有memory barrier，保證 p-&amp;gt;a,p-&amp;gt;b,p-&amp;gt;c僅發生在 p 被 fetch 之後。&lt;br/&gt;另外 rcu_read_lock() rcu_read_unlock() 也是必要的，它們標明了 reader-side critical section，在 preempt kernel 中，&lt;br/&gt;他們的動作就是暫時 disable preempt(前面的條件二)，在 non-preempt kernel 中，就沒事做，展開成空的 macro.&lt;br/&gt;&lt;br/&gt;先跳來看一下 rcu_dereference()&lt;br/&gt;#define rcu_dereference(p)     ({ \&lt;br/&gt;                typeof(p) _________p1 = ACCESS_ONCE(p); \&lt;br/&gt;                smp_read_barrier_depends(); \&lt;br/&gt;                (_________p1); \&lt;br/&gt;                })&lt;br/&gt;其中 ACCESS_ONCE 確保 p 不被最佳化動作影響，可以確實讀取，smp_read_barrier_depends() 意思為 "flush all pending reads that subsequents reads depend on"（使 barrier 之後的 reads 動作不受 barrier 之前的 reads 所影響).&lt;br/&gt;&lt;br/&gt;ok 言歸正傳，既然 pointer 有包裝了 memory barrier。因為 rcu 常用於 list operation，&lt;b&gt;所以 list 動作中，也有 rcu 版本的 API&lt;/b&gt;:&lt;br/&gt;&lt;br/&gt;list_add_rcu()&lt;br/&gt;list_del_rcu()&lt;br/&gt;list_replace_rcu() &lt;br/&gt;&lt;br/&gt;這些 macro 中也包裝了 memory barrier。&lt;br/&gt;&lt;br/&gt;把各種 API 做個表格來看就清楚了：&lt;br/&gt;===============================================================================================================&lt;br/&gt;Category          Publish                    Retract                                Subscribe&lt;br/&gt;&lt;br/&gt;Pointers          rcu_assign_pointer()       rcu_assign_pointer(...,NULL)            rcu_dereference()&lt;br/&gt;&lt;br/&gt;Lists              list_add_rcu()             list_del_rcu()                         list_for_each_entry_rcu()&lt;br/&gt;                   list_add_tail_rcu()&lt;br/&gt;                   list_replace_rcu()&lt;br/&gt;===============================================================================================================&lt;br/&gt;接下來看看 list 的 example，這是 updater 的程式片段:&lt;br/&gt;例四：&lt;br/&gt; 1 struct foo {&lt;br/&gt;  2   struct list_head list;&lt;br/&gt;  3   int a;&lt;br/&gt;  4   int b;&lt;br/&gt;  5   int c;&lt;br/&gt;  6 };&lt;br/&gt;  7 LIST_HEAD(head);&lt;br/&gt;  8 &lt;br/&gt;  9 /* . . . */&lt;br/&gt; 10 &lt;br/&gt; 11 p = search(head, key);&lt;br/&gt; 12 if (p == NULL) {&lt;br/&gt; 13   /* Take appropriate action, unlock, and return. */&lt;br/&gt; 14 }&lt;br/&gt; 15 q = kmalloc(sizeof(*p), GFP_KERNEL);&lt;br/&gt; 16 *q = *p;&lt;br/&gt; 17 q-&amp;gt;b = 2;&lt;br/&gt; 18 q-&amp;gt;c = 3;&lt;br/&gt; 19 list_replace_rcu(&amp;amp;p-&amp;gt;list, &amp;amp;q-&amp;gt;list);&lt;br/&gt; 20 synchronize_rcu();&lt;br/&gt; 21 kfree(p);&lt;br/&gt;其中第 16 行就是 read-copy，第 17-19 行就是 update 動作。&lt;br/&gt;&lt;br/&gt;list_replace_rcu() 如下：&lt;br/&gt;&lt;br/&gt;static inline void list_replace_rcu(struct list_head *old,&lt;br/&gt;                struct list_head *new)&lt;br/&gt;{&lt;br/&gt;    new-&amp;gt;next = old-&amp;gt;next;&lt;br/&gt;    new-&amp;gt;prev = old-&amp;gt;prev;&lt;br/&gt;    smp_wmb();&lt;br/&gt;    new-&amp;gt;next-&amp;gt;prev = new;&lt;br/&gt;    new-&amp;gt;prev-&amp;gt;next = new;&lt;br/&gt;    old-&amp;gt;prev = LIST_POISON2;&lt;br/&gt;}&lt;br/&gt;看得出來，是 list 代換加上內嵌一個 memory barrier.&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;好的，來看看 reader 的動作：&lt;br/&gt;&lt;br/&gt;例五：&lt;br/&gt;list_for_each_rcu(p, list_head) {&lt;br/&gt;  rcu_read_lock();&lt;br/&gt;  if (need_to_reference(p)) {&lt;br/&gt;    reference_without_blocking(p);&lt;br/&gt;    rcu_read_unlock();&lt;br/&gt;    break;&lt;br/&gt;  }&lt;br/&gt;  rcu_read_unlock();&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;rcu_read_lock()/rcu_read_unlock() pair 是標明 reader critical section(CS)。在 CS 裡面，如果要參考某個 link data，有個條件剛剛提過---就是 reader 不能 blocking !!&lt;br/&gt;&lt;br/&gt;總結： RCU algorithm 的動作大抵有三個部份：&lt;br/&gt;1. publish-subscribe 機制，用來給 reader 參考的，如例三與例五。&lt;br/&gt;2. 於 updater 端則是：waiting for pre-existing RCU readers to finish，如例四的 synchronize_rcu()，and&lt;br/&gt;3. maintain multiple versions to permit change w/o harming concurrent RCU readers 就是前面說的兩個條件！&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;問題 1： seqlock 也是 synchronize 機制，與 RCU 比較有何不同？&lt;br/&gt;Ans: seqlock 當遇到 updater update 資料時，會強迫 readers retry reading，但是 RCU 則不會。&lt;br/&gt;&lt;br/&gt;問題 2： 當 reader 執行 list_for_each_entry_rcu() 的同時，若是(假設另一個 CPU上) updater 也正在執行 list_add_rcu() &lt;br/&gt;( 或是 list_del_rcu(), list_replace_rcu() 等) 更改資料，這樣不會有問題嗎？&lt;br/&gt;Ans: 因為在 Linux 系統上，load/store pointer 是 atomic operation，所以 list_for_each_entry_rcu() 參考到的資料，&lt;br/&gt;可能會是原始版本的資料，或是新版本的資料，這兩種其中之一；而不會是資料 inconsistent 的情形。並且，&lt;br/&gt;list_for_each_entry_rcu() 是一路前進的參考，不會回頭，所以看到的可能是新資料 or 舊資料。 &lt;br/&gt;之後 updater 會讓所有參考到舊資料的 readers 保證可以結束 read critical section，然後才把該筆舊資料移除 或置換掉，其餘的 reader 都將讀到新資料，所以不會有問題。 &lt;br/&gt;&lt;br/&gt;&lt;/font&gt;&lt;/font&gt;這裡有個跟以前觀念上不同之處，我們以前的 CS 是保證唯一占用被保護的資源。&lt;br/&gt;但是 RCU  Reader 進入 CS 之後，並不保證他是讀到新或舊資料。讀到新舊資料的分野，是在於 updater 執行 synchronize_rcu() 的時間點，對所有的 readers，在該時間之前，所有的讀取都讀到舊資料！在該時間之後，所有的讀取都將讀到新資料！&lt;br/&gt;&lt;br/&gt;Technorati 標籤: &lt;a class='performancingtags' href='http://technorati.com/tag/RCU' rel='tag'&gt;RCU&lt;/a&gt;, &lt;a class='performancingtags' href='http://technorati.com/tag/kernel%20code' rel='tag'&gt;kernel code&lt;/a&gt;, &lt;a class='performancingtags' href='http://technorati.com/tag/synchronization' rel='tag'&gt;synchronization&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/8646454779089790212-1687836276453980308?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/1687836276453980308/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/05/rcu_26.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/1687836276453980308'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/1687836276453980308'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/05/rcu_26.html' title='RCU 初步認識'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-5471664344292903186</id><published>2009-04-20T00:30:00.000-07:00</published><updated>2009-07-07T22:29:29.672-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>慣C用法</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;這頁紀錄著一些 kernel 裡面看到的慣C用法:&lt;br/&gt;&lt;br/&gt;&lt;b&gt;1. 這種用法好像 C++ 喔!&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;static inline pte_t native_make_pte(pteval_t val)&lt;br/&gt;{&lt;br/&gt;      return (pte_t) { .pte = val };&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;p.s: pte_t 的定義要看 Phisical Address Extension (PAE) 有沒有打開，打開的話，就是一個 64 bit 的 structure, 沒有打開的話，就是一個 32 bit 的 structure:&lt;br/&gt;&lt;br/&gt;#ifdef CONFIG_X86_PAE&lt;br/&gt;  typedef     u64    pteval_t;&lt;br/&gt;  typedef     union {&lt;br/&gt;          struct {&lt;br/&gt;              unsigned long pte_low, pte_high;&lt;br/&gt;          };&lt;br/&gt;          pteval_t pte;&lt;br/&gt; } pte_t;&lt;br/&gt;...&lt;br/&gt;#else /* !CONFIG_X86_PAE */&lt;br/&gt;typedef unsigned long    pteval_t;&lt;br/&gt;typedef union {&lt;br/&gt;    pteval_t pte;&lt;br/&gt;    pteval_t pte_low;&lt;br/&gt;} pte_t;&lt;br/&gt;#endif&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;b&gt;2.常見的 per_cpu()&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;#define per_cpu(var, cpu)\&lt;br/&gt;          (*SHIFT_PERCPU_PTR(&amp;amp;per_cpu_var(var), per_cpu_offset(cpu)))&lt;br/&gt;其中&lt;br/&gt;#define SHIFT_PERCPU_PTR(__p, __offset)    RELOC_HIDE((__p), (__offset))&lt;br/&gt;&lt;br/&gt;#define RELOC_HIDE(ptr, off)                    \&lt;br/&gt;  ({ unsigned long __ptr;                    \&lt;br/&gt;    __asm__ ("" : "=r"(__ptr) : "0"(ptr));        \&lt;br/&gt;    (typeof(ptr)) (__ptr + (off)); })&lt;br/&gt;&lt;br/&gt;the `ptr' constraint "0" means `ptr' will use the same constraints with the 0th variable,&lt;br/&gt;i.e. the `__ptr'. Which has the constraints of  `='(output) and `r'(use register for the variable).&lt;br/&gt;This inline asm means : __ptr = (unsigned long) ptr; and calculate the offset &lt;br/&gt;in unit of `long' instead of `typeof(ptr)', finally return the calculated offset with the type `typeof(ptr)'&lt;br/&gt;&lt;br/&gt;now let's see the other 2 defines:&lt;br/&gt;#define per_cpu_var(var) per_cpu__##var&lt;br/&gt;&lt;br/&gt;extern unsigned long __per_cpu_offset[NR_CPUS];&lt;br/&gt;#define per_cpu_offset(x) (__per_cpu_offset[x])&lt;br/&gt;&lt;br/&gt;所以 per_cpu(var,cpu_id) 展開會得到 per_cpu__##var /*注意：雙底線*/ + __per_cpu_offset[cpu_id]&lt;br/&gt;&lt;br/&gt;例如 sys_ioperm() 裡面有這一個 C statement: &lt;br/&gt;     tss = &amp;amp;per_cpu(init_tss, get_cpu());&lt;br/&gt;展開 macro 就會得到 &lt;br/&gt;     tss = per_cpu__init_tss + __per_cpu_offset[get_cpu()];&lt;br/&gt;&lt;br/&gt;&lt;b&gt;3. 超簡潔的 struct 初始化&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;processor.h 裡頭有這樣的用法：&lt;br/&gt;&lt;font color='#3366ff'&gt;#define&lt;/font&gt; INIT_TSS  {\&lt;br/&gt;    .x86_tss = {\&lt;br/&gt;        .sp0        =&lt;font color='#3366ff'&gt; sizeof&lt;/font&gt;(init_stack) + (&lt;font color='#3366ff'&gt;long&lt;/font&gt;)&amp;amp;init_stack,\&lt;br/&gt;        .ss0        = __KERNEL_DS,\&lt;br/&gt;        .ss1        = __KERNEL_CS,\&lt;br/&gt;        .io_bitmap_base    = INVALID_IO_BITMAP_OFFSET,\&lt;br/&gt;     },\&lt;br/&gt;    .io_bitmap        = { [0 ... IO_BITMAP_LONGS] = ~0 },\&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;這個 INIT_TSS 將來會 assign 給變數型別是 struct tss_struct ，該型別定義如下：&lt;br/&gt;&lt;br/&gt;&lt;font color='#3366ff'&gt;struct&lt;/font&gt; &lt;font color='#009900'&gt;tss_struct &lt;/font&gt;{&lt;br/&gt;&lt;font color='#ff6600'&gt;    /*&lt;br/&gt;     * The hardware state:&lt;br/&gt;     */&lt;/font&gt;&lt;br/&gt;    &lt;font color='#3366ff'&gt;struct&lt;/font&gt; &lt;font color='#009900'&gt;x86_hw_tss&lt;/font&gt;   &lt;font color='#996633'&gt; &lt;font color='#cc9933'&gt;x86_tss&lt;/font&gt;&lt;/font&gt;;&lt;br/&gt;&lt;br/&gt;&lt;font color='#ff6600'&gt;    /*&lt;br/&gt;     * The extra 1 is there because the CPU will access an&lt;br/&gt;     * additional byte beyond the end of the IO permission&lt;br/&gt;     * bitmap. The extra byte must be all 1 bits, and must&lt;br/&gt;     * be within the limit.&lt;br/&gt;     */&lt;/font&gt;&lt;br/&gt;    &lt;font color='#3366ff'&gt;unsigned long&lt;/font&gt;       &lt;font color='#cc9933'&gt; &lt;font color='#996633'&gt;io_bitmap&lt;/font&gt;&lt;/font&gt;[IO_BITMAP_LONGS + 1];&lt;br/&gt; &lt;font color='#ff6600'&gt;   /*&lt;br/&gt;     * Cache the current maximum and the last task that used the bitmap:&lt;br/&gt;     */&lt;/font&gt;&lt;br/&gt;   &lt;font color='#3366ff'&gt; unsigned long&lt;/font&gt;       &lt;font color='#cc9933'&gt; &lt;font color='#996633'&gt;io_bitmap_max&lt;/font&gt;&lt;/font&gt;;&lt;br/&gt;    &lt;font color='#3366ff'&gt;struct thread_struct&lt;/font&gt;    *io_bitmap_owner;&lt;br/&gt;&lt;br/&gt; &lt;font color='#ff6600'&gt;   /*&lt;br/&gt;     * Pad the TSS to be cacheline-aligned (size is 0x100):&lt;br/&gt;     */&lt;/font&gt;&lt;br/&gt;    &lt;font color='#3366ff'&gt;unsigned long&lt;/font&gt;        &lt;font color='#996633'&gt;__cacheline_filler&lt;/font&gt;[35];&lt;br/&gt; &lt;font color='#ff6600'&gt;   /*&lt;br/&gt;     * .. and then another 0x100 bytes for the emergency kernel stack:&lt;br/&gt;     */&lt;/font&gt;&lt;br/&gt;    &lt;font color='#3366ff'&gt;unsigned long&lt;/font&gt;       &lt;font color='#996633'&gt; stack&lt;/font&gt;[64];&lt;br/&gt;&lt;br/&gt;} &lt;font color='#3366ff'&gt;__attribute__&lt;/font&gt;((packed));&lt;br/&gt;&lt;br/&gt;&lt;font color='#3366ff'&gt;struct&lt;/font&gt;&lt;font color='#009900'&gt; x86_hw_tss&lt;/font&gt; {&lt;br/&gt;    &lt;font color='#3366ff'&gt;unsigned short&lt;/font&gt;       &lt;font color='#999900'&gt; &lt;/font&gt;&lt;font color='#666600'&gt;&lt;font color='#996633'&gt;back_link, __blh&lt;/font&gt;;&lt;/font&gt;&lt;br/&gt;    &lt;font color='#3366ff'&gt;unsigned long&lt;/font&gt;        &lt;font color='#996633'&gt;sp0&lt;/font&gt;;&lt;br/&gt;    &lt;font color='#3366ff'&gt;unsigned short&lt;/font&gt;        &lt;font color='#996633'&gt;ss0, __ss0h&lt;/font&gt;;&lt;br/&gt;   &lt;font color='#3366ff'&gt; unsigned long&lt;/font&gt;        &lt;font color='#996633'&gt;sp1&lt;/font&gt;;&lt;br/&gt; ...省略&lt;br/&gt;} &lt;font color='#3366ff'&gt;__attribute__&lt;/font&gt;((packed));&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img class='zemanta-pixie-img' src='http://img.zemanta.com/pixy.gif?x-id=951e91e0-879c-8ee7-85d5-74a68179a2cf'/&gt;&lt;br/&gt;&lt;br/&gt;這樣用法相當簡潔，連同 sub structure 的初始化都可以一口氣完成！&lt;br/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-5471664344292903186?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/5471664344292903186/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/04/c.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/5471664344292903186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/5471664344292903186'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/04/c.html' title='慣C用法'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-7124875866686547024</id><published>2009-02-15T19:41:00.000-08:00</published><updated>2009-06-12T03:06:38.221-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>libusb 的底層追蹤 (libusb thread support and the relation with kernel usbfs)</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;因為做 project，無意間找到了Greg KH 大師級的文章-- [&lt;a href='http://www.linuxjournal.com/node/7582/' target='_blank'&gt;Snooping the USB Data Stream&lt;/a&gt;] 文中有一段提到 kernel 對 usbfs 的支援，讓 application 可直接透過 usbfs 對 device 發出 usb transfer，實做於devio.c, inode.c, and devices.c 等三個 kernel sources. （note: 我這裡的 kernel version 是 2.6.26）&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;而另一方面，在 application library 端，就是依靠 usbfs 的幫忙，發展出 [&lt;a href='http://libusb.sourceforge.net/api-1.0/index.html' target='_blank'&gt;libusb project&lt;/a&gt;] 1.0.0  版，但在 debian testing 的套件裏，還只包到 libusb-0.1.12，若要 library header 檔，請安裝 libusb-dev 套件。&lt;br/&gt;&lt;br/&gt;從 0.1.12 到 1.0.0 做了許多改變，除了 API 幾乎重新定之外，最明顯的是增加了 thread 的支援，但是兩者在最底層的系統呼叫，都是使用了 usbfs 提供的 I/O control。因為 1.0.0 的設計蠻複雜的，所以我還是以 0.1.12 來追蹤（其實是功力不夠啦！）以下就是一些 0.1.12 追蹤的筆記：&lt;br/&gt;&lt;br/&gt;&lt;font face='monospace'&gt;in libusb-0.1.12:&lt;br/&gt;&lt;/font&gt;&lt;font face='monospace'&gt;&lt;br/&gt;usb_bulk_read()          &lt;/font&gt;&lt;font face='monospace'&gt;usb_interrupt_read()&lt;br/&gt;&lt;/font&gt;&lt;font face='monospace'&gt;usb_bulk_write()   與    usb_interrupt_write() &lt;br/&gt;       :                      :&lt;br/&gt;       V                      V&lt;br/&gt;   USB_URB_TYPE_BULK      USB_URB_TYPE_INTERRUPT&lt;br/&gt;                 :           :&lt;br/&gt;                 :           :&lt;br/&gt;                 V           V&lt;br/&gt;               usb_urb_transfer()&lt;br/&gt;&lt;br/&gt;&lt;/font&gt;usb_urb_transfer() 大致上流程，僅僅提供了 synchronous 的傳送方式(就是呼叫之後就等待它完成)---在 0.1.12 的介面上並沒有提供 asynchronous 的方式（就是呼叫後就離開，將來 urb 收/送完成後，系統會呼叫 complete function），注意：這是 libusb-0.1.12 並沒有提供 asynchronous 的函數，但是 kernel 的 IOCTL_USB_SUBMITURB 工作方式卻都是 asynchronous 的動作，等下追蹤 kernel 的部份時就會知道了。&lt;br/&gt;usb_urb_transfer() 用 IOCTL_USB_SUBMITURB 送出 urb 之後，然後一直重複使用 IOCTL_USB_REAPURBNDELAY 來收取completed urb  ，並且把使用者傳入的 timeout 切成 1ms 的單位用 select() 來等待。結果有幾種：&lt;br/&gt;1. select() 等到了 I/O 動作，REAPURB 得到了某個 completed urb ，返回值是所收送的 data 長度。&lt;br/&gt;2. select() 等不到 I/O 動作，重複 1ms 的 select()等待，一直到 timeout 了，返回值是 -ETIMEDOUT&lt;br/&gt;&lt;br/&gt;usb_urb_transfer() 有一段註解，是這樣說的，直接節錄下來：&lt;br/&gt;&lt;br/&gt;&lt;font color='#660000'&gt;#define URB_USERCONTEXT_COOKIE        ((void *)0x1)&lt;br/&gt;&lt;br/&gt;&lt;/font&gt;&lt;font color='#660000'&gt;  /*&lt;br/&gt;   * HACK: The use of urb.usercontext is a hack to get threaded applications&lt;br/&gt;   * sort of working again. Threaded support is still not recommended, but&lt;br/&gt;   * this should allow applications to work in the common cases. Basically,&lt;br/&gt;   * if we get the completion for an URB we're not waiting for, then we update&lt;br/&gt;   * the usercontext pointer to 1 for the other threads URB and it will see&lt;br/&gt;   * the change after it wakes up from the the timeout. Ugly, but it works.&lt;br/&gt;   */&lt;br/&gt;&lt;/font&gt;&lt;br/&gt;雖然這裡說 Threaded application 可以 work ！ 根據這段註解說，使用了 urb.usercontext 來"標示" reapped urb---若不是我們的 urb 就把該 urb.usercontext 設定為 URB_USERCONTEXT_COOKIE，以便讓另一個 thread 可以 reap：&lt;b&gt;但是另一個 thread 可以 reap 到這個作了 cookie 記號的 urb 嗎？&lt;br/&gt;&lt;/b&gt;&lt;br/&gt;追蹤到這裡，我們不得不往 kernel 的 devio.c 追蹤，要徹底了解 kernel 提供 usbfs 的動作才能解答這個問題...&lt;br/&gt;&lt;br/&gt;首先從  IOCTL_USB_SUBMITURB 開始找線索，因為這個是 libusb 定義的 I/O control code，kernel 裏相對應的是 USBDEVFS_SUBMITURB I/O control code，負責處理這個 I/O control code  的是 proc_submiturb(ps, p); 其中 ps 與 p 分別是&lt;br/&gt;&lt;br/&gt;   struct dev_state *ps = file-&amp;gt;private_data;&lt;br/&gt;   void __user *p = (void __user *)arg;&lt;br/&gt;&lt;br/&gt;arg 是 user 由 ioctl system call 傳入的 argument pointer，這裡傳入 user urb。&lt;br/&gt;&lt;b&gt;ps 是 usbdev_open() 時 allocated 得到的&lt;/b&gt;，定義為 ：&lt;br/&gt;&lt;br/&gt;&lt;font color='#000000'&gt;struct dev_state {&lt;br/&gt;    struct list_head list;      /* state list */&lt;br/&gt;    struct usb_device *dev;&lt;br/&gt;    struct file *file;&lt;br/&gt;    spinlock_t lock;            /* protects the async urb lists */&lt;br/&gt;&lt;font color='#990000'&gt;    struct list_head async_pending;&lt;br/&gt;    struct list_head async_completed;&lt;br/&gt;&lt;font color='#000000'&gt;    &lt;/font&gt;&lt;/font&gt;&lt;font color='#000000'&gt;wait_queue_head_t wait;     &lt;/font&gt;/* wake up if a request completed */&lt;br/&gt;    unsigned int discsignr;&lt;br/&gt;    struct pid *disc_pid;&lt;br/&gt;    uid_t disc_uid, disc_euid;&lt;br/&gt;    void __user *disccontext;&lt;br/&gt;    unsigned long ifclaimed;&lt;br/&gt;    u32 secid;&lt;br/&gt;};&lt;/font&gt;&lt;font color='#336666'&gt;&lt;br/&gt;&lt;br/&gt;&lt;/font&gt;&lt;font color='#000000'&gt;可以把這個資料結構看成 process 對於這個 device 的傳送 urb 的狀態紀錄. 其中兩個 list 分別是 urb 送出後就把對應的 async 由 async_pending 紀錄，等 urb complete 之後就把對應的 async 由 async_completed 紀錄，async 是甚麼呢？&lt;font color='#000000'&gt;對於&lt;/font&gt;&lt;font color='#000000'&gt;每個 urb 都有一個對應的 async data structure，是在 proc_do_submiturb() 時 allocate 得到的 &lt;/font&gt;。async 的資料結構為：&lt;br/&gt;&lt;br/&gt;struct async {&lt;br/&gt;    struct list_head asynclist;&lt;br/&gt;&lt;font color='#990000'&gt;    struct dev_state *ps;&lt;/font&gt;&lt;br/&gt;    struct pid *pid;&lt;br/&gt;    uid_t uid, euid;&lt;br/&gt;    unsigned int signr;&lt;br/&gt;    unsigned int ifnum;&lt;br/&gt;    void __user *userbuffer;&lt;br/&gt;&lt;font color='#990000'&gt;    void __user *userurb;&lt;br/&gt;    struct urb *urb;&lt;/font&gt;&lt;br/&gt;    int status;&lt;br/&gt;    u32 secid;&lt;br/&gt;};   &lt;br/&gt;&lt;br/&gt;對每個 urb 都有一個 async 紀錄，在 proc_do_submiturb() 時 allocate 得到，同時它也會紀錄 user urb 的位置，將來可以把 urb 所得的資料 copy 回 user urb。&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;font color='#000000'&gt;整個 urb 的流程為： &lt;/font&gt;&lt;br/&gt;proc_submiturb()&lt;/font&gt;&lt;font color='#000000'&gt;: 把 user's urb(user space) 拷貝一份到我們的 uurb (kernel space)&lt;/font&gt;&lt;br/&gt;&lt;font color='#000000'&gt;-&amp;gt;proc_do_submiturb(): 根據 bulk,interrupt..等 type 分別 initial 一些欄位，然後 allocate async data structure (裡面還包含 urb)，然後放入 ps-&amp;gt;async_pending queue 做紀錄，接著呼叫 usb_submit_urb() （之後就交給 usb host controller 處理了）然後不等結果就返回， 所以我們說 kernel 這裡是以 asynchronous 的方式處理 urb !&lt;br/&gt;&lt;br/&gt;等 usb host controller 把 urb 處理完後，會呼叫 async_complete()，async_complete() 將 async 紀錄從 ps-&amp;gt;async_pending 移到 ps-&amp;gt;completed.&lt;br/&gt;&lt;br/&gt;另一方面 user 要透過 IOCTL_USB_REAPURBNDELAY "收割" 已完成的 urb ，對應到 kernel 為 USBDEVFS_REAPURBNDELAY。這個 I/O control 會呼叫 proc_reapurbnonblock()，它會巡視 ps-&amp;gt;completed 是否有 async 紀錄，若無則返回 -EAGAIN，若有則把找到的 urb (kernel space) 資料拷貝到 user space，並設定 IOCTL_URB_REAPURBNDELAY 時傳入的 arg 指向 user space urb，至此，kernel 傳送的部份已經完成。&lt;br/&gt;&lt;br/&gt;好，kernel 的部份至此大致了解，接下來討論我們的疑問，我們分兩種情形討論：&lt;br/&gt;&lt;b&gt;1. 每一個 thread 都使用同一個 open handle&lt;/b&gt;, 也就是在 kernel 裡面同一份 ps：&lt;br/&gt;  當 IOCTL_USB_REAPURBNDELAY 時，在 kernel 裡，會取出 ps-&amp;gt;completd 上已完成 urb ，但是並不知道是哪一個 thread 的 urb ，因此 libusb 使用 cookie 作記號；&lt;/font&gt;&lt;font color='#000000'&gt;在 usb_urb_transfer() 時，&lt;/font&gt;&lt;font color='#000000'&gt;每一個 thread 在自己的 thread stack 上宣告一個 user space urb，如果第一個 thread reap 到不屬於自己的 urb 就打上 cookie 並繼續從 kernel reap 其他的 urb，此時當第二個 thread reap urb 時，就從 ps-&amp;gt;completed 再抓一個 ... of course ，&lt;b&gt;這樣第二個 thread 就收不到該收的 urb 了&lt;/b&gt;，錯誤就產生了。&lt;br/&gt;&lt;br/&gt;&lt;b&gt;2. &lt;/b&gt;&lt;/font&gt;&lt;font color='#000000'&gt;&lt;b&gt;每一個 thread 各自開了 open handle&lt;/b&gt;, 也就是在 kernel 裡面對應各自的 ps：&lt;/font&gt;&lt;br/&gt;  這樣每個 thread 都對應了自己的 ps-&amp;gt;completed list，&lt;b&gt;所收的 urb 不會混淆，好像也不需要 cookie 了喔&lt;/b&gt;！但是這樣有一個缺點：bulk transfer 之前要 claim interface---就是每個 thread 要使用 usb_urb_transfer() 時必須先 claim interface...，所以原來已經 claim interface 的 thread 要 release interface，那就要把之前該 thread 的 urb 結束掉才行囉，&lt;b&gt;這樣多個 thread "interleave urbs transfer" 的本意就沒了啊！&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;所以結論是：若想以 thread 的方式使用 usblib-0.1.12，大概自己要動手改 usb_urb_transfer() 的部份，否則就直接用 usblib-1.0.0 。&lt;br/&gt;&lt;font color='#000000'&gt;&lt;br/&gt;&lt;/font&gt;&lt;div class='blogger-post-footer'&gt;&lt;img width='1' height='1' src='http://res1.blogblog.com/tracker/8646454779089790212-7124875866686547024.gif?l=rd-life.blogspot.com'/&gt;&lt;/div&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img class='zemanta-pixie-img' src='http://img.zemanta.com/pixy.gif?x-id=50d3c595-2b81-4a20-bc6b-58026257948b'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-7124875866686547024?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/7124875866686547024/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/02/libusb-libusb-thread-support-and_15.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/7124875866686547024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/7124875866686547024'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/02/libusb-libusb-thread-support-and_15.html' title='libusb 的底層追蹤 (libusb thread support and the relation with kernel usbfs)'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-4234636814531131219</id><published>2009-02-12T02:00:00.000-08:00</published><updated>2009-05-26T00:35:32.065-07:00</updated><title type='text'>繼續 R&amp;D 的旅行</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;從 [&lt;a href='http://blog.roodo.com/use_the_force'&gt;樂多&lt;/a&gt;] 移到這裡，是為了編輯方便！，繼續紀錄我的 R&amp;amp;D life....&lt;br/&gt;&lt;br/&gt;下面來看一段&lt;a target='_blank' href='http://www.youtube.com/watch?v=RxI2QOe9DW0'&gt;影片&lt;/a&gt;吧！這是我家小貢丸第一次上台喔！&lt;br/&gt;看他毫不怯場的揮手，希望他以後上台都可以保持這麼大方的態度呢！&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img class='zemanta-pixie-img' src='http://img.zemanta.com/pixy.gif?x-id=2df4759f-9c84-45ff-a77d-09cefbe1c72f'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-4234636814531131219?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/4234636814531131219/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/02/r.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/4234636814531131219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/4234636814531131219'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/02/r.html' title='繼續 R&amp;amp;D 的旅行'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8646454779089790212.post-4726299546041482840</id><published>2009-01-20T20:21:00.000-08:00</published><updated>2010-03-25T02:57:20.212-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>使用cscope 取代 source insight 以瀏覽 kernel source</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;h3 class='title'&gt;&lt;br/&gt;&lt;br/&gt;						&lt;/h3&gt;&lt;br/&gt;						&lt;div class='main'&gt;&lt;br/&gt;										解決linux下代碼查看問題 &lt;br/&gt;&lt;p&gt;在 Windows 下面我們有 Source Insight 可以方便的瀏覽大工程中的代碼，切換到 Linux 環境下開發時， 我們也可以搭建一個這樣的環境。下面的內容將介紹如何搭建這樣一個開發環境(這裡我們假設讀者已經熟悉 emacs 的安裝和配置)。 &lt;br/&gt;　　步驟一安裝下列軟件 &lt;br/&gt;　&lt;br/&gt;　1)cscope ：cscope是一個代碼瀏覽工具，它可以幫你在一個大的工程中，&lt;br/&gt;快速定位到一個函數/變量的聲明位置，所有引用地方等，它可以結合vim和emacs一起使用。&lt;br/&gt;單獨使用cscope時不同文件間的跳轉變得很難處理，這裡我們介紹cscope在emacs環境中的使用，它需要預先建立索引檔：根據&lt;br/&gt;cscope.files 的內容來建立索引：cscope.[in][out]。&lt;br/&gt;&lt;br/&gt;　　步驟二修改或創建.emacs文件 &lt;br/&gt;　　;;加載我們需要的plugin (使用cscope的必備動作) &lt;br/&gt;&lt;font color='#993300'&gt;&lt;font color='#ff0000'&gt;(load-file "/usr/share/emacs/site-lisp/xcscope.el")&lt;br/&gt;(require 'xcscope)&lt;br/&gt;(setq cscope-do-not-update-database "t")&lt;/font&gt;&lt;/font&gt; &lt;font color='#008000'&gt; &lt;/font&gt;&lt;font color='#008000'&gt;;;&lt;/font&gt;&lt;font color='#99cc00'&gt;&lt;font color='#008000'&gt; &lt;/font&gt;&lt;font color='#008000'&gt;這行後面會解釋&lt;/font&gt;&lt;br/&gt;&lt;/font&gt;&lt;font color='#ffff00'&gt;&lt;font color='#ff0000'&gt;(setq cscope-set-initial-directory "./")  &lt;font color='#008000'&gt;;; 在現有目錄下找 cscope.out&lt;/font&gt;&lt;/font&gt;  &lt;/font&gt;&lt;/p&gt;&lt;p&gt;      步驟三添加工程：&lt;br/&gt;　　假設我們要把/home/tom/src/linux-2.6.23的源代碼做出cscope索引，我們可以這樣做，&lt;/p&gt;&lt;p&gt;      &lt;b&gt; #&amp;gt;&lt;font face='monospace'&gt;make ARCH=arm cscope&lt;/font&gt;&lt;/b&gt;&lt;b&gt;  &lt;/b&gt;這裡 ARCH 可以等於 arm, x86, mips,  ...等等你想要的 CPU arch。&lt;br/&gt;&lt;/p&gt;&lt;p&gt;      &lt;big&gt;&lt;big&gt;&lt;big&gt;&lt;big&gt;&lt;b&gt;&lt;font face='tahoma'&gt; &lt;small&gt;或&lt;/small&gt;&lt;/font&gt;&lt;/b&gt;&lt;/big&gt;&lt;/big&gt;&lt;/big&gt;&lt;/big&gt;手動自己來：&lt;br/&gt;&lt;/p&gt;&lt;p&gt;　　1)&lt;b&gt;&lt;font face='monospace'&gt;#&amp;gt;cd /home/tom/src/linux-2.6.23&lt;/font&gt;&lt;/b&gt; 進入源代碼根目錄; &lt;br/&gt;　　2)&lt;b&gt;&lt;font face='monospace'&gt;#&amp;gt;touch cscope.sh&lt;/font&gt;&lt;/b&gt; 創建一個腳本文件，內容如下 &lt;/p&gt;&lt;blockquote&gt;&lt;font size='3' color='#000000'&gt;#!/bin/bash &lt;br/&gt;&lt;/font&gt;&lt;font color='#000000'&gt; LNX=`pwd`&lt;br/&gt;ARCH=arm&lt;br/&gt;    cd / 	&lt;br/&gt;    find  $LNX/                                                                \&lt;br/&gt;	-path "$LNX/arch/*" ! -path "$LNX/arch/$ARCH*" -prune -o               \&lt;br/&gt;	-path "$LNX/include/asm-*" ! -path "$LNX/include/asm-$ARCH*" -prune -o \&lt;br/&gt;	-path "$LNX/tmp*" -prune -o                                           \&lt;br/&gt;	-path "$LNX/Documentation*" -prune -o                                 \&lt;br/&gt;	-path "$LNX/scripts*" -prune -o                                       \&lt;br/&gt;	-path "$LNX/drivers*" -prune -o                                       \&lt;br/&gt;        -name "*.[chxsS]" -print &amp;gt;$LNX/cscope.files&lt;br/&gt;find $LNX/ -path "$LNX/include/asm-generic*" -name "*.[chxsS]" -print &amp;gt;&amp;gt; $LNX/cscope.files&lt;br/&gt;&lt;/font&gt;&lt;/blockquote&gt;&lt;p&gt;　然後 &lt;b&gt;#&amp;gt;cscope -b -k -q&lt;/b&gt; ( -q 是建立雙向鏈結，可增加搜尋速度！)，這時候要等個幾分鐘，等待索引的建立！因為針對 ARCH=arm 來做，所以建出以 arm 為主的索引檔。&lt;/p&gt;&lt;p&gt;    成功後執行 cscope.sh 腳本。&lt;/p&gt;&lt;p&gt;　　步驟四：關於cscope代碼瀏覽命令 &lt;br/&gt;            C-c s a 設定初始化的目錄(cscope-set-initial-directory) ，一般是你代碼的根目錄，為了省事，我們可以把這一行命令在進入 emacs 就執行，像剛剛的 .emacs 範例一樣。&lt;br/&gt;        &lt;img border='0' title='鬼' alt='鬼' src='http://static.roodo.com/blog/emotion/7.gif'/&gt; C-c s &lt;font size='3'&gt;I&lt;/font&gt;             (i 大寫) 對目錄中的相關文件建立列表並進行索引。內定會自動建立索引。記得嗎？我們剛剛做過索引了，並用 -q 參數，所以&lt;strong&gt;這裡不但不要用這個指令&lt;/strong&gt;，(在 emacs 外面用 -q 建索引就好)，&lt;strong&gt;還應該要 disable 自動建索引的功能&lt;/strong&gt;，因為在 emacs 裡面會主動呼叫 cscope 建立索引。所以剛剛我們修改了(setq cscope-do-not-update-database "t")。&lt;/p&gt;&lt;p&gt;&lt;font color='#0000ff'&gt;若不這樣改，在自動建立索引時會抱怨 -q 與 database 不合的警告，重建的 database 也將喪失雙向搜尋的能力，用起來會變得蠻慢的喔！因為 kernel symbol 實在太多了！&lt;br/&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;            C-c s s             序找符號&lt;br/&gt;            C-c s g             尋找全局的定義(即是 cscope-find-global-definition)&lt;br/&gt;            C-c s c             看看指定函數被哪些函數所調用&lt;br/&gt;            C-c s C             看看指定函數調用了哪些函數&lt;br/&gt;            C-c s e             尋找正則表達式&lt;br/&gt;            C-c s f             尋找文件&lt;br/&gt;            C-c s i             看看指定的文件被哪些文件include&lt;br/&gt;            C-c s u 回到上一個 symbol  (即cscope-pop-mark)&lt;br/&gt; &lt;/p&gt;&lt;p&gt;結論：Source Insight 雖然直覺好用，但是你還得找到 Windows 環境才能 run，用wine 模擬 Windows 是一個辦法啦！這裡只是提供了『純 Linux 環境』的做法，供大家參考！&lt;br/&gt;  &lt;/p&gt;&lt;p&gt;&lt;font color='#000000' style='background-color: rgb(192, 192, 192);'&gt;補充&lt;/font&gt;：用 etags 配合使用，更方便：(假設已經裝好 ctags 套件)        &lt;/p&gt;&lt;p&gt;       1)   在進入 emacs 之前先用 etags -R 建立 TAG 檔。&lt;br/&gt;在 emacs 裏面的指令：&lt;br/&gt;       2)    M-x visit-tags-table 會詢問是否用 default TAG file? 按 y 即可。&lt;br/&gt;        3)   M-. 找定義，以游標所在位置的變數來找。&lt;br/&gt;        4)   M-*                                     返回。&lt;br/&gt;       5)   C-u M-. 尋找標籤的下一個定義。&lt;/p&gt;&lt;br/&gt;&lt;font color='#000000' style='background-color: rgb(192, 192, 192);'&gt;補充&lt;/font&gt;：修改 .emacs 取代常用的 cscope 命令，在 (require 'xcscope) 後加上&lt;br/&gt;(define-key global-map [f5] 'cscope-find-this-file)&lt;br/&gt;(define-key global-map [f6] 'cscope-find-this-symbol)&lt;br/&gt;(define-key global-map [f7] 'cscope-pop-mark)&lt;br/&gt;(define-key global-map [f8] 'cscope-find-global-definition)&lt;br/&gt;(define-key global-map [f9] 'cscope-find-global-definition-no-prompting)&lt;br/&gt;(define-key global-map [M-up] 'cscope-prev-symbol)&lt;br/&gt;(define-key global-map [M-down] 'cscope-next-symbol)&lt;br/&gt;(define-key global-map [f12] 'c-down-conditional-with-else)&lt;br/&gt;(define-key global-map [M-f12] 'c-up-conditional-with-else)&lt;br/&gt;&lt;br/&gt;這樣，就可以用 F5, F6, F7, F8, F9 Esc-↑ Esc-↓ 來 browse code，您可以把常用的 key 如法泡製。&lt;/div&gt;&lt;a rel='tag' href='http://technorati.com/tag/Setting' class='performancingtags'&gt;&lt;br/&gt;&lt;br/&gt;&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=c2671ea2-ce33-8901-80ab-594bb359f38d' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8646454779089790212-4726299546041482840?l=rd-life.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rd-life.blogspot.com/feeds/4726299546041482840/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rd-life.blogspot.com/2009/01/cscope-source-insight-kernel-source.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/4726299546041482840'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8646454779089790212/posts/default/4726299546041482840'/><link rel='alternate' type='text/html' href='http://rd-life.blogspot.com/2009/01/cscope-source-insight-kernel-source.html' title='使用cscope 取代 source insight 以瀏覽 kernel source'/><author><name>湯姆熊</name><uri>http://www.blogger.com/profile/01669234462144281117</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_2BsMdsyWdAg/SlRFjggyOuI/AAAAAAAAADY/Jmje_jIf97I/S220/stumbleupon_48.png'/></author><thr:total>0</thr:total></entry></feed>
