<?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-975103007691482821</id><updated>2011-10-19T14:30:15.395-07:00</updated><category term='virtualization'/><category term='bootloader'/><category term='CodeHighlighting'/><category term='L4'/><category term='userspace'/><category term='pistachio'/><category term='kickstart'/><category term='antlr'/><category term='MobiNaf C#'/><category term='HTML'/><title type='text'>Tec Tips Reminder</title><subtitle type='html'>Record some knowledges and ideas in this blog.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>60</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-9097012616669334239</id><published>2011-09-02T15:22:00.000-07:00</published><updated>2011-09-02T15:23:29.693-07:00</updated><title type='text'>what is LMA in objdump?</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div closure_uid_u9bzp3="81"&gt;I am wondering what is LMA in the output of &lt;code&gt;objdump -h&lt;/code&gt;. Finally, I find &lt;a href="http://www-zeuthen.desy.de/dv/documentation/unixguide/infohtml/binutils/docs/ld/Basic-Script-Concepts.html#Basic-Script-Concepts"&gt;this&lt;/a&gt;. And it explains VMA/LMA as following:&lt;/div&gt;&lt;div closure_uid_u9bzp3="81"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div closure_uid_u9bzp3="81"&gt;&lt;blockquote&gt;&lt;div closure_uid_6hm760="60"&gt;Every loadable or allocatable output section has two addresses. The first is the &lt;dfn&gt;VMA&lt;/dfn&gt;, or virtual memory address. This is the address the section will have when the output file is run. The second is the &lt;dfn&gt;LMA&lt;/dfn&gt;, or load memory address. This is the address at which the section will be loaded. In most cases the two addresses will be the same. An example of when they might be different is when a data section is loaded into ROM, and then copied into RAM when the program starts up (this technique is often used to initialize global variables in a ROM based system). In this case the ROM address would be the LMA, and the RAM address would be the VMA&lt;/div&gt;&lt;/blockquote&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/975103007691482821-9097012616669334239?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/9097012616669334239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=9097012616669334239' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/9097012616669334239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/9097012616669334239'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2011/09/what-is-lma-in-objdump.html' title='what is LMA in objdump?'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-1003960689879235618</id><published>2010-05-25T09:55:00.001-07:00</published><updated>2010-05-25T10:06:55.867-07:00</updated><title type='text'>Note: GCC - link static library</title><content type='html'>We can generate our own static library. That is not a big problem. Firstly, compile the source file and then use "ar" to generate the .a library. But the problem is if you want to use you library, in GCC you have to put static library at the end of compiling command. For example, we have three file:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&lt;br /&gt;dummy_lib.h&lt;br /&gt;dummy_lib.cc&lt;br /&gt;main.cc&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;We create a static library with the first file:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&lt;br /&gt;$ g++ -c dummy_lib.cc&lt;br /&gt;$ ar cvq libdummy.a dummy_lib.o&lt;br /&gt;$ ranlib -t libdummy.a&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Then the following statement won't work if there is something in dummy_lib is required by main.cc&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&lt;br /&gt;$ g++ -o output -L./ -ldummy_lib main.cc&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;since gcc will discard the library dummy_lib before it is going to compile main.cc. Instead we have to do:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&lt;br /&gt;$ g++ -o output -L./ main.cc -ldummy_lib&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This is kind of annoying, but have to remember.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-1003960689879235618?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/1003960689879235618/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=1003960689879235618' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/1003960689879235618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/1003960689879235618'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2010/05/note-gcc-link-static-library.html' title='Note: GCC - link static library'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-1698552155450536440</id><published>2010-03-04T22:41:00.000-08:00</published><updated>2010-03-14T00:38:07.980-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>L4 Exercises(1) - Construct Test Env in Mac OSX</title><content type='html'>Just a simple introduction for how to construct experiment environment for L4-Pistachio under Mac OSX. The only requirement for my way is that you have VM Fusion installed. The model I used is consisted of two VMs. One as build machine and tftp boot server, the other as crash machine. You can argue that you can use Mac OSX as build machine. I tried and in my opinion cross compiling is possible but complicated and unclear. Although I successfully build a L4 kernel with cross compiling, I still prefer using virtual machine, since I am not good at cross compiling.&lt;br /&gt;&lt;br /&gt;In the build VM, you need to install:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;g++&lt;/li&gt;&lt;li&gt;autoconfig&lt;/li&gt;&lt;li&gt;autoheader&lt;/li&gt;&lt;li&gt;HG Mercury&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;You can get source from &lt;code&gt;http://hg.l4ka.org/l4ka-pistachio&lt;/code&gt; with HG. You have to build kernel/ and user/ separated. Type "make" under kernel/ will give you more instructions for building it. Read README.HG for special instruments for building user/ part. It is not difficult to get it.&lt;br /&gt;&lt;br /&gt;Since I use the build VM as tftp boot server too, I have to install tftpd on it. My host system in build VM is Ubuntu, &lt;a href="http://www.davidsudjiman.info/2006/03/27/installing-and-setting-tftpd-in-ubuntu/"&gt;this site&lt;/a&gt; will instruct you how to set up tftp server in Ubuntu. Then we have to modify VM Fusion's configuration so that crash VM can be booted through a network source.&lt;br /&gt;&lt;br /&gt;First of all, &lt;a href="http://communities.vmware.com/servlet/JiveServlet/download/718890-1931/VMware%20Fusion%20Network%20Settings%20-%20Part%201.pdf"&gt;this article&lt;/a&gt; is very helpful for finding configuration files of VM fusion. Two virtual networks are available after you install VM fusion, i.e. vmnet1 and vmnet8. vmnet1 is usually used for host only network, which is "private", i.e. VMs inside this network can only communicate with each other and the host system. For example, a VM inside vmnet1 can not access another one inside vmnet8. vmnet8 is NAT network. No matter what kind of network you selected for your VMs, i.e. build and crash. Both of them should be in the same network, so that they can talk to each other. To allow the tftp function, you only need to modify file dhcpd.conf under either vmnet1/ or vmnet8/, depend on your VMs network setting, and add following line:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;subnet 192.168.7.0 netmask 255.255.255.0 {&lt;br /&gt;    range 192.168.7.128 192.168.7.254;&lt;br /&gt;    next-server 192.168.7.128;&lt;br /&gt;    option broadcast-address 192.168.7.255;&lt;br /&gt;    option domain-name-servers 192.168.7.2;&lt;br /&gt;    option domain-name localdomain;&lt;br /&gt;    default-lease-time 1800;                # default is 30 minutes&lt;br /&gt;    max-lease-time 7200;                    # default is 2 hours&lt;br /&gt;    option routers 192.168.7.2;&lt;br /&gt;    allow booting;&lt;br /&gt;    allow bootp;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The IP in next-server is the IP of your build VM. After this, you need to restart server with command:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;    $sudo ./boot.sh --restart&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Then it is ready to boot from network. One thing more for booting is that you need to download a floppy image from &lt;a href="http://i30www.ira.uka.de/%7Eud3/mkgrubdisk"&gt;this site&lt;/a&gt;. Using it for your crash VM's floppy driver. Then your crash VM is ready for booting from build VM.&lt;br /&gt;&lt;br /&gt;Finally, you need a way to debug the kernel. Of course you need to enable this function before you build kernel through command &lt;code&gt;make menuconfig&lt;/code&gt;. Then you have to specify your VM to have a serial port. By default, VM fusion create a file for serial port output, but it is not useful in our case. Fortunately, it still support named pipe solution for serial port. You need go into your VMs package directory under command line and find "&lt;code&gt;.vmx&lt;/code&gt;" file. Looking for keyword "pipe" and seting it as following:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;    erial0.fileType = &amp;quot;pipe&amp;quot;&lt;br /&gt;    serial0.pipe.endPoint = &amp;quot;server&amp;quot;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Also you need a tool to connect to your crash VM's serial port so that it can send command and get output from crash VM. I use minicom, which can be installed through &lt;a href="http://darwinports.com/"&gt;Darwinports&lt;/a&gt;. To configure the minicom to connect to crash VM, you need to create a minicom file by using:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;    $sudo minicom -s vmcrash&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;After the configuration page comes out, select "Serial port setup" and then press "A" to setup Serial Device. The path should be set like:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;    unix#/Volumes/MacSpace/CrashMachine/crashvm&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Then save and quit. Next time, after you start crash VM, you start minicom like:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;    $sudo minicom crashvm&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;It will connect to the serial pipe created by crash VM.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-1698552155450536440?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/1698552155450536440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=1698552155450536440' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/1698552155450536440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/1698552155450536440'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2010/03/l4-exercises-1-construct-test.html' title='L4 Exercises(1) - Construct Test Env in Mac OSX'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-5609147861191372258</id><published>2009-11-21T05:17:00.001-08:00</published><updated>2010-03-13T16:44:59.274-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='userspace'/><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>Life in the userspace(6) - PingPong</title><content type='html'>Finally, I am in this point. From now on, I am going to talk how to write a app for L4. The basic design concept in L4 is using L4 as a base layer and upon the base layer different apps is able to be hosted. Apps can also be understood as service in my opinion. L4 guys deliver three apps as example in there source tree. They are located in &lt;code&gt;user/apps/&lt;/code&gt;. "pingpong" shows you the way to start thread in L4. "grabmem" shows you how to require memory from Sigma0. And "l4test" is a complicated app which allows user to try different APIs of L4. I will explain "pingpong" today.&lt;br /&gt;&lt;br /&gt;"pingpong" is quite simple. It is used to test the performance of IPC, LIPC, even inter-processor IPC. It is consists of 4 threads, i.e. root thread, pager thread, ping thread, pong thread. However there can be 2 or 3 address space. Depending on which kind of IPC test you select, ping and pong threads reside either in the same AS (LIPC) or different AS (IPC).&lt;br /&gt;&lt;br /&gt;The files used for IA32 are following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;pingpong.cc&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;ia32.h&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;crt0-ia32.S&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;code&gt;pingpong.cc&lt;/code&gt; implements common codes for different architecture. &lt;code&gt;ia32.h&lt;/code&gt; includes the special implementation of page handling and ipc in IA32 architecture. Furthermore it shows the way to measure performance in IA32 architecture.&lt;code&gt;crt0-ia32.S&lt;/code&gt; is the C run time stub and has been discussed before.&lt;br /&gt;&lt;br /&gt;Two points is interested here:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;How to start a thread&lt;/li&gt;&lt;li&gt;L4 API&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;How to start a thread&lt;/h4&gt;In L4, to start a thread you need two system calls,&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;L4_ThreadControl&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;L4_SpaceControl&lt;/code&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;You have to provide them three things to create an thread: 1. thread id; 2. stack; 3. UTCB address. The steps to create a thread is as following:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Using &lt;code&gt;L4_ThreadControl&lt;/code&gt; create an inactive thread. Here you have to provide a new unique globe thread id, space provider's thread id, scheduler's thread id and UTCB address. If space provider's thread id is the same as the new thread id, the a new address space is going to be created, otherwise thread is going to be created in the space provider's address space. Furthermore you have to leave pager's thread id as nil so that thread is created as inactive.&lt;/li&gt;&lt;li&gt;Using &lt;code&gt;L4_SpaceControl&lt;/code&gt; to initial the address space. You have to provide the KIP address and the begin of UTCB area so that L4 can map or initialize the corresponding address space for the created thread. If the thread is created in an existing address space then we don't need this step.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Finally using &lt;code&gt;L4_ThreadControl&lt;/code&gt; agian but with pager's thread id to activate the thread.&lt;/li&gt;&lt;li&gt;Till this point the created thread is only runnable, an startup IPC is required to let new thread run.&lt;/li&gt;&lt;/ol&gt;Two places in the pingpong's source code can be used as good example. The first place is when pager thread is created.&lt;br /&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;L4_ThreadControl(pager_tid, L4_Myself(), L4_Myself(), L4_Myself(), (void*)pager_utcb);&lt;br /&gt;L4_Start(pager_tid, (L4_Word_t)pager_stack + sizeof(pager_stack) - 32, START_ADDR(pager));&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Since pager reuses the address apace of root server, there is no &lt;code&gt;L4_SpaceControl&lt;/code&gt; used and pager is created as an active thread. Since root server is the pager of pager thread, &lt;code&gt;L4_Start&lt;/code&gt; is used directly to start pager.&lt;br /&gt;&lt;br /&gt;Another place is where ping and pong threads are created:&lt;br /&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;L4_ThreadControl(ping_tid, ping_tid, master_tid, L4_nilthread, UTCB(0));&lt;br /&gt;L4_ThreadControl(pong_tid, pong_tid, master_tid, L4_nilthread, UTCB(1));&lt;br /&gt;L4_SpaceControl(ping_tid, 0, kip_area, utcb_area, &amp;amp;control);&lt;br /&gt;L4_SpaceControl(pong_tid, 0, kip_area, utcb_area, &amp;amp;control);&lt;br /&gt;L4_ThreadControl(ping_tid, ping_tid, master_tid, pager_tid, NOUTCB);&lt;br /&gt;L4_ThreadControl(pong_tid, pong_tid, master_tid, pager_tid, NOUTCB);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;IPC&lt;/h4&gt;This is the most important part of L4. In fact there is only one IPC system call in L4. It is always synchronized. An IPC is consists of two phases, i.e. send and receive. If you specify both "send to" and "receive from" argument in IPC. Then it is blocked on waiting for reply after it finishes sending phase. If only "send to" is specified, IPC is returned after sending phase is finished. If only "received from" is specified, IPC doesn't send anything and just waits for a message from other threads. There is a IA32 specific pingpong IPC written in &lt;code&gt;ia32.h&lt;/code&gt;,&lt;br /&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;L4_INLINE L4_Word_t pingpong_ipc (L4_ThreadId_t dest, L4_Word_t untyped)&lt;br /&gt;{&lt;br /&gt;   L4_Word_t dummy;&lt;br /&gt;   __asm__ __volatile__ (&lt;br /&gt;   "/* pingpong_arch_ipc() */\n"&lt;br /&gt;   "pushl    %%ebp        \n"&lt;br /&gt;   "xorl    %%ecx, %%ecx    \n"&lt;br /&gt;   "movl    %%esi, (%%edi)    \n"&lt;br /&gt;#if 1&lt;br /&gt;   "call    __L4_Ipc    \n"    /* jump via KIP */&lt;br /&gt;#else&lt;br /&gt;   "leal    1f, %%ebx    \n"    /* enter kernel directly */&lt;br /&gt;   "movl    %%esp, %%ebp    \n"&lt;br /&gt;   "sysenter        \n"&lt;br /&gt;   "1:            \n"&lt;br /&gt;#endif&lt;br /&gt;   "popl    %%ebp        \n"&lt;br /&gt;   : "=d" (dummy), "=S"(untyped)&lt;br /&gt;   : "a" (dest), "d" (dest), "S"(untyped), "D"(__L4_X86_Utcb())&lt;br /&gt;   : "ebx", "ecx" );&lt;br /&gt;   return untyped;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;I don't know why it is written in assembly. The most important is that &lt;span style="color: rgb(204, 51, 204); font-weight: bold;"&gt;AX&lt;/span&gt; and &lt;span style="color: rgb(204, 51, 204); font-weight: bold;"&gt;DX&lt;/span&gt; registers are specified as dest in the example. And both of them are the first argument of IPC system. Therefore pingpong IPC is an IPC with both "send" and "receive" phases, which means the next "send" is only possible when the previous "receive" is finished. pingpong threads both use this call to communicate with each other. The only difference between them is that ping thread is in charge of calculating performance.&lt;br /&gt;&lt;br /&gt;Ok, I will stop here today. Next step is see how to manager the memory. See u soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-5609147861191372258?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/5609147861191372258/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=5609147861191372258' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/5609147861191372258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/5609147861191372258'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2009/11/life-in-userspace6-pingpong.html' title='Life in the userspace(6) - PingPong'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-8620067460451919882</id><published>2009-11-08T14:08:00.000-08:00</published><updated>2009-11-08T14:16:09.049-08:00</updated><title type='text'>EP(entry point) of a program</title><content type='html'>I know that EP(entry point) can be different from &lt;code&gt;"main"&lt;/code&gt;, but I don't know how and why, again... I remember I found out this before, but the knowledge is lost somehow. So I will write down here again. There are two way to have an entry point of program:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Using the default entry point. It is &lt;code&gt;"start"&lt;/code&gt;, not &lt;code&gt;"main"&lt;/code&gt;. C/C++ library makes a glue and redirect the entry point to &lt;code&gt;"main"&lt;/code&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Specify a entry pointer with &lt;code&gt;"-e"&lt;/code&gt; in linker (for sure, I am talking about the gnu linker). In L4, you will find &lt;code&gt;"-e_start"&lt;/code&gt; in the makefile and this is why in all &lt;code&gt;crt0.S&lt;/code&gt;, the first .global symbol is mostly &lt;code&gt;"_start"&lt;/code&gt;, i.e. it is the entry point.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-8620067460451919882?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/8620067460451919882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=8620067460451919882' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/8620067460451919882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/8620067460451919882'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2009/11/epentry-point-of-program.html' title='EP(entry point) of a program'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-5719397534089459717</id><published>2009-10-30T01:57:00.000-07:00</published><updated>2010-03-13T16:50:52.819-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='userspace'/><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>Life in the userspace (5) - Sigma0 as Pager</title><content type='html'>There are several confusions after my last post. One of them is how the address space of Sigma0 looks like. Following my intuition, I thought the address space is filled by kernel with 1-1 mapping, since I heard something like 1-1 mapping during my old study. For proving this I dig into kernel source code, what I found is are following factors:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Sigma0 doesn't have a pager.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Sigma0 is handled specially by L4 kernel, especially for page fault handling, since it has no pager.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Kernel doesn't mapping physical address into Sigma0's address space till there is a page fault.&lt;/li&gt;&lt;/ol&gt;You can find the prove for first point through function &lt;code&gt;init_root_servers()&lt;/code&gt; in file &lt;code&gt;kernel/src/api/v4/thread.cc&lt;/code&gt;, a simple code snip is like:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;    TRACE_INIT (&amp;quot;Creating sigma0 (%t)\n&amp;quot;, TID(sigma0));&lt;br /&gt;    tcb = create_root_server( sigma0,     // tid and space&lt;br /&gt;                              root_server,// scheduler&lt;br /&gt;                              NILTHREAD,  // pager&lt;br /&gt;                              utcb_area,&lt;br /&gt;                              kip_area,&lt;br /&gt;                              ROOT_UTCB_START,&lt;br /&gt;                              get_kip()-&amp;gt;sigma0.ip,&lt;br /&gt;                              get_kip()-&amp;gt;sigma0.sp);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;you see, the pager is &lt;code&gt;NILTHREAD&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;The second point you can find the prove through member function &lt;code&gt;handle_pagefault(...)&lt;/code&gt; in structure &lt;code&gt;space_t&lt;/code&gt;. The implementation of this function is located in file &lt;code&gt;kernel/src/api/v4/space&lt;/code&gt;. You will find the the page fault ipc is only going to be sent to pager when the page fault is not caused by Sigma0. For Sigma0, &lt;code&gt;map_sigma0(...)&lt;/code&gt; is simply used.&lt;br /&gt;&lt;br /&gt;OK, in my opinion, there are two cases where page fault is going to happen in Sigma0. Firstly, Sigma0 need memory for its own usage, for example allocate a new &lt;code&gt;region_t&lt;/code&gt; structure. The initial number of pre-allocated &lt;code&gt;region_t&lt;/code&gt; is 32. If they are used up, following codes is going to cause a page fault and let kernel map memory to Sigma0's address space:&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;region_t * region_list_t::alloc (void)&lt;br /&gt;{&lt;br /&gt; if (! list)&lt;br /&gt; {&lt;br /&gt;     // We might need some memory for allocating memory.&lt;br /&gt;     region_t tmp;                        &amp;lt;-page fault could happen&lt;br /&gt;     add ((L4_Word_t) &amp;amp;tmp, sizeof (tmp));&lt;br /&gt;&lt;br /&gt;     // Allocate some memory to sigma0.&lt;br /&gt;     L4_MapItem_t dummy;                  &amp;lt;- page fault could happen&lt;br /&gt;     if (! allocate_page (sigma0_id, min_pgsize, dummy))&lt;br /&gt;     {&lt;br /&gt;         printf (&amp;quot;s0: Unable to allocate memory.\n&amp;quot;);&lt;br /&gt;         for (;;)&lt;br /&gt;             L4_KDB_Enter (&amp;quot;s0: out of memory&amp;quot;);&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     bool was_alloced = (list == NULL);&lt;br /&gt;     if (! was_alloced)&lt;br /&gt;         list = (region_listent_t *) NULL;&lt;br /&gt;&lt;br /&gt;     // Add newly allocated memory to pool.&lt;br /&gt;     add (L4_Address (L4_SndFpage (dummy)), (1UL &amp;lt;&amp;lt; min_pgsize));&lt;br /&gt;&lt;br /&gt;     if (was_alloced)&lt;br /&gt;         // Swap temorary structure with a newly allocated one.&lt;br /&gt;         tmp.swap (alloc ());&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; // Remove first item from free list.&lt;br /&gt; region_listent_t * r = list;&lt;br /&gt; list = r-&amp;gt;next ();&lt;br /&gt;&lt;br /&gt; return r-&amp;gt;region ();&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The second one is when Sigma0 functions as pager. It will manage to allocate a MapItem, which contains the virtual address of Sigma0 to be mapped. The virtual address could contain nothing while the mapping happens, then a page fault during mapping happens and kernel will handle this page fault as I discussed above.&lt;br /&gt;&lt;br /&gt;Finally what is 1-1 mapping? You will see &lt;code&gt;map_sigma0(...)&lt;/code&gt; has only one address as input parameter, which means that it represents both virtual address and physical address, i.e. 1-1 mapping.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-5719397534089459717?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/5719397534089459717/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=5719397534089459717' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/5719397534089459717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/5719397534089459717'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2009/10/life-in-userspace-5-sigma0-as-pager.html' title='Life in the userspace (5) - Sigma0 as Pager'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-4789366715324083976</id><published>2009-10-21T13:12:00.000-07:00</published><updated>2010-03-13T16:54:50.257-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='userspace'/><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>Life in the userspace (4) - Sigma0</title><content type='html'>Finally, we reached the topic Sigma0. In my opinion, Sigma0 is a very simple memory manager. It arranges free memory, including I/O memory, and provides a way for root task to get memory from it. The &lt;code&gt;crt0-ia32.S&lt;/code&gt; indicates the entry point of whole program, i.e. &lt;code&gt;_start&lt;/code&gt; or &lt;code&gt;_stext&lt;/code&gt;. There are two labels because different compiler need different entry point.  Besides a multi boot header is also defined in &lt;code&gt;crt0-ia32.S&lt;/code&gt;. I don't want to talk this here, you can find more information about multi bot header in my old post. The real entry point function is &lt;code&gt;sigma0_main&lt;/code&gt;, which is implemented in &lt;code&gt;sigma0.cc&lt;/code&gt;.  If you look into &lt;code&gt;sigma0.cc&lt;/code&gt;, you will find that Sigma0 is consisted of three steps.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Getting information from KIP region.&lt;/li&gt;&lt;li&gt;Using the information to initialize it memory management structures.&lt;/li&gt;&lt;li&gt;Entering a endless loop to wait for IPCs from other threads, e.g. kernel threads, root server.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;We have talked how L4 pass KIP to user space in previous post, so I will skip the first step. The second step is initializing memory management structures. First of all, I will introduce four structures for memory management, i.e. &lt;code&gt;region_t&lt;/code&gt;, &lt;code&gt;region_listent_t&lt;/code&gt;, &lt;code&gt;region_list_t&lt;/code&gt;, &lt;code&gt;region_list_t&lt;/code&gt;. They are defined and implemented in &lt;code&gt;region.cc&lt;/code&gt; and &lt;code&gt;region.h&lt;/code&gt;. The idea is to manage memory with unit region_t. There are one list to store unused &lt;code&gt;region_t&lt;/code&gt; unit and many pools to manage the memory allocation and management. The list of &lt;code&gt;region_t&lt;/code&gt; works as a unit store. If one &lt;code&gt;region_t&lt;/code&gt; retires from one of pool, Sigma0 will put it into this list, so that it can be reused when another pool or the same pool want a &lt;code&gt;region_t&lt;/code&gt; for allocating a new memory block. One thing confused me for a while is the following code of &lt;code&gt;region_listent_t&lt;/code&gt;:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;    /**&lt;br /&gt;     * Opaque class for holding a region_t structure.&lt;br /&gt;     */&lt;br /&gt;    class region_listent_t&lt;br /&gt;    {&lt;br /&gt;        region_t    reg;&lt;br /&gt;&lt;br /&gt;    public:&lt;br /&gt;&lt;br /&gt;        region_t * region (void)&lt;br /&gt;        { return &amp;amp;reg; }&lt;br /&gt;&lt;br /&gt;        region_listent_t * next (void)&lt;br /&gt;        { return *(region_listent_t **) this; }&lt;br /&gt;&lt;br /&gt;        void set_next (region_listent_t * n)&lt;br /&gt;        { *(region_listent_t **) this = n; }&lt;br /&gt;    } __attribute__ ((packed));&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The &lt;code&gt;next()&lt;/code&gt; and &lt;code&gt;set_next&lt;/code&gt; looks weired. But the purpose is to store the next free &lt;code&gt;region_t&lt;/code&gt;'s pointer in the beginning space of current &lt;code&gt;region_t&lt;/code&gt; structure. The following figure may explain the situation:&lt;pre&gt;&lt;br /&gt; ___________      ___________&lt;br /&gt;|   pnext---|---&gt;|   pnext---|---&gt; ....&lt;br /&gt;|           |    |           |&lt;br /&gt;|           |    |           |&lt;br /&gt;|___________|    |___________|&lt;br /&gt;&lt;br /&gt;region_t         region_t&lt;br /&gt;&lt;/pre&gt; Since the content of &lt;code&gt;region_t&lt;/code&gt; in free list doesn't make any sense, so L4 guy just use it as plane memory region. However, in my opinion, it is better use it with &lt;code&gt;union&lt;/code&gt; instead of some weired tricks, this may be clearer for reader. The pools represent the memory region of different type. The allocated memory is managed by &lt;code&gt;alloc_pool&lt;/code&gt;, the unused memories are managed by &lt;code&gt;conv_momery_pool&lt;/code&gt; (conventional) and &lt;code&gt;memory_pool&lt;/code&gt; (non-conventional). After allocation, a region in unused pool could be removed from pool, be split into two regions and contain reduced size.&lt;br /&gt;&lt;br /&gt;Now come back to initialization. The initialization is simple and finished by function &lt;code&gt;init_mempool_from_kip(void)&lt;/code&gt;. There are two styles, but there is only one aim, i.e. put used memory to &lt;code&gt;alloc_pool&lt;/code&gt; and unused memory into &lt;code&gt;memory_pool&lt;/code&gt; and &lt;code&gt;conv_memory_pool&lt;/code&gt;. The memory descriptor stored in KIP is used to provide base information. I remember that I have talked this in old post. After the base information is processed, Sigma0 focuses on the memories that are used by loaded service, e.g. itself, RootServer and Kdebug. These informations are also stored in KIP. &lt;code&gt;alloc_memory(...)&lt;/code&gt; is used to register the memory used by these services.&lt;br /&gt;&lt;br /&gt;The last step is to listen IPC from other threads. Regarding the codes the major task of Sigam0 is memory allocation. One thing I'd like to notice here is that Sigma0 grabs all memory in it's address space and uses 1-1 mapping.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I don't remember whether low 2G or low 3G address space is used for user space. I have to check this. But anyway, there will be a problem to manage more than 4G memory. I remember there is some solution for this problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-4789366715324083976?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/4789366715324083976/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=4789366715324083976' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/4789366715324083976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/4789366715324083976'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2009/10/life-in-userspace-4-sigma0.html' title='Life in the userspace (4) - Sigma0'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-4661754392969028952</id><published>2009-10-13T06:05:00.001-07:00</published><updated>2010-03-14T00:38:52.578-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='userspace'/><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>Life in the userspace (3) - Back To Kernel Space</title><content type='html'>As I planned in last post, I will go though the exception handling in this post. To better understand this post, you need to read my old post &lt;a href="http://markustips.blogspot.com/2008/02/l4-pistachio-kernel-6.html"&gt;L4 pistachio Kernel (6)&lt;/a&gt;, since in that post I explain how the default handler exc_catch_common is installed for all &lt;span style="font-weight: bold; color: rgb(204, 51, 204);font-family:arial;"&gt;IDT&lt;/span&gt; entries. That is very interesting. I will start with the codes after for(...) loop in idt_t()'s constructor. In fact, if there is no kernel debug support required, L4 installs only 4 exception handlers in &lt;span style="font-weight: bold; color: rgb(204, 51, 204);font-family:arial;"&gt;IDT&lt;/span&gt; table. They are:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;    void exc_invliad_opcode(void)&lt;br /&gt;    void exc_nomath_coproc(void)&lt;br /&gt;    void exc_gp(void)&lt;br /&gt;    void exc_pagefault(void)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;First three are defined in file &lt;span style="font-style: italic; color: rgb(0, 153, 0);"&gt;l4ka-pistachio/kernel/src/glue/v4-x86/exception.cc&lt;/span&gt;. The last one is defined in file &lt;span style="font-style: italic; color: rgb(0, 153, 0);"&gt;l4ka-pistachio/kernel/src/glue/v4-x86/space.cc&lt;/span&gt;. There are two kinds of exceptions. For one kind,  you will get the error code from cpu, for the other you won't. So L4 guys make 2 macros for simplifying declaration of exception handler. You can find them in file &lt;span style="color: rgb(0, 153, 0); font-style: italic;"&gt;l4ka-pistachio/kernel/src/arch/x86/x32/trapgate.h&lt;/span&gt;. I will explain only the one for "with error code". The only difference between these two macro is one single stack operation.&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;/**&lt;br /&gt; * X86_EXCWITH_ERRORCODE: allows C implementation of &lt;br /&gt; *   exception handlers and trap/interrupt gates with error &lt;br /&gt; *   code.&lt;br /&gt; *&lt;br /&gt; * Usage: X86_EXCWITH_ERRORCODE(exc_gp)&lt;br /&gt; */&lt;br /&gt;#define X86_EXCWITH_ERRORCODE(name, reason)                 \&lt;br /&gt;extern &amp;quot;C&amp;quot; void name (void);                                \&lt;br /&gt;static void name##handler(x86_exceptionframe_t * frame);    \&lt;br /&gt;void name##_wrapper()                                       \&lt;br /&gt;{                                                           \&lt;br /&gt;    __asm__ (                                               \&lt;br /&gt;        &amp;quot;.global &amp;quot;#name &amp;quot;               \n&amp;quot;                 \&lt;br /&gt;        &amp;quot;\t.type &amp;quot;#name&amp;quot;,@function      \n&amp;quot;                 \&lt;br /&gt;        #name&amp;quot;:                         \n&amp;quot;                 \&lt;br /&gt;        &amp;quot;pusha                          \n&amp;quot;                 \&lt;br /&gt;        &amp;quot;push   %%ds                    \n&amp;quot;                 \&lt;br /&gt;        &amp;quot;push   %%es                    \n&amp;quot;                 \&lt;br /&gt;        &amp;quot;push   %1                      \n&amp;quot;                 \&lt;br /&gt;        &amp;quot;push   %%esp                   \n&amp;quot;                 \&lt;br /&gt;        set_kds (eax)                                       \&lt;br /&gt;        clr_dbgctl_lbr ()                                   \&lt;br /&gt;        &amp;quot;call   %0                      \n&amp;quot;                 \&lt;br /&gt;        set_dbgctl_lbr ()                                   \&lt;br /&gt;        &amp;quot;addl   $8, %%esp               \n&amp;quot;                 \&lt;br /&gt;        &amp;quot;popl   %%es                    \n&amp;quot;                 \&lt;br /&gt;        &amp;quot;popl   %%ds                    \n&amp;quot;                 \&lt;br /&gt;        &amp;quot;popa                           \n&amp;quot;                 \&lt;br /&gt;        &amp;quot;addl   $4, %%esp               \n&amp;quot;                 \&lt;br /&gt;        &amp;quot;iret                           \n&amp;quot;                 \&lt;br /&gt;        :                                                   \&lt;br /&gt;        : &amp;quot;m&amp;quot;(*(u32_t*)name##handler), &amp;quot;i&amp;quot;(reason)          \&lt;br /&gt;        );                                                  \&lt;br /&gt;}                                                           \&lt;br /&gt;static void name##handler(x86_exceptionframe_t * frame)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;All &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;exc_&lt;/span&gt; functions are defined, in fact, in wrapper function. The wrapper function is never called by anyone, they just reserve the space in code segment and then define the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;exc_&lt;/span&gt; function in assembly style. In short, the macro declares and defines the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;exc_&lt;/span&gt; functions in a very strange way... Why should this be implemented like this? no idea. Furthermore, in the end of macro, there is just a beginning of a function's implementation. If we combine the following code, you will know how the Macro is used:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;X86_EXCNO_ERRORCODE(exc_nomath_coproc, X86_EXC_NOMATH_COPROC)&lt;br /&gt;{&lt;br /&gt;    tcb_t * current = get_current_tcb();&lt;br /&gt;&lt;br /&gt;    TRACEPOINT(X86_NOMATH, &amp;quot;X86_NOMATH %t @ %p\n&amp;quot;,&lt;br /&gt;               current, frame-&amp;gt;regs[x86_exceptionframe_t::ipreg]);&lt;br /&gt;&lt;br /&gt;    current-&amp;gt;resources.x86_no_math_exception(current);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;So if you want to use the macro, you have to append at least one pair "{}" after it. Back to the previous macro, its job is simple. It saves current execution environment and jumps into real handler routine. For the exception without error code, one more line code is added:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&amp;quot;subl   $4, %%esp               \n&amp;quot;                     \&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Since exception error code is pushed into stack, it is needed to simulated in no error code situation so that codes:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&amp;quot;addl   $8, %%esp               \n&amp;quot;                     \&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;can be used to recovery execution environment for both "with error" and "without error" situation.&lt;br /&gt;&lt;br /&gt;I don't want to dig into how the exceptions are really handled. If you are interested, you can read &lt;span style="font-style: italic; color: rgb(0, 153, 0);"&gt;exception.cc&lt;/span&gt; and &lt;span style="font-style: italic; color: rgb(0, 153, 0);"&gt;space.cc&lt;/span&gt; I mentioned above.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-4661754392969028952?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/4661754392969028952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=4661754392969028952' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/4661754392969028952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/4661754392969028952'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2009/10/life-in-userspace-3-back-to-kernel.html' title='Life in the userspace (3) - Back To Kernel Space'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-9110942776151291748</id><published>2009-10-03T11:55:00.000-07:00</published><updated>2010-03-13T17:05:52.583-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>Life in the userspace (2) - L4_KernelInterface</title><content type='html'>Before I start to dig into sigma0, I would like to talk about one system call:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;L4_INLINE void* L4_KernelInterface(L4_Word_t *ApiVersion,&lt;br /&gt;                            L4_Word_t *ApiFlags,&lt;br /&gt;                            L4_Word_t *KernelId)&lt;br /&gt;{&lt;br /&gt;    void * base_address;&lt;br /&gt;&lt;br /&gt;  __asm__ __volatile__ (&lt;br /&gt;        &amp;quot;/* L4_KernelInterface() */                 \n&amp;quot;&lt;br /&gt;        &amp;quot;       lock; nop                           \n&amp;quot;&lt;br /&gt;&lt;br /&gt;        : /* outputs */&lt;br /&gt;        &amp;quot;=a&amp;quot; (base_address),&lt;br /&gt;        &amp;quot;=c&amp;quot; (*ApiVersion),&lt;br /&gt;        &amp;quot;=d&amp;quot; (*ApiFlags),&lt;br /&gt;        &amp;quot;=S&amp;quot; (*KernelId)&lt;br /&gt;&lt;br /&gt;        /* no inputs */&lt;br /&gt;        /* no clobbers */&lt;br /&gt;    );&lt;br /&gt;&lt;br /&gt;    return base_address;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;This system call is used by L4 applications to get base address of L4 kernel interface page and other three information, i.e. API version, API flags and Kernel id. I don't want to dig into the means of three API parameters, but focus on the codes. For a beginner, like me, it might very difficult to understand how the function works. There is only one inline assembly and only one line assembly codes:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&amp;quot;       lock; nop                           \n&amp;quot;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;How does this line make the L4 pistachio kernel copy information to EAX, ECX, EDX and ESI? Experienced programmer may find immediately that this assembly code is invalid! This is why we call it a slow system call. In fact, the function will raise a system exception "Invalid Opcode", L4 kernel will exception handler will put necessary information into suitable registers and return back to user space. Then user space function, inline assembly will copy information from registers to the variables. The exception handler for x86 is defined in &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 153, 0);"&gt;l4ka-pistachio/kernel/src/glue/v4-x86/exception.cc&lt;/span&gt;&lt;/span&gt; as:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;X86_EXCNO_ERRORCODE(exc_invalid_opcode, X86_EXC_INVALIDOPCODE)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Looks like we may need to look into exception handlers in detail later. It is helpful for understand codes.&lt;br /&gt;&lt;br /&gt;Moreover, you can find how L4 initializes &lt;span style="color: rgb(204, 51, 204); font-weight: bold;"&gt;IDT&lt;/span&gt; in post &lt;a href="http://markustips.blogspot.com/2008/02/l4-pistachio-kernel-6.html"&gt;L4 pistachio Kernel(6)&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-9110942776151291748?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/9110942776151291748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=9110942776151291748' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/9110942776151291748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/9110942776151291748'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2009/10/life-in-userspace-getkernelinterface.html' title='Life in the userspace (2) - L4_KernelInterface'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-3886710197100087243</id><published>2009-10-01T12:47:00.000-07:00</published><updated>2009-10-01T12:56:31.721-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CodeHighlighting'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><title type='text'>Code Highlighting</title><content type='html'>In order to write blog more professionally, I tried to find some website to get html codes for highlighting C/C++ code. Let's see the result:&lt;br /&gt;&lt;br /&gt;First one from "CodeColorizer":&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;FONT COLOR=RED&gt;&lt;B&gt;void&lt;/B&gt;&lt;/FONT&gt; &lt;FONT COLOR=BLUE SIZE=+1&gt;*&lt;/FONT&gt; region_t&lt;FONT COLOR=BLUE SIZE=+1&gt;:&lt;/FONT&gt;&lt;FONT COLOR=BLUE SIZE=+1&gt;:&lt;/FONT&gt;&lt;FONT COLOR=RED&gt;&lt;B&gt;operator&lt;/B&gt;&lt;/FONT&gt; &lt;FONT COLOR=RED&gt;&lt;B&gt;new&lt;/B&gt;&lt;/FONT&gt; &lt;FONT COLOR=BLUE SIZE=+1&gt;&lt;B&gt;(&lt;/B&gt;&lt;/FONT&gt;L4_Size_t size&lt;FONT COLOR=BLUE SIZE=+1&gt;&lt;B&gt;)&lt;/B&gt;&lt;/FONT&gt;&lt;br /&gt;&lt;FONT COLOR=BLUE SIZE=+1&gt;&lt;B&gt;{&lt;/B&gt;&lt;/FONT&gt;&lt;br /&gt;    &lt;FONT COLOR=RED&gt;&lt;B&gt;return&lt;/B&gt;&lt;/FONT&gt; &lt;FONT COLOR=BLUE SIZE=+1&gt;&lt;B&gt;(&lt;/B&gt;&lt;/FONT&gt;&lt;FONT COLOR=RED&gt;&lt;B&gt;void&lt;/B&gt;&lt;/FONT&gt; &lt;FONT COLOR=BLUE SIZE=+1&gt;*&lt;/FONT&gt;&lt;FONT COLOR=BLUE SIZE=+1&gt;&lt;B&gt;)&lt;/B&gt;&lt;/FONT&gt; region_list&lt;FONT COLOR=BLUE SIZE=+1&gt;&lt;B&gt;.&lt;/B&gt;&lt;/FONT&gt;alloc &lt;FONT COLOR=BLUE SIZE=+1&gt;&lt;B&gt;(&lt;/B&gt;&lt;/FONT&gt;&lt;FONT COLOR=BLUE SIZE=+1&gt;&lt;B&gt;)&lt;/B&gt;&lt;/FONT&gt;&lt;FONT COLOR=BLUE SIZE=+1&gt;&lt;B&gt;;&lt;/B&gt;&lt;/FONT&gt;&lt;br /&gt;&lt;FONT COLOR=BLUE SIZE=+1&gt;&lt;B&gt;}&lt;/B&gt;&lt;/FONT&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Second one from "toHtml":&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;void&lt;/span&gt; &lt;span style='color:#808030; '&gt;*&lt;/span&gt; region_t&lt;span style='color:#800080; '&gt;::&lt;/span&gt;operator new &lt;span style='color:#808030; '&gt;(&lt;/span&gt;L4_Size_t size&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;void&lt;/span&gt; &lt;span style='color:#808030; '&gt;*&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; region_list&lt;span style='color:#808030; '&gt;.&lt;/span&gt;alloc &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Last one from "CodeHTMLer":&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style=' color: Blue;'&gt;void&lt;/span&gt; * region_t::&lt;span style=' color: Blue;'&gt;operator&lt;/span&gt; &lt;span style=' color: Blue;'&gt;new&lt;/span&gt; (L4_Size_t size)&lt;br /&gt;{ &lt;br /&gt;    &lt;span style=' color: Blue;'&gt;return&lt;/span&gt; (&lt;span style=' color: Blue;'&gt;void&lt;/span&gt; *) region_list.alloc ();&lt;br /&gt;} &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I like the second one in fact. And it is the easiest converter for getting html code directly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-3886710197100087243?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/3886710197100087243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=3886710197100087243' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/3886710197100087243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/3886710197100087243'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2009/10/code-highlighting.html' title='Code Highlighting'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-1480782148576521422</id><published>2009-10-01T06:52:00.000-07:00</published><updated>2009-10-13T06:06:07.232-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='userspace'/><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>Life in the userspace (1) - Preface</title><content type='html'>One and half years ago, I described some details about pistachio kernel. I stopped after I started my first job at RTS Realtime System. Should I say I love my current job? It is better to shut up now. Anyway, meanwhile I have some time to continue my hobby and write something here. For me, I found that to write down the knowledge is much better than to keep them in my mind (I am getting older every day).&lt;br /&gt;&lt;br /&gt;In the next few days, I will try to explore the way to write an application upon pistachio. I was looking for a program manual for pistachio, but failed. API specification is there, but that is not very useful for a beginner to start writing his application upon L4. I also found a draft of program manual, but it is far from sufficient and may be a little out-of-date.&lt;br /&gt;&lt;br /&gt;The focus of next days is /user directory under lk4a-pistachio directory - assuming that you clone the pistachio source tree from HG repository. The road map would be like: I started from sigma0 directory and show what sigma0 is; then I will jump between lib/ and /apps to explain how an root task could be written; finally I will try write my own root task application as an exercise for myself.&lt;br /&gt;&lt;br /&gt;There is another util/ directory under user/. I won't go into it since I have introduced kickstart/ before I introduced pistachio, while piggybacker/ is not related to x86 architecture and grubdisk is only the stuff for booting menu.&lt;br /&gt;&lt;br /&gt;I will and must stick to my plan. ^_^&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-1480782148576521422?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/1480782148576521422/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=1480782148576521422' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/1480782148576521422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/1480782148576521422'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2009/10/life-in-userspace.html' title='Life in the userspace (1) - Preface'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-7116248621199817582</id><published>2009-08-03T14:32:00.000-07:00</published><updated>2009-08-03T14:35:58.742-07:00</updated><title type='text'>Hard to bring it back again</title><content type='html'>Looks like I forget a lot of things. I have to pick them up again bit by bit. This would take a lot time..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-7116248621199817582?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/7116248621199817582/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=7116248621199817582' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/7116248621199817582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/7116248621199817582'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2009/08/hard-to-bring-it-back-again.html' title='Hard to bring it back again'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-2377062074305019071</id><published>2009-05-23T16:20:00.000-07:00</published><updated>2009-05-23T16:22:17.393-07:00</updated><title type='text'>Lazy...as always</title><content type='html'>I am really lazy... I didn't do what I want to do for a long time. Can I start working on VM again? I doubt...doubt...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-2377062074305019071?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/2377062074305019071/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=2377062074305019071' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/2377062074305019071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/2377062074305019071'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2009/05/lazyas-always.html' title='Lazy...as always'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-8281334007950396596</id><published>2009-03-16T08:49:00.000-07:00</published><updated>2009-03-16T08:51:04.030-07:00</updated><title type='text'>Finally...</title><content type='html'>Finally, I have internet at home... Now I should restart blogging!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-8281334007950396596?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/8281334007950396596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=8281334007950396596' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/8281334007950396596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/8281334007950396596'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2009/03/finally.html' title='Finally...'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-3133188950564027076</id><published>2009-01-19T01:50:00.000-08:00</published><updated>2009-01-19T01:56:52.606-08:00</updated><title type='text'>New Year and New Life</title><content type='html'>I didn't update this blog for a very very long time. There are two reasons:&lt;br /&gt;&lt;br /&gt;1. I don't have internet connection at home.&lt;br /&gt;2. There is something wasting too much of my time - I get divorced.&lt;br /&gt;&lt;br /&gt;What a bad year 2008! Anyway, I would like to restart my life together with this blog in 2009.&lt;br /&gt;&lt;br /&gt;Good luck for myself and hope I can make something this year.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-3133188950564027076?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/3133188950564027076/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=3133188950564027076' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/3133188950564027076'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/3133188950564027076'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2009/01/new-year-and-new-life.html' title='New Year and New Life'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-1700749179685619260</id><published>2008-05-04T13:24:00.000-07:00</published><updated>2008-05-04T13:31:15.390-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>Short Notes (7) - VMWare Fusion &amp; Minicom</title><content type='html'>VMWare Fusion is the release version of VMWare on Mac OSX. It doesn't officially support serial port with "named pipe", but you can manually change the setting in ".vmx" file to use "named pipe" serial port. However, the pipe is created as "root" and cannot be written except "root" so that minicom cannot successfully use this pipe. I don't know how to change this situation, but the simplest way to work around it is starting minicom with "sudo"... That's it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-1700749179685619260?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/1700749179685619260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=1700749179685619260' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/1700749179685619260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/1700749179685619260'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/05/short-notes-7-vmware-fusion-minicom.html' title='Short Notes (7) - VMWare Fusion &amp; Minicom'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-6794960756234248215</id><published>2008-04-29T10:53:00.000-07:00</published><updated>2008-04-29T11:15:20.849-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>Short Notes (6) - New Plan</title><content type='html'>Because of my current day job I haven't update my blog for a very long time. How to use my time well is a big challenge standing before me. Therefore, I am trying to make a schedule here so that I can regularly update this blog. After the day job I usually have 5 hours for relax and own hobbies. I would like to pick out two hours a day to learn L4. In my old plan, I should code and write at the same time, which means I should figure out how L4 works through programming a small system on L4. Now, I'd like to detail this plan here.&lt;br /&gt;&lt;br /&gt;- One blog per week (at least).&lt;br /&gt;- Two hours a day for investigating L4.&lt;br /&gt;- Every week I need to find a theme (Short Note on weekend)&lt;br /&gt;&lt;br /&gt;So what is the first theme?&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;###########################################&lt;br /&gt;  "Create/Manipulate/Stop a thread on L4"&lt;br /&gt;###########################################&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;God bless me to finish it this week :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-6794960756234248215?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/6794960756234248215/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=6794960756234248215' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/6794960756234248215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/6794960756234248215'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/04/short-notes-6-new-plan.html' title='Short Notes (6) - New Plan'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-3880078549681521411</id><published>2008-04-24T03:20:00.000-07:00</published><updated>2008-04-24T03:21:22.136-07:00</updated><title type='text'>Heartbeat...Heartbeat</title><content type='html'>Keep my u-kernel blog alive!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-3880078549681521411?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/3880078549681521411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=3880078549681521411' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/3880078549681521411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/3880078549681521411'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/04/heartbeatheartbeat.html' title='Heartbeat...Heartbeat'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-4839015463721621261</id><published>2008-03-09T14:33:00.000-07:00</published><updated>2008-03-11T15:34:18.093-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>Short Notes (5) - .depend</title><content type='html'>Yeah, I will answer the last question now. How is the ".depend" file used? "make" allows you to specify an extended script file besides "makefile" or "Makefile". So in SDI project, .depend is specified as extended script. Looking into the ".depend" file, you will find the format is just like a rule for "make" script. For example,&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;a.o : b.h&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;so, you will find that all header files for server stub is described as dependent file for some object file and their compilation rules are defined in l4.build.mk as:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;$(SERV_STUBS) : ...&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;That's it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-4839015463721621261?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/4839015463721621261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=4839015463721621261' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/4839015463721621261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/4839015463721621261'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/03/short-notes-5-depend.html' title='Short Notes (5) - .depend'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-6856077911385028343</id><published>2008-03-09T10:15:00.000-07:00</published><updated>2008-03-09T14:33:07.686-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>Short Notes (4) - .depend</title><content type='html'>It's shame to keep my blog live through writing "Short Notes"... Maybe next weekend I could write more here... In the last two weeks, I just lost my passion for a while. The reason is probably the day job. After my regular working time, no energy more for my hobby consult. Weekend.. Yeah, just spending a lot of time for relaxing... hey.&lt;br /&gt;&lt;br /&gt;Here I would like to discuss a small technique used for compiling, source code dependence. I was wondering how the .depend files are created in L4 or SDI project. This file is used for "make" to check the file dependence among different source files, i.e. on which header files a C source file dependents. I googled in order to see how this file could be generated. However, most results indicate that dependency is mostly found out through makedepend  tool which is kinda not used in SDI project. At last, through check make script, I found that gcc can also generate the dependency map through option -M and -MG. This is really interesting for me :).&lt;br /&gt;&lt;br /&gt;Another question is how .depend file is used? Is it automatically checked by "make" or not?? Is MAKEFILES macro is preserved by "make"?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-6856077911385028343?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/6856077911385028343/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=6856077911385028343' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/6856077911385028343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/6856077911385028343'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/03/short-notes-4-depend.html' title='Short Notes (4) - .depend'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-7198835886479535479</id><published>2008-03-03T03:12:00.000-08:00</published><updated>2008-03-03T06:02:19.891-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>Short Note (3) - minicom</title><content type='html'>I didn't post anything for a long time, since I didn't have enough energy to continue investigating L4 current. The regular work sucks me up... Last weekend, I am trying to compile L4 on Mac OS X, but failed :(. I think the problem is assembler used under Mac OS X is different from that under Linux. I will try to compile and install the latest gnu Binutil later and see whether this works. What I would like to notice here is something about minicom. Under Max OS X minicom's default directory for lockfile is &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;/opt/var/lock&lt;/span&gt;, where normal user is not permitted to create, modify file. If you want to use minicom as normal user, you should change the directory path through&lt;br /&gt;&lt;blockquote&gt;1. sudo minicom -s {configuration}&lt;configuration&gt;&lt;br /&gt;2. select Serial device setting&lt;br /&gt;3. press B to change the directory&lt;br /&gt;&lt;/configuration&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-7198835886479535479?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/7198835886479535479/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=7198835886479535479' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/7198835886479535479'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/7198835886479535479'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/03/short-note-3-minicom.html' title='Short Note (3) - minicom'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-2184976172922565524</id><published>2008-02-23T10:12:00.000-08:00</published><updated>2008-02-24T06:18:05.433-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>L4 pistachio Kernel (11)</title><content type='html'>In this post I will discuss the last function in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_all_threads&lt;/span&gt;(), i.e. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_root_servers&lt;/span&gt;(), located in &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;api/v4/thread.cc&lt;/span&gt;. The root servers consist of &lt;span style="font-family:trebuchet ms;"&gt;sigma0&lt;/span&gt;, &lt;span style="font-family:trebuchet ms;"&gt;sigma1&lt;/span&gt; and root task. &lt;span style="font-family:trebuchet ms;"&gt;sigma0&lt;/span&gt; is essential, whereas &lt;span style="font-family:trebuchet ms;"&gt;sigma1&lt;/span&gt; and root task are optional. These 3 services don't run in kernel space, but in user space. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_root_servers&lt;/span&gt;() actually creates three threads for each service. In oder to create thread, we need thread number, &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;KTCB&lt;/span&gt; area and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;UTCB&lt;/span&gt; area. So in the beginning of codes, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_root_servers&lt;/span&gt;() get the minimal thread number for user space services from &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;UserBase&lt;/span&gt; field of &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;ThreadInfo&lt;/span&gt; section in &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;KIP&lt;/span&gt;. It then allocate to pages, represented by flex page structure in L4, to &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;UTCB&lt;/span&gt; area and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;KIP&lt;/span&gt; area in new address space.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  fpage_t utcb_area = fpage_t::nilpage(),&lt;br /&gt;           kip_area = fpage_t::nilpage();&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The next &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;while&lt;/span&gt;(...) loop is used to calculate the necessary &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;UTCB&lt;/span&gt; size.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  while((1U &lt;&lt;&gt;utcb_info.get_minimal_size(),&lt;br /&gt;     get_kip()-&gt;utcb_info.get_utcb_size() * ROOT_MAX_THREADS ))&lt;br /&gt;  size_utcb++;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Then the page structure for &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;UTCB&lt;/span&gt; area and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;KIP&lt;/span&gt; area are initialized through &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;fpage_t::set&lt;/span&gt;(...). You need to mention that the page size passed into &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;fpage_t::set&lt;/span&gt;(...) is in log2 format. This is also the reason L4 guys use left shift operation to calculate the &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;UTCB&lt;/span&gt; size. After these initialization &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_root_servers&lt;/span&gt;() checks the special fields in KIP to consider whether there are sigma0, sigma1 and root service mapped in the memory. I have discussed these area before, you can check them out in old post. Then &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;create_root_server&lt;/span&gt;(...) is used to create and initialize the address space, &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;KTCB&lt;/span&gt; area and so on. It is better to talk about it detailedly.&lt;br /&gt;&lt;br /&gt;After some checking, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;create_root_server&lt;/span&gt;(...) gets the &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;KTCB&lt;/span&gt; entry for new thread from the current address space, since &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;KTCB&lt;/span&gt; area should be mapped in the same phase of each address space. In order to allocate address space, it uses &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;allocate_space&lt;/span&gt;() in &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;glue/v4-x86/space.cc&lt;/span&gt;. This function get the memory resource from the kernel memory region represented by &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;kmem&lt;/span&gt;. It also allocate the page directory for the space and uses it to initialize space_t structure. The next step is &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;arch_init_root_server&lt;/span&gt;(...), which is empty in &lt;span style="font-family:trebuchet ms;"&gt;IA-32&lt;/span&gt; platform. Then &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;create_inactive&lt;/span&gt;(...) is used to create an thread in inactive state. It is similar to the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;tcb_t::create_kernel_thread&lt;/span&gt;(...), which I have discussed before. &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;UTCB&lt;/span&gt; area and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;KIP&lt;/span&gt; area are passed to initialize new &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;space_t&lt;/span&gt; structure after new thread is created and the new &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;space_t&lt;/span&gt; is hooked to new &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;KTCB&lt;/span&gt;. After these initialization, the thread is prepared to be executed, so &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;tcb_t::activate&lt;/span&gt;(). The most important work in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;tcb::activate&lt;/span&gt;() is manipulating the kernel stack, which is achieved &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;through tcb_t::create_startup_stack&lt;/span&gt;(...). Then &lt;span style="font-family:trebuchet ms;"&gt;IP&lt;/span&gt; and &lt;span style="font-family:trebuchet ms;"&gt;SP&lt;/span&gt; is set in &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;KTCB&lt;/span&gt; and the thread state is changed to running. At last the new created thread is inserted into running queue of current scheduler. The the sigma0 service is up, more exactly is ready to up! I suggest you read above suffer along with the code located in &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;api/v4/thread.cc&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;The rest of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_root_servers&lt;/span&gt;() is using the same to create threads for &lt;span style="font-family:trebuchet ms;"&gt;sigma1&lt;/span&gt; and root service.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-2184976172922565524?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/2184976172922565524/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=2184976172922565524' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/2184976172922565524'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/2184976172922565524'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/l4-pistachio-kernel-11.html' title='L4 pistachio Kernel (11)'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-5701444690957574668</id><published>2008-02-20T13:20:00.001-08:00</published><updated>2008-02-21T13:33:07.551-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>L4 pistachio Kernel (10)</title><content type='html'>In this post I'd like to investigate what &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_all_threads&lt;/span&gt;() does. In this function there are three calls for other functions, i.e. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_interrupt_threads&lt;/span&gt;(),&lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt; init_kernel_threads&lt;/span&gt;() and &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_root_servers&lt;/span&gt;(). The duty of first function is simple,&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;void SECTION(".init") init_interrupt_threads()&lt;br /&gt;{&lt;br /&gt;  /* initialize KIP */&lt;br /&gt;  word_t num_irqs = get_interrupt_ctrl()-&gt;get_number_irqs();&lt;br /&gt;  get_kip()-&gt;thread_info.set_system_base(num_irqs);&lt;br /&gt;  TRACE_INIT("System has %d interrupts\n", num_irqs);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;it sets the &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;SystemBase&lt;/span&gt; field of &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;ThreadInfo&lt;/span&gt; in &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KIP&lt;/span&gt; to the number of hardware &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;IRQs&lt;/span&gt;. The thread id lower than &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;SystemBase&lt;/span&gt; is dedicated for &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;IRQ&lt;/span&gt; threads in L4. And thread id between &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;SystemBase&lt;/span&gt;  and &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;UserBase&lt;/span&gt; (another field of &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;ThreadInfo&lt;/span&gt; in &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KIP&lt;/span&gt;) is used by kernel internally. The thread id above &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;UserBase&lt;/span&gt; can be used by applications upon L4. For more information, please checking the L4 manual.&lt;br /&gt;&lt;br /&gt;The next function is called &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_kernel_threads&lt;/span&gt;(). At first, it, just like &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_interrupt_threads&lt;/span&gt;(), initializes &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;UserBase&lt;/span&gt; field. But then I am confused, because this function creates a dummy kernel thread. Why should a dummy kernel thread created? I'm not sure. However, it is worth to look how L4 create a thread (at least kernel level). You may notice that L4 has already created a thread before, i.e. idle thread. But, creating idle thread differs at least from two aspects from creating a general kernel thread. At first, idle thread has the thread id &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;NILTHREAD&lt;/span&gt;, which cannot be used by other threads. Secondly, idle thread has its dedicated, per processor &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt; block, whereas the other threads will share a common &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt; array. L4 divides kernel space into four region, e.g. small space region, static kernel region, per cpu kernel region. Idle thread's &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt;s are located in per cpu region and common &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt; array is located in other kernel region. Now, let's discuss the steps for creating a kernel thread.&lt;br /&gt;&lt;br /&gt;At first, a thread needs a thread id. The dummy kernel thread uses the lowest valid thread id, which can be retrieved by &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;get_kip()-&gt;thread_info.get_system_base&lt;/span&gt;(), then &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;threadid_t::set_global_id&lt;/span&gt;(...) will fill the the fields, i.e. thread number and version, in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;threadid_t&lt;/span&gt; structure. After that, you will see &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;space_t::get_tcb&lt;/span&gt;(...) function. It returns the virtual address of current thread's &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt;. Be careful it ONLY return the address, the page containing such &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt; may not exist in current page table. The code in the function is like,&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;INLINE tcb_t * space_t::get_tcb(threadid_t tid)&lt;br /&gt;{&lt;br /&gt;   return (tcb_t*)((KTCB_AREA_START)&lt;br /&gt;        + ((tid.get_threadno() &amp;amp; VALID_THREADNO_MASK) * KTCB_SIZE));&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB_AREA_START&lt;/span&gt; is a dedicated virtual address for the start of &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt; array. Thread number is used as index in the &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt; array. The other looks like naive. Why may not the current thread's &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt; exist in it's address space? It's better to watch video about L4 address space of MKC leture. But I will explain a little here.&lt;br /&gt;&lt;br /&gt;In L4, each address space will synchronize their dynamic kernel area (vaddr &gt; &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;0xC0000000&lt;/span&gt;) with the kernel space, e.g. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;space_t&lt;/span&gt; for kernel. In the beginning, &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt; array is empty (or 0 mapping? must investigate). When a thread is created, kernel first allocates an empty address space to it and then find a &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt; according to its thread number. However, the corresponding &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt; entry may not allocated in page table. So a page fault happens, the corresponding page entry is filled with a physical page address. Now the mapping only exists in the kernel space, but still not in the thread's address space. Later the &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt; is required in this thread's address space, e.g. thread switch need to retrieve current thread's &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt;. Another page fault happens in current address space and the kernel space maps corresponding physical page into current address space. OK, I just guess about this according to the knowledge I learned from MKC lecture. Don't blame me if I am wrong. I may correct this explanation sometime later :).&lt;br /&gt;&lt;br /&gt;After the address of &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt; is retrieved. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;create_kernel_thread&lt;/span&gt;() is used for initializing the created thread. The most important thing in this function is &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;tcb_t::init&lt;/span&gt;(...). At first &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;tcb_t::init&lt;/span&gt;(...) use &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;tcb_t::allocate&lt;/span&gt;() to ensure the physical page for this &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt; is mapped into current address space. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;tcb_t::allocate&lt;/span&gt;() uses a or instruction to touch the virtual address of &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt;. If it doesn't exist in current address space, a page fault will bring the corresponding physical page. Besides it also set the initial state, partner of the created thread. The further initialization touches &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;myself_global&lt;/span&gt;, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;myself_local&lt;/span&gt;, resource (fpu_state, copy area), queue. Finally &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;scheduler_t::init_tcb&lt;/span&gt;(...) sets some scheduler related parameter into &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt; and &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_stack&lt;/span&gt;() returns the highest virtual address of current &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt; as the kernel stack point. In the end of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;create_kernel_threads&lt;/span&gt;(), the dummy thread's state is set to aborted so that it will never be executed. Now I guess that kernel creats a dummy thread in order to finish some thread related area, e.g. &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KTCB&lt;/span&gt; array in kernel space. But I am still not sure :{.&lt;br /&gt;&lt;br /&gt;The last thing in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_all_threads&lt;/span&gt;() is &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_root_servers&lt;/span&gt;(). I will discuss it next post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-5701444690957574668?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/5701444690957574668/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=5701444690957574668' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/5701444690957574668'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/5701444690957574668'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/l4-pistachio-kernel-10.html' title='L4 pistachio Kernel (10)'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-5784428708430914744</id><published>2008-02-18T11:47:00.000-08:00</published><updated>2009-10-29T08:20:07.138-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>L4 pistachio Kernel (9)</title><content type='html'>I would like to discuss more about the system's startup. Till now things are in the kernel level. And a lot of codes for initialization are actually put things, e.g. function pointer onto stack. For example, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;scheduler_t::init&lt;/span&gt;(...) puts function pointer of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;idle_thread&lt;/span&gt;() and &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;initial_all_threads&lt;/span&gt;() onto the kernel stack of idle thread. The stack looks actually like this&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;______________________ Highest Address of KTCB&lt;br /&gt;| user level DS   |      = start_addr + KTCB_SIZE&lt;br /&gt;|_________________|&lt;br /&gt;| user level SP   |&lt;br /&gt;|_________________|&lt;br /&gt;| user level flag |&lt;br /&gt;|_________________|&lt;br /&gt;| user level CS   |&lt;br /&gt;|_________________|&lt;br /&gt;| user level ip   |&lt;br /&gt;|_________________|_____&lt;br /&gt;|                 |&lt;br /&gt;|      ...        |      EXC_FRAME_SIZE&lt;br /&gt;|                 |&lt;br /&gt;|_________________|_____&lt;br /&gt;| return_to_user  |&lt;br /&gt;|_________________|&lt;br /&gt;|  idle_thread    |&lt;br /&gt;|_________________|&lt;br /&gt;| init_all_threads|&lt;br /&gt;|_________________|&lt;br /&gt;|                 |&lt;br /&gt;|                 |&lt;br /&gt;|      ...        |&lt;br /&gt;|                 |&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You may be confused, where comes those user level stuff, and why should be exist here. I have to say that I skipped introducing &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;create_startup_stack&lt;/span&gt;() function last time. It is actually important and It is the one who puts such lot user level stuff and function pointer of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;return_to_user&lt;/span&gt;() onto the stack. Of course it also puts function pointer of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;idle_thread&lt;/span&gt;(). All things above &amp;amp;&lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;return_to_user&lt;/span&gt; is used for switching from kernel level to user level. In &lt;span style="font-family:trebuchet ms;"&gt;IA-32&lt;/span&gt;,  &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;iret &lt;/span&gt;is used for automatically changing privilege level and task switch. When &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;iret&lt;/span&gt; executes, CPU looks current stack pointed by &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;ESP&lt;/span&gt; and fetch vary user level information and restores the interrupted execution environment so that interrupted user application can continue its work. In legend OS, kernel level is only entered when interrupts or exceptions happen. In order to prove this, let's see what actually needs intervention from kernel. In common, there are two situations, i.e system calls and hardware interrupts. For hardware interrupts, it is already clear from its name that it uses iret to go back to user level. For system calls, you need to know that they are usually implemented through exception. For example, some systems dedicate &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;INT 0x80&lt;/span&gt;  (software exception) for system calls. When user application invokes system call, it actually raises an exception. Of course, the return from exception is also achieved by &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;iret&lt;/span&gt; instruction. But in modern system, there is an alternative for exception and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;iret&lt;/span&gt;, i.e &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;sysenter&lt;/span&gt; &amp;amp; &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;sysexit&lt;/span&gt;. They works faster than &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;iret&lt;/span&gt; and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;sysexit&lt;/span&gt; doesn't require OS provides user level information, except IP and SP, since the calling convention in programming language, i.e. C/C++ will have to preserve these information. In simple words, &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;sysenter&lt;/span&gt; and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;sysexit&lt;/span&gt; are more like function call and return, whereas exception and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;iret&lt;/span&gt; are different at all.&lt;br /&gt;&lt;br /&gt;At last, let's recall the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;scheduler_t::start&lt;/span&gt;(...) function and see what happens when this function is called. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;initial_switch_to&lt;/span&gt;(...) is the major body of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;scheduler_t::start&lt;/span&gt;(...). As we saw in last post, there are only two assembly statement. The first moves stack's address of idle thread into esp, and the second ret instruction direct retrieve the function pointer of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_all_threads&lt;/span&gt;() and starts executing this function. The return point of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_all_threads&lt;/span&gt;() will redirect to start of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;idle_thread&lt;/span&gt;(). Since &lt;span style="color: rgb(204, 0, 0);"&gt;idle_thread&lt;/span&gt;() never returns, the rest of idle thread's stack may never be used.&lt;br /&gt;&lt;br /&gt;OK, now I stop here today. The pace of my post may be slower in the future, since one side I will start my normal work from tomorrow and other side the codes are more and more complex than before now. I need more time to understand them and write down my thought.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-5784428708430914744?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/5784428708430914744/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=5784428708430914744' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/5784428708430914744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/5784428708430914744'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/l4-pistachio-kernel-9.html' title='L4 pistachio Kernel (9)'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-8865603938822152089</id><published>2008-02-17T01:28:00.000-08:00</published><updated>2008-02-17T05:09:46.376-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>L4 pistachio Kernel (8)</title><content type='html'>Today I will try to finish reading the routine &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;startup_system&lt;/span&gt;(). Last time we stopped after &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_mdb&lt;/span&gt;(). The next general step is initializing the kernel debugger. The function pointer &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;kdebug_init&lt;/span&gt;() is only effective when you turn on the kernel debug option in kernel configuration. It is put into &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;KIP&lt;/span&gt; in the file &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;api/v4/kernelinterface.cc&lt;/span&gt;. The real definition for &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;kdebug_init&lt;/span&gt;() is located in &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;l4ka_pistachio/kernel/kdb&lt;/span&gt;. I will talk it more when I discuss kernel debugger.&lt;br /&gt;&lt;br /&gt;Following the initializing for kernel debugger there is initialization routine for interrupt controller.  &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;get_interrupt_ctrl&lt;/span&gt;() returns a variable named intctrl, which is defined in file &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;platform/generic/intctrl-pic.cc&lt;/span&gt; or &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;platfor/generic/intctrl-apic.cc&lt;/span&gt;. I only discuss the legend interrupt controller, so I focus on intctrl-pic.cc. In the routine &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_arch&lt;/span&gt;() you will see, L4 initialize all 15 hardware vector in IDT with function &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;hwirq_x&lt;/span&gt;(), where x represents interrupt number, e.g. 1. The definition of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;hwirq_x&lt;/span&gt; is achieved by Macro &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;HW_IRQ&lt;/span&gt;(x) which is located in &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;file glue/v4-x86/x32/hwirq.h&lt;/span&gt;. Using macro to define function is at least widely used in system programming, especially for those very similar functions. For example &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;hwirq_x&lt;/span&gt;() functions are only differed by interrupt number from each other. The most code settles in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;hwirq_x&lt;/span&gt;() functions is same. However using Macro increasing the difficulty for reader, since they usually cannot find out the declaration through searching the function name. Looking into the Macro,&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  __asm__ (                                                   \&lt;br /&gt;      "   .section .text                  \n"\&lt;br /&gt;      "   .align 16                   \n"\&lt;br /&gt;      "   .global hwirq_"#num"                \n"\&lt;br /&gt;      "   .type hwirq_"#num",@function            \n"\&lt;br /&gt;      "hwirq_"#num":                      \n"\&lt;br /&gt;      "   pusha           /* save regs    */  \n"\&lt;br /&gt;      "   pushl   %ds                 \n"\&lt;br /&gt;      "   pushl   %es                 \n"\&lt;br /&gt;      "   pushl   $"#num"     /* irq number   */      \n"\&lt;br /&gt;      "   jmp hwirq_common    /* common stuff */      \n");&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;you will find all interrupt handlers are redirected to function hwirq_common(), which is defined through Macro &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;HW_IRQ_COMMON&lt;/span&gt;().&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  __asm__(                            \&lt;br /&gt;  "   .section .text                  \n"\&lt;br /&gt;  "   .align 16                   \n"\&lt;br /&gt;  "   .globl hwirq_common             \n"\&lt;br /&gt;  "hwirq_common:                      \n"\&lt;br /&gt;  "   pushl   $intctrl    /* this pointer */  \n"\&lt;br /&gt;  __SET_KDS                       \&lt;br /&gt;  "   call    intctrl_t_handle_irq            \n"\&lt;br /&gt;  "   addl    $8,%esp     /* clear stack  */  \n"\&lt;br /&gt;  "   popl    %es                 \n"\&lt;br /&gt;  "   popl    %ds                 \n"\&lt;br /&gt;  "   popa            /* restore regs */  \n"\&lt;br /&gt;  "   iret                        \n"\&lt;br /&gt;  );&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;so now we know &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;intctrl_t_handle_irq&lt;/span&gt; is final handler for all interrupt in L4. So where is this function? I find answer in &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;platform/generic/intctrl-pic.h&lt;/span&gt;. See the last function declaration in class &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;generic_intctrl_t&lt;/span&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  void handle_irq(word_t irq) __asm__("intctrl_t_handle_irq");&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;It looks like &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;handle_irq&lt;/span&gt;() will be renamed to &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;intctrl_t_handle_irq&lt;/span&gt; after compiling. Note, in GCC &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;__asm__&lt;/span&gt; can only be put after function declaration, not definition. That means:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  void func1( ... ) __asm__("..."); // legal&lt;br /&gt;&lt;br /&gt;  void func1( ... ) __asm__("...") { ... } // illegal&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;handle_irq&lt;/span&gt;() masks and acknowledges the hardware interrupt and tries to find a user level interrupt handler through &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;handle_interrupt&lt;/span&gt;() function. I will discuss this when I talk about L4 API about interrupt later.&lt;br /&gt;&lt;br /&gt;After the vectors in &lt;span style="font-family: trebuchet ms;"&gt;IDT&lt;/span&gt; are initialized. The master and slave interrupt controller are hardware initialized. One interrupt controller (i8259) can only handle 8 interrupt request. In order to achieve 15 interrupts, an additional interrupt controller is necessary, i.e. slave i8259. The slave is connected with pin 2 of master. In the code, i8259 is represented by &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;i8259_pic_t&lt;/span&gt; class template in file &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;platform/pc99/8259.h&lt;/span&gt;. Master and slave are defined as follow in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;generic_intctrl_t&lt;/span&gt; class,&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  i8259_pic_t&lt;0x20&gt; master;&lt;br /&gt;  i8259_pic_t&lt;0xa0&gt; slave;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;0x20&lt;/span&gt; and &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;0xa0&lt;/span&gt; are port address for master and slave i8259 controller. In &lt;span style="font-family: trebuchet ms;"&gt;IA-32&lt;/span&gt;, I/O ports are used to communicate with hardware. The &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;i8259_pic_t::init&lt;/span&gt;(...) routine tells controller the base address of interrupt vectors it can use, the slave id if it is master and the initial mode. These purposes are all achieved by port operations.&lt;br /&gt;&lt;br /&gt;After interrupt controller is initialized, L4 tries to initial the hardware timer. The hardware timer is represented by &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;timer_t&lt;/span&gt; class, which is defined in &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;glue/v4-x86/timer.cc&lt;/span&gt;. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;timer_t::init_global&lt;/span&gt;() is used for initializing. At first it changes the interrupt vector entry in &lt;span style="font-family: trebuchet ms;"&gt;IDT&lt;/span&gt;. Then it uses &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;rtc_t&lt;/span&gt; class to hardware initialize the timer. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;rtc_t&lt;/span&gt; is defined in &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;platform/pc99/rtc.h&lt;/span&gt;. The hardware operation is achieved similar to i8259 through I/O port.&lt;br /&gt;&lt;br /&gt;The code after timer initialization is for SMP initialization. I don't talk about SMP currently, so I just skip it and see the initialization for scheduler. Scheduler is represented by &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;scheduler_t&lt;/span&gt; in file &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;api/v4/scheduler.h&lt;/span&gt; and &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;api/v4/scheduler.cc&lt;/span&gt;. The most work of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;scheduler_t::init&lt;/span&gt;(...) does is to create and initialize the idle thread.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;   get_idle_tcb()-&gt;create_kernel_thread(NILTHREAD, &amp;amp;__idle_utcb);&lt;br /&gt;   get_idle_tcb()-&gt;set_space(get_kernel_space());&lt;br /&gt;   get_idle_tcb()-&gt;myself_global.set_raw((word_t)0x1d1e1d1e1d1e1d1eULL);&lt;br /&gt;   get_idle_tcb()-&gt;create_startup_stack(idle_thread);&lt;br /&gt;   if( bootcpu )&lt;br /&gt;       get_idle_tcb()-&gt;notify(init_all_threads);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;get_idle_tcb&lt;/span&gt;() return's idle thread's &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;tcb_t&lt;/span&gt; structure. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;create_kernel_thread&lt;/span&gt;() is used for allocating thread ID and filling utcb field in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;tcb_t&lt;/span&gt; structure. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;set_space&lt;/span&gt;() sets the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;space_t&lt;/span&gt;  pointer. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;my_global.set_raw&lt;/span&gt;(...) sets the global TID. At last a startup stack is created for idle thread, and the entry point is &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;idle_thread&lt;/span&gt;().  How L4 creates and initializes thread will be detailed discussed when I investigate the API implementation of L4. At last, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;notify&lt;/span&gt;() will be call to set return point in stack to the function point of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_all_threads&lt;/span&gt;(). I will discuss this in next post, now I will explain &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;idle_thread&lt;/span&gt;(), which look like:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;   while(1)&lt;br /&gt;   {&lt;br /&gt;   if (!get_current_scheduler()-&gt;schedule(get_idle_tcb()))&lt;br /&gt;   {&lt;br /&gt;       spin(78, get_current_cpu());&lt;br /&gt;       processor_sleep();&lt;br /&gt;   }&lt;br /&gt;   }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;you see this is an endless loop, so this thread will never return. In &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;processor_sleep&lt;/span&gt;(),  instruction is used for stop CPU execution. The execution resumes when an external interrupt happens, e.g. timer interrupt. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;x86_sleep&lt;/span&gt;() in &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;arch/x86/cpu.h&lt;/span&gt; is used by &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;processor_sleep&lt;/span&gt;() to achieve the implementation with &lt;span style="font-family: trebuchet ms; color: rgb(204, 0, 0);"&gt;hlthlt&lt;/span&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;   INLINE void x86_sleep(void)&lt;br /&gt;   {&lt;br /&gt;       __asm__ __volatile__(&lt;br /&gt;           "sti   \n"&lt;br /&gt;           "hlt   \n"&lt;br /&gt;           "cli   \n"&lt;br /&gt;           :);&lt;br /&gt;   }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;before &lt;span style="font-family: trebuchet ms; color: rgb(204, 0, 0);"&gt;hlt&lt;/span&gt;, &lt;span style="font-family: trebuchet ms; color: rgb(204, 0, 0);"&gt;sti&lt;/span&gt; will enable the interrupt flag in EFLAGS, after that the flag will be cleared so that current interrupt can be handled. After &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init&lt;/span&gt;() routine &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;scheduler_t::start&lt;/span&gt;() routine will set the cpu that initial thread will run on and switch the stack to the initial thread (idle thread).&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;   INLINE void NORETURN initial_switch_to (tcb_t * tcb)&lt;br /&gt;   {&lt;br /&gt;       asm("movl %0, %%esp\n"&lt;br /&gt;       "ret\n"&lt;br /&gt;       :&lt;br /&gt;       : "r"(tcb-&gt;stack));&lt;br /&gt;       while (true)&lt;br /&gt;       /* do nothing */;&lt;br /&gt;   }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;the &lt;span style="font-family: trebuchet ms; color: rgb(204, 0, 0);"&gt;ret&lt;/span&gt; instruction will jump to the function entry pushed on the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;idle_stack&lt;/span&gt;. Then the system startup finishes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-8865603938822152089?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/8865603938822152089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=8865603938822152089' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/8865603938822152089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/8865603938822152089'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/l4-pistachio-kernel-8.html' title='L4 pistachio Kernel (8)'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-6289029542781347874</id><published>2008-02-15T12:08:00.000-08:00</published><updated>2009-10-13T05:53:15.219-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>L4 pistachio Kernel (7)</title><content type='html'>Since the next step is about initializing mapping database, it is better to shortly introduce mapping and mapping database before I go deeply.&lt;br /&gt;&lt;br /&gt;Mapping is a mechanism in L4 to share memory or allocate memory. A physical memory page can be mapped into different address spaces, but there is only one owner of this page. This owner can allow the other to map its memory page into their address space within permitted access right. The receivers can also give their received pages to other requesters, however the granted right cannot exceed what they received from owner. So you see, a lot of address space can have the same physical page. This implements the memory sharing. The owner can also give up his ownership of one page, so the one who mapped this page will own the page, this might be used as memory allocation. The latter one is unusual, because I think the memory manager should own all memory page and never give up the ownership so that it can monitor the memory usage. In fact, mapping with sharing can also achieve memory allocation. One important thing is that the the giver can take back page from all sub-mapped address space. For example, A, B, C, D are for address space, a page is mapped from A to B, from B to C, and from C to D. If A want to take back mapped page (unmap) from B then C and D also lose this page. In order to achieve this effect, mapping database is introduced to manage the hierarchical mapping relationship. The relationship is constructed as a tree. When a unmapping happens, L4 will search the tree and find the node that revoke the unmapping. Then according to each child and sub-child of this node, it find out the corresponding address space and remove the physical page from it. For more information, please read the Joshua's slides about L4 and watch his video about mapping. I thought, maybe I should put them on line sometimes.&lt;br /&gt;&lt;br /&gt;Now let's see the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_mdb&lt;/span&gt;() function. At first, I'd like to introduce some classes about mapping database, i.e. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mapnode_t&lt;/span&gt;, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;rootnode_t&lt;/span&gt; and &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;dualnode_t&lt;/span&gt;. I think &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mapnode_t&lt;/span&gt; is used to represent the address space received a mapping. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;rootnode_t&lt;/span&gt; represents the owner of physical page. What &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;dualnode_t&lt;/span&gt; represents, I am still not sure now. Looking into &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_mdb&lt;/span&gt;() may help a little. It first creates a array for root nodes by using &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mdb_create_roots&lt;/span&gt;(). This array covers the whole rage of possible address space of platform. But every node represents the biggest size of page supported by platform. For example, &lt;span style="font-family:trebuchet ms;"&gt;IA-32&lt;/span&gt; supports &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;4M&lt;/span&gt; page and the address space is &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;4G&lt;/span&gt;, the number of entries in this array is &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;4G&lt;/span&gt;/&lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;4M&lt;/span&gt; = &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;1024&lt;/span&gt;. See the following code,&lt;br /&gt;&lt;pre style="background: rgb(255, 255, 255) none repeat scroll 0% 0%; color: rgb(0, 0, 0); -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;dual &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt;&lt;br /&gt;    mdb_create_dual&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(125, 0, 69);"&gt;NULL&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt;mdb_create_roots&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;mapnode_t&lt;span style="color: rgb(128, 0, 128);"&gt;::&lt;/span&gt;size_max&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;static&lt;/span&gt; NOINLINE&lt;br /&gt;rootnode_t &lt;span style="color: rgb(128, 128, 48);"&gt;*&lt;/span&gt; mdb_create_roots &lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;mapnode_t&lt;span style="color: rgb(128, 0, 128);"&gt;::&lt;/span&gt;pgsize_e size&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="background: rgb(221, 0, 0) none repeat scroll 0% 0%; color: rgb(255, 255, 255); -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-weight: bold; font-style: italic;"&gt;{&lt;/span&gt;&lt;br /&gt;    rootnode_t &lt;span style="color: rgb(128, 128, 48);"&gt;*&lt;/span&gt;newnodes&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;*&lt;/span&gt;n&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    word_t num &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; mdb_arraysize &lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;size&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;    newnodes &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;rootnode_t &lt;span style="color: rgb(128, 128, 48);"&gt;*&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; mdb_alloc_buffer&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;sizeof&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;rootnode_t&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;*&lt;/span&gt;num&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;for&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;n &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; newnodes&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt; num&lt;span style="color: rgb(128, 128, 48);"&gt;-&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;-&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt; n&lt;span style="color: rgb(128, 128, 48);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;    n&lt;span style="color: rgb(128, 128, 48);"&gt;-&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;&gt;&lt;/span&gt;set_ptr &lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;mapnode_t &lt;span style="color: rgb(128, 128, 48);"&gt;*&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; &lt;span style="color: rgb(125, 0, 69);"&gt;NULL&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;return&lt;/span&gt; newnodes&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="background: rgb(221, 0, 0) none repeat scroll 0% 0%; color: rgb(255, 255, 255); -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-weight: bold; font-style: italic;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;INLINE word_t mdb_arraysize &lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;mapnode_t&lt;span style="color: rgb(128, 0, 128);"&gt;::&lt;/span&gt;pgsize_e pgsize&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="background: rgb(221, 0, 0) none repeat scroll 0% 0%; color: rgb(255, 255, 255); -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-weight: bold; font-style: italic;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;1&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;mdb_pgshifts&lt;span style="color: rgb(128, 128, 48);"&gt;[&lt;/span&gt;pgsize&lt;span style="color: rgb(128, 128, 48);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(0, 140, 0);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;]&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;-&lt;/span&gt;mdb_pgshifts&lt;span style="color: rgb(128, 128, 48);"&gt;[&lt;/span&gt;pgsize&lt;span style="color: rgb(128, 128, 48);"&gt;]&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="background: rgb(221, 0, 0) none repeat scroll 0% 0%; color: rgb(255, 255, 255); -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-weight: bold; font-style: italic;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The first assignment is located in &lt;span style="font-style: italic; color: rgb(204, 51, 204);"&gt;init_mdb&lt;/span&gt;(), where size_max represents 4M page. You can find this meaning in arch&lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;/x86/x32/ptab.h&lt;/span&gt; and &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;arch/x86/pgent.h&lt;/span&gt; by searching &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;X86_PGSIZES&lt;/span&gt;. Following the sequence of function call you will see in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mdb_arraysize&lt;/span&gt;() the maximal address space size is retrieved though max page size. It will be cleaner if you see &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;pgsize_e&lt;/span&gt; and &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mdb_pgshifts&lt;/span&gt;[]. Actually &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;pgsize_e&lt;/span&gt; is used as index in array &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mdb_pgshifts&lt;/span&gt;[], each entry represents a  supported page size by platform. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mdb_arraysize&lt;/span&gt;() converts the index finally into real page size.&lt;br /&gt;&lt;br /&gt;The node array is assigned to a created dual node and the map node in dual node is assigned as &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;NULL&lt;/span&gt;. The dual node is assigned to &lt;span style="font-family:trebuchet ms;"&gt;sigma0&lt;/span&gt;'s map node, which means &lt;span style="font-family:trebuchet ms;"&gt;sigma0&lt;/span&gt; can control a whole address space because of the root node array. Note, this still doesn't mean sigma0 own all physical memory. They are still not mapped into its address space.&lt;br /&gt;&lt;br /&gt;After initialization for &lt;span style="font-family:trebuchet ms;"&gt;sigma0&lt;/span&gt;'s map node. A page size support checking is executed. Then &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_mdb&lt;/span&gt;() finishes its work...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-6289029542781347874?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/6289029542781347874/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=6289029542781347874' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/6289029542781347874'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/6289029542781347874'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/l4-pistachio-kernel-7.html' title='L4 pistachio Kernel (7)'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-2584579756135768696</id><published>2008-02-14T03:04:00.000-08:00</published><updated>2009-10-13T05:47:31.298-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>L4 pistachio Kernel (6)</title><content type='html'>Let's continue the reading today. After &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;setup_gdt&lt;/span&gt;() comes &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;idt.activate&lt;/span&gt;(). This is similar to how people activates &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;GDT&lt;/span&gt; and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;TSS&lt;/span&gt;,&lt;br /&gt;&lt;pre style="background: rgb(255, 255, 255) none repeat scroll 0% 0%; color: rgb(0, 0, 0); -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;void&lt;/span&gt; SECTION&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 230);"&gt;.init.cpu&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt; idt_t&lt;span style="color: rgb(128, 0, 128);"&gt;::&lt;/span&gt;activate&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(128, 0, 128);"&gt;{&lt;/span&gt;&lt;br /&gt;     x86_descreg_t ide&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;word_t&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;descriptors&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;sizeof&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;descriptors&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;     idt&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;setdescreg&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;x86_descreg_t&lt;span style="color: rgb(128, 0, 128);"&gt;::&lt;/span&gt;idtr&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(128, 0, 128);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;These codes are located in &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;glue/v4_x86/idt.cc&lt;/span&gt;. It fill the value into &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;IDTR&lt;/span&gt;. However, what more interesting is how &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;IDT&lt;/span&gt; is initialized. The initialization filled each exception handler, by default, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;exc_catch_common&lt;/span&gt;. The codes for initialization follows the above codes and reside in class constructor &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;idt_t&lt;/span&gt;(). The most confused codes is the first loop in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;idt_t&lt;/span&gt;().&lt;br /&gt;&lt;pre style="background: rgb(255, 255, 255) none repeat scroll 0% 0%; color: rgb(0, 0, 0); -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;exc_catch_all&lt;span style="color: rgb(128, 128, 48);"&gt;[&lt;/span&gt;i&lt;span style="color: rgb(128, 128, 48);"&gt;]&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;sizeof&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;exc_catch_all&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;-&lt;/span&gt;i&lt;span style="color: rgb(128, 128, 48);"&gt;*&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;sizeof&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;u64_t&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;-&lt;/span&gt;&lt;span style="color: rgb(0, 140, 0);"&gt;5&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 140, 0);"&gt;8&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;0xe8&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt; add_int_gate&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;i&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;func_exc&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;&amp;amp;&lt;/span&gt;exc_catch_all&lt;span style="color: rgb(128, 128, 48);"&gt;[&lt;/span&gt;i&lt;span style="color: rgb(128, 128, 48);"&gt;]&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In order to understand this loop, it is necessary to read three files, i.e. &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;exception.cc&lt;/span&gt;, &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;linker-pc99.lds&lt;/span&gt; under directory &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;glue/v4-x86/x32&lt;/span&gt; and &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;glue/v4-x86/exception.cc&lt;/span&gt;. In the &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;linker-pc99.lds&lt;/span&gt; you will find that &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;exc_catch_all&lt;/span&gt;[] array and &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;exc_catch_common&lt;/span&gt; handler are put side by side. I describe this situation as follow,&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;________________&lt;br /&gt;|                |&lt;br /&gt;|                |&lt;br /&gt;|                |&lt;br /&gt;|                |&lt;br /&gt;|                |&lt;br /&gt;.                .&lt;br /&gt;. exc_catch_all  .&lt;br /&gt;.                .&lt;br /&gt;.                .&lt;br /&gt;|                |&lt;br /&gt;|                |&lt;br /&gt;|                |&lt;br /&gt;|                |&lt;br /&gt;|                |&lt;br /&gt;|________________|&lt;br /&gt;|                |&lt;br /&gt;|exc_catch_common|&lt;br /&gt;|________________|&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;from the above figure you may understand where &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;sizeof(exc_catch_all) - i*sizeof(u64_t)&lt;/span&gt; comes from. Closer the entry is to &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;exc_catch_common&lt;/span&gt;, smaller is the offset that should be filled into entry. I don't know if I clearly explained this stuff... Hope you understand. &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;0xe8&lt;/span&gt; represents the "near call with 4 byte offset (5 byte)", this is the reason for existence of "&lt;span style="color: rgb(204, 0, 0);font-family:trebuchet ms;" &gt;-5&lt;/span&gt;". After each entry is initialized, they are put into the descriptor table as interrupt gate. The rest code fills special entry in descriptor table with special values, e.g. replace the entry for handling pagefault with the function pointer &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;exc_pagefault&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;After &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;IDT&lt;/span&gt; is activated, an initializing routine for &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;KIP&lt;/span&gt; is called. The initializing routine sets the system call variables to their proper value, the function pointer of each system call routine. I am not very sure what &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;ARCH_SYSCALL&lt;/span&gt; is, I will investigate them later. Then more memory will be grabbed for kernel through &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;add_more_kmem&lt;/span&gt;(). It looks for the reserved contiguous memory region in &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;KIP&lt;/span&gt;'s memory descriptors. If there is one, it is reserved for our kernel. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;add_more_kmem&lt;/span&gt;() will put into free memory list in kernel memory manager. If there is not, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;add_more_kmem&lt;/span&gt;() continues to see if special memory descriptor reserved_mem1 is set and put the memory described by reserved_mem1 into free memory list. Then &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_meminfo&lt;/span&gt;() will reconstruct the memory descriptor map in KIP. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_meminfo&lt;/span&gt;() is located in &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;glue/v4-x86/x32/init.cc&lt;/span&gt;. The next step is initializing the mapping database in L4 pistachio. I will discuss it in next post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-2584579756135768696?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/2584579756135768696/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=2584579756135768696' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/2584579756135768696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/2584579756135768696'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/l4-pistachio-kernel-6.html' title='L4 pistachio Kernel (6)'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-7698081634475023961</id><published>2008-02-13T03:14:00.000-08:00</published><updated>2008-02-13T15:25:22.559-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>L4 pistachio Kernel (5) - IA-32 Registers</title><content type='html'>In last post I finished reading &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;init_kernel_space&lt;/span&gt;(), and now let's come back to &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;startup_system&lt;/span&gt;() and see the next step. The next step is initialize task state segment structure (&lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;TSS&lt;/span&gt;). What does this structure do, I will not discuss here. The initializing routine &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;tss.setup&lt;/span&gt;(...) for x86 architect is responsible for calculating the offset of IO protection bitmap and setting value of stopper (a variable) to &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;0xFF&lt;/span&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  INLINE void x86_tss_t::setup(u16_t ss0)&lt;br /&gt;  {&lt;br /&gt;      iopbm_offset =&lt;br /&gt;          (u16_t)((u64_t)io_bitmap - (u64_t)this);&lt;br /&gt;      stopper = 0xff;&lt;br /&gt;  }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;It seems that ss0 is not used in this initializing routine...why? I guess, maybe L4 doesn't use &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;TSS&lt;/span&gt;. But I am not very sure. Then global descriptor table(&lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;GDT&lt;/span&gt;) is setup through &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;setup_gdt&lt;/span&gt;(). I think it is better to explain first the basic structure of INTEL CPU and its registers. IMHO, there are three kinds of registers in the Intel's &lt;span style="font-family:trebuchet ms;"&gt;IA-32&lt;/span&gt; architect. One type is called Memory-Management Register, the second is called Control Register, the third is called General Purpose Register. I will not discuss the third kind here, since it is usually very familiar to most people.&lt;br /&gt;&lt;br /&gt;Memory-Management Register contains briefly 4 registers, i.e. global descriptor table register (&lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;GDTR&lt;/span&gt;), local descriptor table register (&lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;LDTR&lt;/span&gt;), interrupt descriptor table register (&lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;IDTR&lt;/span&gt;) and task register (&lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;TR&lt;/span&gt;). The format of each register consists of two parts, i.e. base address and limit. There is relationship among &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;GDTR&lt;/span&gt;, &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;LDTR&lt;/span&gt; and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;TR&lt;/span&gt;. Global descriptor table contains the content of &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;TR&lt;/span&gt; and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;LDTR&lt;/span&gt;. When task switch happens, CPU automatically reads the &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;LDTR&lt;/span&gt; descriptor and  descriptor from &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;TSS&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt; and &lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;GDT&lt;/span&gt; &lt;/span&gt;fill them into &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;LDTR&lt;/span&gt; and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;TR&lt;/span&gt;. That means theoretically each task can have its own Local Descriptor Table and Task State Segment. But most mode operating system doesn't use &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;TSS&lt;/span&gt;. Furthermore, I guess Linux doesn't use &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;LDT&lt;/span&gt; whereas Windows uses it. The &lt;span style="font-family:trebuchet ms;"&gt;figure 2.1&lt;/span&gt; in &lt;a href="http://www.intel.com/products/processor/manuals/index.htm"&gt;&lt;span style="font-style: italic;"&gt;Intel 64 and IA-32 Software Developer's Manual&lt;/span&gt;&lt;/a&gt; tells us when the registers and corresponding tables are useful. The &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;GDT&lt;/span&gt; and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;IDT&lt;/span&gt; are always necessary, since Intel architecture requires &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;GDT&lt;/span&gt; to provide the base segment descriptor, e.g the data segment descriptor for user mode (unprivileged) or the code segment descriptor for kernel mode (privileged), and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;IDT&lt;/span&gt; is at least used to handle the incoming interrupt. &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;LDT&lt;/span&gt; is useful when OS decides to use Trap gate and call gate, which are not very popular. &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;TSS&lt;/span&gt; is an alternative to accelerate the task switch speed, however this feature is alway not very popular. Anyway, &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;GDT&lt;/span&gt; and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;IDT&lt;/span&gt; are essential, but &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;LDT&lt;/span&gt; and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;TSS&lt;/span&gt; are not.&lt;br /&gt;&lt;br /&gt;Control Registers is made up with 6 register. They &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;CR0&lt;/span&gt;, &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;CR1&lt;/span&gt;, &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;CR2&lt;/span&gt;, &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;CR3&lt;/span&gt;, &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;CR4&lt;/span&gt; and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;CR8&lt;/span&gt;. &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;CR0&lt;/span&gt; is very important, since it controls a lot of important CPU behavior, e.g. on/off Paging, real/protected mode. &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;CR3&lt;/span&gt; is another important control register, it contains the root physical address of page directory table, remember how L4 set active page directory table in last post? &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;CR2&lt;/span&gt; contains the page fault linear address (virtual address).&lt;br /&gt;&lt;br /&gt;Ok, After this explanation let's continue to read the codes in startup_system(...). After the &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;TSS&lt;/span&gt; is initialized. It tried to initialize the global descriptor table.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  setup_gdt(tss, 0)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This function is defined in &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;glue/v4-x86/x32/init.cc&lt;/span&gt;. Looking into it, the first four lines are used to setting privileged code/data segment descriptor and unprivileged code/data segment.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  gdt[gdt_idx(X86_KCS)].set_seg(0, ~0UL, 0, x86_segdesc_t::code);&lt;br /&gt;  gdt[gdt_idx(X86_KCS)].set_seg(0, ~0UL, 0, x86_segdesc_t::data);&lt;br /&gt;  gdt[gdt_idx(X86_KCS)].set_seg(0, ~0UL, 3, x86_segdesc_t::code);&lt;br /&gt;  gdt[gdt_idx(X86_KCS)].set_seg(0, ~0UL, 3, x86_segdesc_t::data);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The third parameter indicates the privilege-level. 0 means the highest (privileged), 3 means the lowest (unprivileged).  The gdt variable is defined in glue&lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;/v4-x86/x32/init.cc&lt;/span&gt; as array of type &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;x86_segdesc_t&lt;/span&gt;. It also put the shared &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;UTCB&lt;/span&gt; page into &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;GDT&lt;/span&gt; as a separate segment. Then is the &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;TSS &lt;/span&gt;segment descriptor which we just initialized. Then codes set the &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;GDTR&lt;/span&gt; and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;TR&lt;/span&gt; register.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  x86_descreg_t gdtr((word_t) &amp;amp;gdt, sizeof(gdt));&lt;br /&gt;  gdtr.setdescreg(x86_descreg_t::gdtr);&lt;br /&gt;  x86_descreg_t tr((word_t) &amp;amp;tr, sizeof(tr));&lt;br /&gt;  tr.setdescreg(x86_descreg_t::tr);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Then some codes appear to make CPU to use the new settings.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  asm("ljmp %0, $1f \n"&lt;br /&gt;      "1: \n"&lt;br /&gt;      :&lt;br /&gt;      : "i" (X86_KCS)&lt;br /&gt;  );&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;ljmp&lt;/span&gt; will reload the segments setting from just filled &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;GDT&lt;/span&gt;. The next inline assembly fills all segment registers with correct value. Then the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;set_gdt&lt;/span&gt;(...) function finishes its work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-7698081634475023961?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/7698081634475023961/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=7698081634475023961' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/7698081634475023961'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/7698081634475023961'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/l4-pistachio-kernel-5-ia-32-registers.html' title='L4 pistachio Kernel (5) - IA-32 Registers'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-3187355175772043651</id><published>2008-02-12T13:50:00.000-08:00</published><updated>2008-02-13T03:13:40.500-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>L4 pistachio Kernel (4) - More</title><content type='html'>I will try to finish talking about &lt;span style="font-style: italic; color: rgb(153, 0, 0);"&gt;init_kernel_space&lt;/span&gt;(). The last big work is&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;   space_t::init_kernel_mappings();&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Before we talk about this structure, I'd like to introduce one structure &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mem_region_t&lt;/span&gt; in file &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;generic/memregion.h&lt;/span&gt;. It is used in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;kernel_interface_page_t&lt;/span&gt; for indicating the special memory regions, dedicated or reserved, e.g. bootmem region is recorded as the first reserved memory region in &lt;span style="color: rgb(51, 102, 255);font-family:trebuchet ms;" &gt;KIP&lt;/span&gt;. The most interesting thing here is how L4 guys put these information. Do you remember how &lt;span style="color: rgb(51, 102, 255);font-family:trebuchet ms;" &gt;KIP&lt;/span&gt; records information about &lt;span style="font-family:trebuchet ms;"&gt;sigma0&lt;/span&gt; and &lt;span style="font-family:trebuchet ms;"&gt;root_task&lt;/span&gt; when kickstart loads the kernel? Yeap, they use the undefined sections in &lt;span style="color: rgb(51, 102, 255);font-family:trebuchet ms;" &gt;KIP&lt;/span&gt;. This time the guys do the same, they use the other undefined regions to record special memory regions. Try to compare the structure definition of kernel_interface_page_t and the L4 manual, count the offset of following code:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;   class kernel_interface_page_t {&lt;br /&gt;       ...&lt;br /&gt;       mem_region_t main_men;&lt;br /&gt;       mem_region_t reserved_mem0;&lt;br /&gt;&lt;br /&gt;       mem_region_t reserved_mem1;&lt;br /&gt;       mem_region_t dedicated_mem0;&lt;br /&gt;&lt;br /&gt;       mem_region_t dedicated_mem1;&lt;br /&gt;       mem_region_t dedicated_mem2;&lt;br /&gt;&lt;br /&gt;       mem_region_t dedicated_mem3;&lt;br /&gt;       mem_region_t dedicated_mem4;&lt;br /&gt;       ...&lt;br /&gt;   };&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;you will find it is between &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;0x60&lt;/span&gt; and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;0x90&lt;/span&gt;, where is marked undefined in manual. So almost each undefined sections in &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;KIP&lt;/span&gt; is used for some purpose. Ok, let's come back to the function &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;init_kernel_mappings&lt;/span&gt;&lt;span style="color: rgb(204, 0, 0); font-style: italic;font-family:courier new;" &gt;&lt;/span&gt;(). Till this point all kernel are still working at 1-1 mapping style, which means virtual address is the same as physic address. After &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_kernel_mappings&lt;/span&gt;() function, the kernel will be put into correct virtual address area, i.e. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;phys_addr&lt;/span&gt; + &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;KERNEL_OFFSET&lt;/span&gt;. An example is to remap the boot memory region, which is stored in reserved_mem0:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;   mem_region_t reg = get_kip()-&gt;reserved_mem0;&lt;br /&gt;   align_memregion(reg, KERNEL_PAGE_SIZE);&lt;br /&gt;   remap_area(phys_to_virt(reg.low), reg.low, PGSIZE_KERNEL,&lt;br /&gt;          reg.get_size(), true, true, true);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;These codes first get the memory information, then align it to page size, at last remap them into correct virtual address area. Then the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;.init&lt;/span&gt; segment will also be remapped into high virtual area, after that is the special low 4M memory region, video memory and a special page for UTCBs. The page is a part of kernel stuff, but it can be accessed through gs:0. L4 guys do this in order to get rid of some unnecessary kernel/user switchs. The rest part of code is very special. I am not going to talk about them currently. After I finish the whole general review, I may come back to talk about them. One question here is why the UTCB page be allocated and remapped twice? I may dig it out sometimes.&lt;br /&gt;&lt;br /&gt;At the end of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_kernel_space&lt;/span&gt;() is the action to load current root space's page table into gdt register. This is achieved through:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;   x86_mmu_t::set_active_pagetable(&lt;br /&gt;                 (word_t)kernel_space-&gt;get_top_pdir_phys(0))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The method is implemented in &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;arch/x86/mmu.h&lt;/span&gt; by moving the root address into &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;CR3&lt;/span&gt; register.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-3187355175772043651?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/3187355175772043651/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=3187355175772043651' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/3187355175772043651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/3187355175772043651'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/l4-pistachio-kernel-4-more.html' title='L4 pistachio Kernel (4) - More'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-3479257427385894641</id><published>2008-02-12T03:42:00.001-08:00</published><updated>2008-02-12T13:07:19.886-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>L4 pistachio Kernel (4)</title><content type='html'>In last post I stopped after &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;kmem.init&lt;/span&gt;(...), now let's see the next statement:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;get_kip()-&gt;reserved_mem0.set(...);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Here, I was stopped by finding what &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;get_kip&lt;/span&gt;() does. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;get_kip&lt;/span&gt;() was defined in &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;api/v4/kernelinterface.h&lt;/span&gt; as,&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;INLINE kernel_interface_page_t * get_kip()&lt;br /&gt;{&lt;br /&gt;    return &amp;KIP;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;before this function definition, there is a declaration for &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;KIP&lt;/span&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;extern "C" {&lt;br /&gt;    extern kernel_interface_page_t KIP;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;First this is not the real declaration of KIP because of the "&lt;span style="color: rgb(51, 51, 255);"&gt;extern&lt;/span&gt;" keyword. The real declaration and initialization locate in &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;api/v4/kernelinterface.cc&lt;/span&gt; as,&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;kernel_interface_page_t KIP UNIT(KIP_SECTION) =&lt;br /&gt;{&lt;br /&gt;    ...&lt;br /&gt;};&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;One more thing you should know is that KIP is on earth the same as variable kip. It is defined at the beginning of file &lt;span style="color: rgb(153, 153, 0);"&gt;kernelinterface.h&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;#define KIP kip&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The function &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;reserved_mem0.set&lt;/span&gt;(...) is used to set the kernel occupied region as reserved. After this, the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_bootmem&lt;/span&gt;() finishes its work.&lt;br /&gt;&lt;br /&gt;Following the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_bootmem&lt;/span&gt;() is the initialization code for &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;space_t&lt;/span&gt; structure. According to lecture given by Joschua, every L4 thread has its &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;space_t&lt;/span&gt; structure, but all L4 threads share the same kernel region. The shared region is based on a root space(kernel space). Mostly that means all kernel stuff in other &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;space_t&lt;/span&gt; will be synchronized upon the root space (I guess). The &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_kernel_space&lt;/span&gt;() is a static function defined in &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;glue/v4-x86/space.cc&lt;/span&gt; and responsible for initializing this root &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;space_t&lt;/span&gt;. Looking into &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_kernel_space&lt;/span&gt;(), it first check if the kernel space is already initialized,&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;ASSERT(!kernel_space);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Then it tried to allocate memory for kernel &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;space_t&lt;/span&gt;, this is achieved through &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;alloc&lt;/span&gt;(...) function in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;kmem_t&lt;/span&gt; class.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;kernel_space=&lt;br /&gt;   (space_t*)kmem.alloc(kmem_space,sizeof(space_t));&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Be careful, there are two &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;alloc&lt;/span&gt;(...) functions. One is declared as public, the other is declared as protected. The latter is called by former. The reason for this is that the public &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;alloc&lt;/span&gt;(...) function contains codes for debugging. Then it checks if the allocation is successful,&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;ASSERT(kernel_space);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;then &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_kernel_space&lt;/span&gt;() also allocate memory to page directory for kernel space and record the address of kernel address in itself.  If you look into &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;space_t&lt;/span&gt; class, you will find how L4 divide its address space. The whole address space, represented by class &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;top_pdir_t&lt;/span&gt;, is divided into five sections:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;class top_pdir_t{&lt;br /&gt;public:&lt;br /&gt;union{&lt;br /&gt;    pgent_t pgent[1024];  //allocate enough space&lt;br /&gt;    struct {&lt;br /&gt;    x86_pgent_t&lt;br /&gt;      user[USER_AREA_END&gt;&gt;X86_X32_PDIR_BITS];&lt;br /&gt;    x86_pgent_t&lt;br /&gt;      small[SMALLSPACE_AREA_SIZE &gt;&gt; X86_X32_PDIR_BITS];&lt;br /&gt;    x86_pgent_t&lt;br /&gt;      copy_area[COPY_AREA_COUNT]&lt;br /&gt;    [COPY_AREA_SIZE &gt;&gt; X86_X32_PDIR_BITS];&lt;br /&gt;    x86_pgent_t&lt;br /&gt;      readmem_area[MEMREAD_AREA_SIZE &gt;&gt; X86_X32_PDIR_BITS];&lt;br /&gt;    space_t * space;&lt;br /&gt;}; // five sections&lt;br /&gt;};&lt;br /&gt;};&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The first section is user space, then a section for small space, which is used to optimize the performance. You can put such as device driver in this space to reduce the space switch. The third section called copy area, the string copy between two address space can be achieved more efficient by mapping the target space into this area and avoid one space switch. The forth section is the readonly section of kernel. After that is a section for mixed variables. You can find more information from the slides of MKC lectured in Uni. Karlsruhe.&lt;br /&gt;&lt;br /&gt;After the memory is successfully allocated for kernel space, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init_kernel_mappings&lt;/span&gt;() is used to initialize the mappings in kernel space. I will talk it in next post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-3479257427385894641?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/3479257427385894641/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=3479257427385894641' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/3479257427385894641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/3479257427385894641'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/l4-pistachio-kernel-4.html' title='L4 pistachio Kernel (4)'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-2962509439133596630</id><published>2008-02-11T06:44:00.000-08:00</published><updated>2008-02-12T16:28:13.171-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>Short Note (2) - Good Resource</title><content type='html'>If you want to understand L4 pistachio micro kernel, I recommend you watch Joshua LeVasseur's teaching records. You can get them from &lt;a href="http://i30www.ira.uka.de/teaching/courses/lecture.php?courseid=150&amp;amp;lid=en"&gt;here&lt;/a&gt;. Note they are password protected, but I think you can ask the guy in Uni. Karlsruhe for the username and password.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-2962509439133596630?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/2962509439133596630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=2962509439133596630' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/2962509439133596630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/2962509439133596630'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/short-note-2-good-resource.html' title='Short Note (2) - Good Resource'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-3513206868476023010</id><published>2008-02-11T02:48:00.000-08:00</published><updated>2008-02-11T06:42:46.354-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><title type='text'>L4 pistachio Kernel (3)</title><content type='html'>First of all, I have to mention again that a lot of variables are &lt;span class="Apple-style-span" style="color: rgb(255, 102, 0);"&gt;not directly declared&lt;/span&gt; in source files &lt;span class="Apple-style-span" style="color: rgb(255, 102, 0);"&gt;but in linker script&lt;/span&gt;. You will see that during my explanation. Yesterday I stopped at function &lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="color: rgb(204, 0, 0);"&gt;startup_system&lt;/span&gt;&lt;/span&gt;(). What this function does is initializing the kernel structure and activating some functions. Let's start looking into it.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt; if(is_ap)&lt;br /&gt;    startup_processor();&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;This is used in multiprocessor scenario in order to initial and startup adjunct processor. It is not in the range of our current discussion.&lt;br /&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt; clear_bss();&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/span&gt;Then BSS section is cleared. I am not very sure if this is necessary since I remember it is cleared when kernel is relocated.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt; call_global_ctors();&lt;br /&gt; call_node_ctors();&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;are two statements used for invoking constructors. Why? Don't forget that L4 didn't use the standard C/C++ library, so the initialization routine included in this library is not linked into the pistachio kernel. However, L4 pistachio uses C/C++ as its default programming language, people must find a way to follow the C/C++ ABI convention. These two statements are used for this purpose. If we look deeper inside these two functions, you will find there are an array of functions to be called, e.g. in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;call_global_ctors&lt;/span&gt;(), defined in ctors.cc, it works like:&lt;pre&gt;&lt;code&gt;&lt;br /&gt; for (unsigned int i = 0; __ctors_GLOBAL__[i] != 0; i++)&lt;br /&gt;    __ctors_GLOBAL__[i]();&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;where &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;__ctors_GLOBAL__&lt;/span&gt;[] are declared in ctors.ldi. After the C/C++ convention requirement is filled,&lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt; init_hello&lt;/span&gt;() is used to display a message on the output console. Usually you will see it on the com port monitor, e.g. minicom. This function is special, it only works when you activate the debug option when you configure the kernel build. Otherwise, it is replaced by a empty statement.&lt;pre&gt;&lt;code&gt;&lt;br /&gt; check_cpu_features();&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;is the next step. It was defined in glue&lt;span style="font-style: italic; color: rgb(204, 153, 51);"&gt;/v4-x86/x32/init.cc&lt;/span&gt;. It checks if CPU has all features L4 required. If not, it will print all missed feature and stop execution. Of course, &lt;span style="color: rgb(204, 0, 0);font-family:trebuchet ms;" &gt;CPUID&lt;/span&gt; is used to finish this checking. For how to check if CPU supports &lt;span style="color: rgb(204, 0, 0);font-family:trebuchet ms;" &gt;CPUID&lt;/span&gt; instruction, you'd like to check function &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;x86_x32_has_cpuid&lt;/span&gt;(). Inside this function, it uses EFLAG to check the existence of &lt;span style="color: rgb(204, 0, 0);font-family:trebuchet ms;" &gt;CPUID&lt;/span&gt; instruction. What kind of features are necessary for L4? It is relied on your configuration. &lt;pre&gt;&lt;code&gt;&lt;br /&gt; init_bootmem();&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;prepares the scratch space "boot mem" that I mentioned when I explained the linker script. At first, it clear up the region. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;start_bootmem&lt;/span&gt; and &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;end_bootmem&lt;/span&gt; are two variables defined in linker script. Now we are going to see something about kernel memory management. The kernel memory management is achieved by kmem of class kmem_t, which you can find in file &lt;span style="font-style: italic; color: rgb(204, 153, 51);"&gt;generic/kmemory.h&lt;/span&gt; and &lt;span style="font-style: italic; color: rgb(204, 153, 51);"&gt;generic/kmemory.cc&lt;/span&gt;. In current stage, we need to initialize this manager by invoking &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;kmem.init&lt;/span&gt;(...). The &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;init&lt;/span&gt;(...) function does only two things, initialize the variable for kernel memory management:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt; kmem_free_list = NULL;&lt;br /&gt; free_chunks = 0;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;and register the boot memory area as free memory in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;kmem_free_list&lt;/span&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt; free(start, (word_t)end - (word_t)start);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;free&lt;/span&gt;(...) function is used to update the information about free memory resource. It first tests the region that is declared as free, e.g. size checking. Then it splits the free region into predefined chuck size and organizes them as a list, if necessary. Following codes do this:&lt;pre&gt;&lt;code&gt;&lt;br /&gt; for( p = (word_t*)address;&lt;br /&gt; p &lt; ((word_t*)(((word_t)address)+size - KMEM_CHUNKSIZE));&lt;br /&gt; p = (word_t *) *p)  *p = (word_t)&lt;br /&gt;     p + KMEM_CHUNKSIZE; &lt;/code&gt;&lt;/pre&gt;At last, the organized list is inserted into free memory list as following:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;span style="color: rgb(51, 51, 255);"&gt; // Iterating the list and find a place&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; for (pre=(word_t*)(void *)&amp;amp;kmem_free_list,&lt;br /&gt;     curr = kmem_free_list;&lt;br /&gt; curr &amp;amp;&amp;amp; (address &gt; curr);&lt;br /&gt; prev = curr, curr = (word_t*) *curr);&lt;br /&gt;&lt;/code&gt;&lt;code&gt;&lt;span style="color: rgb(51, 51, 255);"&gt; // insert here&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt; *prev = (word_t)address; *p = (word_t) curr;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;There are two things you need to know. First, before modifying the list structure, L4 uses spinlock to prevent the race condition. Second, &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;KMEM_CHECK&lt;/span&gt; is meaningless currently, it is declared as empty.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After the boot memory is register for free, it is also declared as reserved memory region, so that user cannot use it. Ok, I think it is enough for today :).&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/975103007691482821-3513206868476023010?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/3513206868476023010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=3513206868476023010' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/3513206868476023010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/3513206868476023010'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/l4-pistachio-kernel-3.html' title='L4 pistachio Kernel (3)'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-4960991799739082607</id><published>2008-02-10T13:13:00.001-08:00</published><updated>2008-02-11T06:37:38.071-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>Short Note (1) - BSP v.s. AP</title><content type='html'>During reading the source code of pistachio, I was stopped by BSP and AP. After searching I get the result:&lt;br /&gt;&lt;br /&gt;BSP - Bootstrap Processor&lt;br /&gt;AP   - Adjunct Processor&lt;br /&gt;&lt;br /&gt;They are used in multi-processor scenario.&lt;br /&gt;&lt;span style="font-size:-1;"&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-4960991799739082607?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/4960991799739082607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=4960991799739082607' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/4960991799739082607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/4960991799739082607'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/short-notebsp-vs-ap.html' title='Short Note (1) - BSP v.s. AP'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-2867046028313457775</id><published>2008-02-10T04:21:00.000-08:00</published><updated>2008-02-10T09:38:52.564-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><title type='text'>L4 pistachio Kernel (2)</title><content type='html'>Today, I am going to start reading codes of L4 pistachio. I don't want to complicate the explanation, my discussion only focuses on IA-32 uniprocessor system. Let's start with &lt;span style="color: rgb(153, 153, 0); font-style: italic;"&gt;startup.S&lt;/span&gt;, located in &lt;span style="color: rgb(0, 204, 204); font-style: italic;"&gt;platform&lt;/span&gt;, which takes over the control from kickstart. One thing I have to mention is that I was trying to explain the codes one directory after another, however this doesn't work. So I decided to follow the control flow and explain whatever I encounter.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;The code in &lt;span style="color: rgb(153, 153, 0); font-style: italic;"&gt;startup.S&lt;/span&gt; is very similar to the codes in &lt;span style="color: rgb(153, 153, 0); font-style: italic;"&gt;star&lt;/span&gt;&lt;span style="color: rgb(153, 153, 0); font-style: italic;"&gt;tup.S&lt;/span&gt; of kickstart. It first initializes the segments:&lt;pre&gt;&lt;code&gt;&lt;br /&gt;.section .init.startup32&lt;br /&gt;.code32&lt;br /&gt;start:&lt;br /&gt;_start:&lt;br /&gt; cli&lt;br /&gt; cld&lt;br /&gt; mov %ds, %ax&lt;br /&gt; mov %ax, %es&lt;br /&gt; mov %ax, %fs&lt;br /&gt; mov %ax, %gs&lt;br /&gt; mov %ax, %ss&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Here, &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;.init.startup32&lt;/span&gt; shows that following codes belongs to &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;.init&lt;/span&gt; section, see &lt;span style="color: rgb(153, 153, 0); font-style: italic;"&gt;linker-pc99.lds&lt;/span&gt;. Then &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;.code32&lt;/span&gt; indicates that these codes are executed in protected mode of x86 machine. Defining both labels &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;start&lt;/span&gt; and &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;_start&lt;/span&gt; is for the compatibility of different compiler. Then:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt; lea _mini_stack-4, %esp&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;will set the stack for further execution. B.T.W. &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;lea&lt;/span&gt; means &lt;span style="color: rgb(255, 102, 102);"&gt;load effective address&lt;/span&gt;. After this step, kernel is going to initialize the paging system and the call &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;init_paging&lt;/span&gt; function. The &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;init_paging&lt;/span&gt; is defined in &lt;span style="color: rgb(0, 204, 204); font-style: italic;"&gt;glue/v4-x86/x32/init.cc&lt;/span&gt;. Take a look  in the function, two variables are initialized, i.e. &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;init_pdir[]&lt;/span&gt; and &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;init_ptable[][]&lt;/span&gt;. &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;init_pdir[]&lt;/span&gt; represents the initial page directory and &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;init_ptable[][]&lt;/span&gt; contains the page table&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;s&lt;/span&gt; that will be installed into page directory. The first dimension of &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;init_ptable[][]&lt;/span&gt; indexes the address of each page table, the second dimension contains the actual page table entries. The following codes are the most important in this function,&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;for (int i = 0; i &lt; MAX_KERNEL_MAPPINGS; i++)&lt;br /&gt;{&lt;br /&gt;for (int j = 0; j &lt; 1024; j++)&lt;br /&gt; // first assignment&lt;br /&gt; init_ptable[i][j] = ((i &lt;&lt; IA32_PDIR_BITS) |&lt;br /&gt;        (j &lt;&lt; X86_PAGE_BITS)  |&lt;br /&gt;        PAGE_ATTRIB_INIT);&lt;br /&gt; // second assignment&lt;br /&gt; init_pdir[i] =&lt;br /&gt;  init_pdir[(KERNEL_OFFSET &gt;&gt; IA32_PDIR_BITS) + 1] =&lt;br /&gt;  (word_t)(init_ptable[i]) | PAGE_ATTRIB_INIT;&lt;br /&gt;} &lt;/code&gt;&lt;/pre&gt;The first assignment initializes page tables with  the physic address from &lt;span style="font-family: trebuchet ms; color: rgb(51, 51, 255);"&gt;0&lt;/span&gt;. The second assignment puts each page table into two places of the virtual memory space. One place is the &lt;span style="font-family: trebuchet ms;"&gt;1-1&lt;/span&gt; mapping place and the second place is kernel area in the virtual memory space, see the figure below.&lt;br /&gt;&lt;pre&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CnqxOYln9N8/R68uWxHN8SI/AAAAAAAAAAs/TsvMAUycYp0/s1600-h/ptable.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_CnqxOYln9N8/R68uWxHN8SI/AAAAAAAAAAs/TsvMAUycYp0/s320/ptable.JPG" alt="" id="BLOGGER_PHOTO_ID_5165398266292859170" border="0" /&gt;&lt;/a&gt;&lt;/pre&gt;&lt;br /&gt;After the initial virtual memory space is filled, the page directory table should be installed into MMU. The MMU functions can be found in directory &lt;span style="font-style: italic; color: rgb(0, 204, 204);"&gt;arch/x86/mmu.h&lt;/span&gt;. I will discuss two of them in this post. The first is &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;set_active_pagetable(...)&lt;/span&gt;, which is actually implemented with one assembly instruction,&lt;br /&gt;&lt;pre&gt;&lt;code&gt; mov root_addr, %cr3&lt;/code&gt;&lt;/pre&gt;since we are in privileged mode, &lt;span style="color: rgb(51, 51, 255);font-family:trebuchet ms;" &gt;CR3&lt;/span&gt; register can be modified. The second is &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;enable_paging&lt;/span&gt;(). It uses &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;x86_cr0_set&lt;/span&gt;(...) to change the flags about paging in &lt;span style="color: rgb(51, 51, 255);font-family:trebuchet ms;" &gt;CR0 &lt;/span&gt;register. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;x86_cr0_set&lt;/span&gt; can be found in file &lt;span style="font-style: italic; color: rgb(0, 204, 204);"&gt;arch/x86/cpu.h&lt;/span&gt;.  Its work is reading &lt;span style="color: rgb(51, 51, 255);font-family:trebuchet ms;" &gt;CR0&lt;/span&gt;, ORing its value with the given value and writing back to &lt;span style="color: rgb(51, 51, 255);font-family:trebuchet ms;" &gt;CR0&lt;/span&gt;. After the paging is enabled. The control flow runs back to &lt;span style="font-style: italic; color: rgb(153, 153, 0);"&gt;startup.S&lt;/span&gt;. The mini stack is cleared and &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;startup_system &lt;/span&gt;is called, which I will explained next time.&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/975103007691482821-2867046028313457775?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/2867046028313457775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=2867046028313457775' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/2867046028313457775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/2867046028313457775'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/l4-pistachio-kernel-2.html' title='L4 pistachio Kernel (2)'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_CnqxOYln9N8/R68uWxHN8SI/AAAAAAAAAAs/TsvMAUycYp0/s72-c/ptable.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-3120111389529068081</id><published>2008-02-09T11:25:00.000-08:00</published><updated>2008-02-09T11:29:55.636-08:00</updated><title type='text'>The Saturday :)</title><content type='html'>It's Saturday. It is the day I chat with my parents in Shanghai. So I just want to rest my soul today. Totally relax! (Although I read part of paper for variable radix page table, Hey~).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-3120111389529068081?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/3120111389529068081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=3120111389529068081' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/3120111389529068081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/3120111389529068081'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/saturday.html' title='The Saturday :)'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-7847030014539037854</id><published>2008-02-08T01:24:00.000-08:00</published><updated>2008-02-10T05:02:20.522-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><title type='text'>L4 pistachio Kernel (1)</title><content type='html'>Following the plan, I'd like to explain the linker script used to build L4 pistachio kernel. I discuss this because I was confused when I first touch the source code of L4. At least, I don't know where to start reading the codes. The Makefile can help a little, but it doesn't reveal the structure of kernel, but only indicates the requirements for building the kernel. For example, you need to specify the option so that linker doesn't use the standard C library for your binary (It is meaningless to use it, since there is no such library when the kernel boots). However, Makefile gives me a tip where to find the structure of binary, the linker script. During reading the Makefile, I recognize the option that commands the GNU linker to finally generate binary, where also indicates which linker script is used.&lt;br /&gt;&lt;br /&gt;Recall! I only focus on the source codes for IA-32 platform. For other platforms, you can use the same way as I used for IA-32 to analyze them.&lt;br /&gt;&lt;br /&gt;First of all, the major linker script for IA-32 platform is stored in directory:&lt;br /&gt;&lt;blockquote style="color: rgb(204, 0, 0);"&gt;(l4-top-dir)/kernel/src/glue/v4-x86/x32/&lt;/blockquote&gt;and named &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;linker-pc99.lds&lt;/span&gt;. Through the whole file, you can find out more sub linker scripts which are included in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;linker-pc99.lds&lt;/span&gt;. They are &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;kip.ldi&lt;/span&gt;, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;linkersets.ldi&lt;/span&gt;, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mdb.ldi&lt;/span&gt;, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;ctor.ldi&lt;/span&gt; and &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;debug.ldi&lt;/span&gt;. They are responded to different sections in final binary.&lt;br /&gt;&lt;br /&gt;Before I go further, I'd like to mention one thing that in linker script people can also define variable used in source code. Verse vise, you can also use the variables defined in C source code in linker script. The variable "&lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;memory_descriptors&lt;/span&gt;" is a good example. You may be confused because there is no declaration for this variable, but it is used in the linker script. To find the declaration of this variable is not a easy way for me to go. But at last, I found it in file &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;kernelinterfaces.cc&lt;/span&gt;. The declaration is not finished directly, it looks like:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;#if !define(KIP_MEMDESCS)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;#define KIP_MEMDESCS memory_descriptors&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;#endif&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;extern "C" {&lt;br /&gt;memdesc_t &lt;span style="color: rgb(204, 51, 204);"&gt;KIP_MEMDESCS&lt;/span&gt;[&lt;span style="color: rgb(204, 51, 204);"&gt;KIP_MIN_MEMDESCS&lt;/span&gt;]\&lt;br /&gt;  &lt;span style="color: rgb(204, 51, 204);"&gt;UNIT&lt;/span&gt; (&lt;span style="color: rgb(204, 51, 204);"&gt;KIP_SECTION&lt;/span&gt; ".mdesc);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;As you saw above, the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;memory_descriptors&lt;/span&gt; is declared through Marco "&lt;span style="color: rgb(204, 51, 204);"&gt;KIP_MEMDESCS&lt;/span&gt;". A lot of Macros are used in pistachio's source code. It may be easy for coding but it's really difficult for reading.&lt;br /&gt;&lt;br /&gt;Now let's walk through the linker_pc99.lds. In the beginning,&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;ENTRY(_start)&lt;br /&gt;&lt;br /&gt;BOOTMEM_SIZE = 128K;&lt;br /&gt;&lt;br /&gt;_start_text_phys = 0x00100000 + 0x200;&lt;br /&gt;_start_text = _start_text_phys + KERNEL_OFFSET;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;it declares entry point for the binary, which is labeled as "&lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;_start&lt;/span&gt;". Then the size of a scratch region for booting are defined. Then &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;_start_text_phys&lt;/span&gt; indicates the physic memory location for the kernel to load, and &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;_start_text&lt;/span&gt; is the virtual address location for the kernel, where &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;KERNEL_OFFSET&lt;/span&gt; is defined in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;offsets.h&lt;/span&gt; as &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;0xF0000000&lt;/span&gt;. From this declaration we know that kernel is loaded into the &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;0x00100000&lt;/span&gt; in the physic memory and &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;0xF0100000&lt;/span&gt; in every L4 thread's address space.&lt;br /&gt;&lt;br /&gt;The SECTIONS indicates the organization of binary. Briefly it is made up of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;.text&lt;/span&gt; section, &lt;span style="font-style: italic; color: rgb(255, 0, 0);"&gt;.utramp&lt;/span&gt; section, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;.rodata&lt;/span&gt; section, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;.kip&lt;/span&gt; section, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;.cpulocal&lt;/span&gt; section, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;.data&lt;/span&gt; section, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;.kdebug&lt;/span&gt; section, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;.sets&lt;/span&gt; section and &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;.init&lt;/span&gt; section. However, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;.init&lt;/span&gt; section is different from the others, if you see the attributes of each sections. The most section are specified as:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;.#section# . : AT (ADDR(.#section# - KERNEL_OFFSET))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;but .init section is defined as:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;.init (. - KERNEL_OFFSET) : AT (ADDR(.init))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The attribute before ":" specifies the virtual address, the attribute after ":" specifies the physic address (I guess).  For more information you can see &lt;a href="http://www.gnu.org/software/binutils/manual/ld-2.9.1/html_mono/ld.html#SEC21"&gt;this section&lt;/a&gt; in GNU linker manual. So the statement for &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;.init&lt;/span&gt; section indicates that its virtual address is the same as its physic address! It is a 1-1 mapping. For this setting is because there is still no paging system during the init stage.&lt;br /&gt;&lt;br /&gt;One more thing is that that all section is page aligned(4K in IA-32). It is achieved by code:&lt;br /&gt;&lt;pre&gt;&lt;code&gt; ALIGN(4K);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;why is this necessary? Do you still remember how kickstart find KIP page? Yea...This is one of reasons that make every section page aligned!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-7847030014539037854?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/7847030014539037854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=7847030014539037854' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/7847030014539037854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/7847030014539037854'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/l4-pistachio-kernel-1.html' title='L4 pistachio Kernel (1)'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-7929716937418670783</id><published>2008-02-07T11:21:00.000-08:00</published><updated>2008-02-07T12:02:46.185-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><title type='text'>L4 pistachio Kernel - Road Map</title><content type='html'>I am very tired today, since I traveled for almost whole day. So today I'd like only to list out a road map for next step - reading source code of L4 pistachio kernel.&lt;br /&gt;&lt;br /&gt;The source tree for L4 pistachio kernel consists of for major sub directory. They are "api", "generic", "glue" and "platform". "api" contains the codes for constructing system calls. "generic" contains mostly the memory management stuff. "glue" contains the code that abstracts the hardware platform, e.g. codes implementing interrupt &amp;amp; exception mechanism in kernel. User application cannot directly modify the interrupt description table, L4 provides interface for user to set their interrupt or exception handler. At last, "platform" directory contains the code to initialize the platform dependent hardware, for example, the interrupt controller, CPU. It also contains the the codes to startup the kernel - Startup.S.&lt;br /&gt;&lt;br /&gt;In the next days, I will first try to analyze the linker script and figure out the structure of kernel binary. Then I will start with "platform" directory, followed by "glue" and "generic", and finally "api". I am not sure yet, which of "glue" and "generic" I should review firstly. Most probably I will analyze the code in these directories mixed.&lt;br /&gt;&lt;br /&gt;Before I finish this post, I recommend you (if there is one :) to read the paper about &lt;a href="http://www.ertos.nicta.com.au/publications/papers/Szmajda_Heiser_03.abstract"&gt;radix page table&lt;/a&gt;, since pistachio seems using such kind of page table instead of traditional page table.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-7929716937418670783?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/7929716937418670783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=7929716937418670783' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/7929716937418670783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/7929716937418670783'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/l4-pistachio-kernel-road-map.html' title='L4 pistachio Kernel - Road Map'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-7176977050535963256</id><published>2008-02-06T02:13:00.000-08:00</published><updated>2008-02-06T03:48:58.646-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='kickstart'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><title type='text'>Kickstart - kick the kenrel to start (5) - ELF</title><content type='html'>In last post I finished walking through the main routines of kickstart. However, I put the ELF stuff aside in order not to destroy the continuity of explanation. Today I would like to pick back ELF stuff and make them clear. At first, I'd like to make a brief introduce of ELF.&lt;br /&gt;&lt;br /&gt;ELF means "executable and linkable format". It defines a way how people constructs a executable or linkable file. A file in ELF format usually contains three headers, i.e. ELF header, section header and program header.&lt;br /&gt;&lt;br /&gt;The ELF header indicates some brief information about the whole file. For example, it contains the identity of ELF. The identity is 16-byte long. The first four bytes must contain &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;0x7F&lt;/span&gt;, '&lt;span style="color: rgb(204, 51, 204);"&gt;E&lt;/span&gt;', '&lt;span style="color: rgb(204, 51, 204);"&gt;L&lt;/span&gt;', and '&lt;span style="color: rgb(204, 51, 204);"&gt;F&lt;/span&gt;'. The fifth byte indicates in what kind of platform the ELF file fits, e.g. &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;1&lt;/span&gt; means 32-bit platform and &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;2&lt;/span&gt; means 64-bit platform. ELF header also contains the offset to section header and program header in file. For more details about ELF you can check &lt;a href="http://www.sco.com/developers/gabi/2001-04-24/ch4.eheader.html#elfid"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The section header contains very detailed organization information about the ELF file, since the ELF file is made up with various sections. It is useful for linker but not so important when the file need to be loaded into memory for execution. For your interesting you can learn it from &lt;a href="http://www.sco.com/developers/gabi/2001-04-24/ch4.sheader.html"&gt;this site&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The program header is relevant for all ELF loader, because it tells loader how to split the content of current ELF file and where to put them in the memory. What may confuse you here is the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;vaddr&lt;/span&gt; and &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;paddr&lt;/span&gt; field in program header. In my opinion, the vaddr (virtual address) field is only used when the virtual address mechanism is turned on in system, e.g. after OS initializes its virtual memory management component. And paddr (physical address) is only used when the system requires to know the exact physical location in memory, e.g. there is no VM system or VM system should be skipped over. For more information look &lt;a href="http://www.sco.com/developers/gabi/2001-04-24/ch5.pheader.html#segment_contents"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Now let's go back to kickstart and see how it implements the ELF loader. The prototype of ELF loader is declared as:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;blockquote&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;bool&lt;/span&gt; elf_load (&lt;span style="color: rgb(51, 204, 0);"&gt;L4_Word_t&lt;/span&gt; file_start,&lt;br /&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;L4_Word_t&lt;/span&gt; file_end,&lt;br /&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;L4_Word_t&lt;/span&gt; *memory_start,&lt;br /&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;L4_Word_t&lt;/span&gt; *memory_end,&lt;br /&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;L4_Word_t&lt;/span&gt; *entry,&lt;br /&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;L4_Word_t&lt;/span&gt; *type,&lt;br /&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;L4_MemCheck_Func_t&lt;/span&gt; check)&lt;/blockquote&gt;&lt;br /&gt;&lt;/pre&gt;You can find out from this declaration that &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;memory_start&lt;/span&gt;, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;memory_end&lt;/span&gt;, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;entry&lt;/span&gt; and &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;type&lt;/span&gt; are the result of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;elf_load&lt;/span&gt;(...), since pointers are passed into &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;elf_load&lt;/span&gt;(...) and the content of these variables is allowed to be changed. The &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;memory_start&lt;/span&gt; and &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;memory_end&lt;/span&gt; is the final location of binary in the memory, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;entry&lt;/span&gt; is the entry point of this binary and &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;type&lt;/span&gt; will indicate 32-bit or 64-bit format.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;elf_load&lt;/span&gt;(...) checks the identity of current file first and determines the platform type. Then it calls a  subroutine according to type of platform, i.e. 32-bit platform with &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;elf_load32&lt;/span&gt;(...) and 64-bit platform with &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;elf_load64&lt;/span&gt;(...), to actually relocate the binary.  The subroutine checks if the current elf binary executable, i.e. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;type&lt;/span&gt; field of ELF header, is &lt;span style="font-family: trebuchet ms; color: rgb(204, 51, 204);"&gt;2&lt;/span&gt;. Then it finds out the entry point in &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;entry&lt;/span&gt; field of ELF header. It also checks if the program header valid, since without program header the loader doesn't know where to put the different sections in file. At last it loads all loadable parts, according to the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;type&lt;/span&gt; field in program header, of ELF file into the right place in memory. Since in this stage, we don't have any virtual memory system, all operations are handled with physical addresses in program header. In the end of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;elf_loadxx&lt;/span&gt;(...) the &lt;span style="font-style: italic;"&gt;start_addr&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;end_addr&lt;/span&gt; of memory region for binary is calculated and stored.&lt;br /&gt;&lt;br /&gt;I also understand now what &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;root_task_type&lt;/span&gt; means, it is platform information from ELF header, i.e. 32-bit or 64-bit. To read the code of elf loader is really helpful for me :).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-7176977050535963256?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/7176977050535963256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=7176977050535963256' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/7176977050535963256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/7176977050535963256'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/kickstart-kick-kenrel-to-start-5-elf.html' title='Kickstart - kick the kenrel to start (5) - ELF'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-3895210382405835401</id><published>2008-02-05T03:32:00.000-08:00</published><updated>2008-02-12T16:28:36.029-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='kickstart'/><category scheme='http://www.blogger.com/atom/ns#' term='pistachio'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><title type='text'>Kickstart - kick the kenrel to start (4)</title><content type='html'>Today I will continue reviewing the initial routine in kickstart. In last post I introduced the class &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;L4_KernelConfigurationPage_t&lt;/span&gt; which is used by kickstart to install information in &lt;span style="color: rgb(51, 102, 255);"&gt;KIP&lt;/span&gt; region. Now we look back to the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mbi_init&lt;/span&gt;() function. The function starts with finding KIP region with &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;find_kip(...)&lt;/span&gt;, see last post. Then it turns to analyze the multi-boot information (mbi) from boot loader. At first, it checks the command line passed contained in mbi. Inner &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mbi_init&lt;/span&gt;(), three Macros are defined to copy and analyze the command line,&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;- &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;"&gt;COPY_STRING&lt;/span&gt; is used to copy command line string into a preserved cache.&lt;br /&gt;&lt;br /&gt;- &lt;span style="color: rgb(204, 51, 204);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;PARSENUM&lt;/span&gt;&lt;/span&gt; is used to covert string numbers to real number according to the metric, i.e Kilobytes, Megabytes, Gigabytes, and put and print them in a predefined message.&lt;br /&gt;&lt;br /&gt;- &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;"&gt;PARSEBOOL&lt;/span&gt; is a macro to switch on and off some options according to the command line.&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;After finishing parsing the command line comes the most important task of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mbi_init&lt;/span&gt;(), i.e. looking for the modules following kickstart and relocating them. As I mentioned before, the first module following kickstart is L4 micro kernel &lt;span style="color: rgb(51, 51, 255); font-style: italic;"&gt;pistachio&lt;/span&gt;, and then there comes &lt;span style="color: rgb(51, 51, 255); font-style: italic;"&gt;sigma0&lt;/span&gt;, after sigma0 is &lt;span style="font-style: italic; color: rgb(51, 51, 255);"&gt;root_task&lt;/span&gt;. root_task is not included by kernel source tree, it should be provided by L4 user. In the beginning &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;mbi_init&lt;/span&gt;() checks if the flag bit of modules is set in the mbi flags. If so, it will check if the number of current modules are exceed the limit defined by MAX_MBI_MODULES. If exceeds, the additional modules will be dropped, i.e.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;blockquote&gt;mbi-&gt;modcount = &lt;span style="color: rgb(204, 51, 204);"&gt;MAX_MBI_MODULES&lt;/span&gt;;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;According to the number of modules, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mbi_init&lt;/span&gt;() relocates the modules information in new place through copying, i.e.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;// mbi is a global var!&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;orig_mbi_modules[i] = mbi_modules[i] = mbi-&gt;mods[i];&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;//switch the pointer to new location&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;mbi-&gt;mods = mbi_modules;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;To do like this allows kernel to free the memory occupied by boot loader (I guess). Then the command line passed by root_task also replace the original command line stored in mbi, since the original one isn't used by further execution any more. At last, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mbi_init&lt;/span&gt;() uses function &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;load_modules&lt;/span&gt;() to relocate the modules.&lt;br /&gt;&lt;br /&gt;Now let's see the &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;load_modules&lt;/span&gt;() function. In this function it also checks the modules flag for sure. One thing special is it clears entry point in each modules, since, I think, after relocation the entry point will be certainly changed. Another reason, I guess, is that boot loader, e.g. Grub, didn't extract the modules' binary format, it only load them in their original form into memory, so the entry point for each module is useless. The actual work to analyze and relocate modules are handed to &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;elf_load&lt;/span&gt;() function, in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;elf.h&lt;/span&gt; and &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;elf.cc&lt;/span&gt;, through Macro &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;"&gt;LOADIT&lt;/span&gt;. Let's put the elf stuff aside first and continue reading the codes. After the three essential modules are loaded, the other modules followed are also loaded as demand. I also believe, when the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;load_modules&lt;/span&gt;() finishes, each entry of &lt;span style="font-style: italic;"&gt;mbi-&gt;mods[i]&lt;/span&gt; will be filled correctly. Furthermore the &lt;span style="font-style: italic;"&gt;start&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;end&lt;/span&gt; of each module is also modified to fit in new location.&lt;br /&gt;&lt;br /&gt;Now the L4 kernel is relocated, so we need to find KIP region in the new location through &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;find_kip&lt;/span&gt;() again. The kernel now is in its final position, the modified information should be write back into the KIP region. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;install_memory&lt;/span&gt;(), in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mbi-ia32.cc&lt;/span&gt;, will fill the region of memory information through the memory map either stored in mbi or predefined by L4 guys. After the memory map is installed, information about sigma0 and root_task is also installed through fuctions, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;install_sigma0&lt;/span&gt; and &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;install_root_task&lt;/span&gt; introduced in last post. At last, the user level modules, which are loaded besides kernel, sigma0 and root_task, are protected by marking memory occupied by them as &lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;"&gt;L4_BootLoaderSpecificMemoryType&lt;/span&gt;, definded in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;include/l4/kip.h&lt;/span&gt;. In the final stage of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mbi_init&lt;/span&gt;(), a bootinfo section is created if necessary. The section records the original information from boot loader, e.g. where the modules are original placed in the memory. These information could be used by kernel later.&lt;br /&gt;&lt;br /&gt;Finally we reach the end of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mbi_init&lt;/span&gt;(). Here the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;kip_update&lt;/span&gt;() is called, see more about it in last post, and then the entry point of kernel is returned. A question is still not answered when I read the code. What is the root_task_type?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-3895210382405835401?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/3895210382405835401/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=3895210382405835401' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/3895210382405835401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/3895210382405835401'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/kickstart-kick-kenrel-to-start-4.html' title='Kickstart - kick the kenrel to start (4)'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-6816412613443469538</id><published>2008-02-04T07:54:00.000-08:00</published><updated>2008-02-04T10:51:58.420-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='kickstart'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><title type='text'>Kickstart - kick the kenrel to start (3)</title><content type='html'>In this post I will start explaining what initial routine in kickstart does. It is heavier work than last two posts.&lt;br /&gt;&lt;br /&gt;The initial routine in kickstart (for multi-boot loader) is called &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mbi_init&lt;/span&gt; and defined in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mbi-loader.cc&lt;/span&gt;. Before we start digging into this routine, I'd like to introduce a class for managing "&lt;span style="font-style: italic; color: rgb(51, 51, 255);"&gt;kernel interface page&lt;/span&gt;"(&lt;span style="color: rgb(51, 51, 255);"&gt;KIP&lt;/span&gt;) of L4 pistachio micro kernel. The class is named &lt;span style="color: rgb(51, 51, 255); font-style: italic;"&gt;kip_manager_t&lt;/span&gt;, which is declared in &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;kipmgr.h&lt;/span&gt; and implemented in &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;kipmgr.cc&lt;/span&gt;. For figuring out what this class really represents, I'd like to describe some important member functions in this class one by one.&lt;br /&gt;&lt;br /&gt;"&lt;span style="font-weight: bold;font-size:100%;" &gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;bool&lt;/span&gt; find_kip(&lt;span style="color: rgb(51, 204, 0);"&gt;L4_Word_t&lt;/span&gt; kernel_start, &lt;span style="color: rgb(51, 204, 0);"&gt;L4_Word_t&lt;/span&gt; kernel_end)&lt;/span&gt;&lt;/span&gt;"&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;This function is used to find out the KIP&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;/span&gt; region located in micro kernel. In order to achieve this, you need to pass the start address and end address of current location of microkernel, which should be determined by boot loader. This method will iterate all pages from &lt;span style="font-style: italic;"&gt;kernel_start&lt;/span&gt; to &lt;span style="font-style: italic;"&gt;kernel_end&lt;/span&gt; according to the size of L4 configuration page, currently 4K bytes, in order to locate the KIP page. The KIP can be recognized through its magic label "&lt;span style="color: rgb(204, 0, 0);font-family:trebuchet ms;" &gt;L4_MIGIC&lt;/span&gt;" (&lt;span style="color: rgb(51, 51, 255);"&gt;user/include/l4/kcp.h&lt;/span&gt;).  After kickstart finds KIP, it begans preparing the further modification. At first it determines the length of "word" defined by current kernel. This is a metric for kernel to measure the SIZE. Probably it only differs between different architect, e.g. IA-32 and IA-64. The word size on IA-32 may only be 32 bits (I guess). Next step is to retrieve the offset to the region of "memory information" in KIP, since the memory information passed from boot loader need to be filled into this region so that applications upon L4 can use it. If you look into a little for this step you may confused by &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;GET_KIP(MemoryInfo)&lt;/span&gt;. Where does &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;MemoryInfo&lt;/span&gt; come from? After searching the source tree, you should only find a definition of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;MemoryInfo&lt;/span&gt; in class &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;L4_KernelConfigurationPage_t&lt;/span&gt;, which normally cannot be directly used as a separated variable. However, &lt;span style="font-style: italic; color: rgb(204, 51, 204);"&gt;GET_KIP(...) &lt;/span&gt;is not a function but a Macro, which is define as,&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;#define&lt;/span&gt; &lt;span style="color: rgb(204, 51, 204);"&gt;GET_KIP&lt;/span&gt;(&lt;span style="font-style: italic;"&gt;field&lt;/span&gt;) get_value(&lt;span style="color: rgb(204, 51, 204);"&gt;KCP_OFFSET&lt;/span&gt;(&lt;span style="font-style: italic;"&gt;field&lt;/span&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Here, &lt;span style="color: rgb(204, 0, 0);"&gt;get_value(...)&lt;/span&gt; is a protected method in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;kip_manager_t&lt;/span&gt;, and &lt;span style="color: rgb(204, 51, 204); font-style: italic;"&gt;KCP_OFFSET(...)&lt;/span&gt; is another Macro. If you dig deeper in KCP_OFFSET(...), you will find how MemoryInfo is used.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;#define KCP_OFFSET&lt;/span&gt;(field) \&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;(((&lt;span style="color: rgb(51, 204, 0);"&gt;L4_Word_t&lt;/span&gt;) (&amp;amp;((&lt;/span&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;L4_KernelConfigurationPage_t&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt; *) 0)-&gt;field))/\&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;sizeof(&lt;span style="color: rgb(51, 204, 0);"&gt;L4_Word_t&lt;/span&gt;)&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The statement &lt;span style="color: rgb(204, 0, 0);font-family:trebuchet ms;" &gt;(((L4_Word_t) (&amp;amp;((L4_KernelConfigurationPage_t *) 0)-&gt;field))&lt;/span&gt; will give the offset of field in class &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;L4_KernelConfigurationPage_t&lt;/span&gt; in bytes.  And then the division will turn the offset into "word" aligned, since all fields in L4_KernelConfigurationPage_t are word aligned. So actually the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;GET_KIP(MemoryInfo)&lt;/span&gt; will be expanded into&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;blockquote&gt;get_value( (((&lt;span style="color: rgb(51, 204, 0);"&gt;L4_Word_t&lt;/span&gt;) (&amp;amp;((&lt;span style="color: rgb(51, 204, 0);"&gt;L4_KernelConfigurationPage_t&lt;/span&gt; *) 0)-&gt;MemoryInfo)) \&lt;br /&gt;/sizeof(&lt;span style="color: rgb(51, 204, 0);"&gt;L4_word_t&lt;/span&gt;) )&lt;/blockquote&gt;&lt;/span&gt;&lt;/span&gt;Be careful, here we didn't get the final offset of memory information. The effective offset is stored in the high end of the word, i.e 31-16 bit in IA-32. So a shift operation according to the word size is necessary. And then we can finally calculate the address of region of memory information through&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;blockquote&gt;base address of kernel + effective offset&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;For more information, please read &lt;a href="http://l4ka.org/projects/pistachio/l4-x2-r5.pdf"&gt;L4 x2 revision 4 manual&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;"&lt;span style="font-family: trebuchet ms; font-weight: bold;"&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;void&lt;/span&gt; update_bootinfo(&lt;span style="color: rgb(51, 204, 0);"&gt;L4_Word_t&lt;/span&gt; boot_info)&lt;/span&gt;"&lt;br /&gt;&lt;br /&gt;This function will write bootinfo section in KIP with the value passed from boot loader. Another task of this function is to write the count of memory information description in the low-end of MemoryInfo section, i.e 15-0 bit in IA-32.&lt;br /&gt;&lt;br /&gt;"&lt;span style="font-family: trebuchet ms; font-weight: bold;"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;void&lt;/span&gt; install_sigma0(...) &amp;amp; &lt;span style="color: rgb(51, 204, 0);"&gt;void&lt;/span&gt; install_root_task(...)&lt;/span&gt;"&lt;br /&gt;&lt;br /&gt;As I first looked at these two methods, I was confused, since there are no official regions to put the information of sigma0 and root task (not in the L4 manual). Later I notice this is a tricky implementation from L4 guys. There are two header files, i.e. &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;kcp.h&lt;/span&gt; and &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;kip.h&lt;/span&gt;. &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;kcp.h&lt;/span&gt; is used by kickstart to modify the KIP, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;kip.h&lt;/span&gt; is used by user application to access the KIP. After reading the kcp.h, I notice that the scratch place of KIP in manual, say offset 0x10 - 0x40 in IA-32, are used to store the sigma0 and root task information. Why they are need to be stored?? investigate later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-6816412613443469538?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/6816412613443469538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=6816412613443469538' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/6816412613443469538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/6816412613443469538'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/kickstart-kick-kenrel-to-start-3.html' title='Kickstart - kick the kenrel to start (3)'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-2433524258977057117</id><published>2008-02-03T08:57:00.000-08:00</published><updated>2008-02-03T10:25:14.708-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='kickstart'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><title type='text'>Kickstart - kick the kernel to start (2)</title><content type='html'>After the kickstart takes over the control, e.g. setup a mini_stack, retrieve the multi-boot information pointer, a function named "loader" is called, which is defined in file &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;kickstart.cc&lt;/span&gt;. It should never return, because in the end of this function a "&lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;launch_kernel&lt;/span&gt;" function hands the control to the mircokernel. Before this transaction happens, a few things must be done.&lt;br /&gt;&lt;br /&gt;First kickstart checks the current loader format. Although in the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;crt0-ia32.S&lt;/span&gt; codes are dedicated to cooperate with multi-boot specification compatible boot loader, the codes in kickstart.cc are still written to be able to be extended for other loader formats. An array named &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;loader_formats[]&lt;/span&gt;, defined in file &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;ia32.cc&lt;/span&gt;, are used to test the format of current boot loader. Currently it contains only the entry for multi-boot (&lt;span style="color: rgb(51, 51, 255);"&gt;MB&lt;/span&gt;) boot loader. Each entry is a &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;loader_format_t&lt;/span&gt; variable, which has three members - a string to describe the format, a probe function to see if current boot loader matches this format and an initial routine to initialize the information from boot loader. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;loader_format_t&lt;/span&gt; is defined in file &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;kickstart.h&lt;/span&gt;. For the &lt;span style="color: rgb(51, 51, 255);"&gt;MB&lt;/span&gt; format, mbi_probe and mbi_init are used to probe and init the information from boot loader. I will look into three files, &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mbi.cc&lt;/span&gt;, &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;mbi-ia32.cc&lt;/span&gt; and &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;mbi-loader.cc&lt;/span&gt; for more information. Obviously, their names told us they will handle the multi-boot information (&lt;span style="color: rgb(204, 0, 0);"&gt;mbi&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;Let's see first what &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mbi_probe&lt;/span&gt; in &lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;mbi_loader.cc&lt;/span&gt; does. At first it call a static function &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;prepare&lt;/span&gt; of class mbi_t. This function achieve a simple task, checking if the boot_loader is multi-boot compatible and if it is, returning the multi-boot information structure. Recall my last post, there is a variable called &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;grub_mbi_flags&lt;/span&gt;. This variable should contain the magic number of multi-boot format, which is &lt;span style="color: rgb(102, 0, 204);font-family:trebuchet ms;" &gt;0x2BADB002&lt;/span&gt;, if the boot loader is in this format. After the boot loader passes the checking of magic number, the pointer of multi-boot information will be returned and stored in a global variable called &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;mbi_copy&lt;/span&gt;. Then the probe routine finishes.&lt;br /&gt;&lt;br /&gt;Before we go on, it may be better to see what is in the multi-boot information. I don't want to explain too much here, because there is a good manual to explain everything. You can find this manual &lt;a href="http://www.gnu.org/software/grub/manual/multiboot/multiboot.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;After the probe routine, the initial routine comes. It fills the boot information into KIP section in the microkernel binary, then relocates the different modules into their proper location. I will explain it in the next post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-2433524258977057117?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/2433524258977057117/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=2433524258977057117' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/2433524258977057117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/2433524258977057117'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/kickstart-kick-kernel-to-start-2.html' title='Kickstart - kick the kernel to start (2)'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-847649533011269212</id><published>2008-02-02T07:52:00.000-08:00</published><updated>2008-02-02T11:15:14.549-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='kickstart'/><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><title type='text'>Kickstart - kick the kernel to start (1)</title><content type='html'>Kickstart is a tool loaded by "grub" before L4 kernel is going to be loaded. You may think it is a bridge between the world of "grub" and the world of L4. Conceptually kickstart will relocate the modules following it into their correct place, initial the kernel and start the kernel. If you are a student of University Karlsruhe, you can find more information from the website of course "&lt;a href="http://i30www.ira.uka.de/teaching/courses/lecture.php?courseid=153&amp;amp;lid=en"&gt;SDI&lt;/a&gt;". Slide named "L4 crash course 1" explains the duty of kickstart briefly. Here I would like to investigate how kickstart is implemented to fill its responsibility. I will only discuss the source for  32bit x86 (IA-32) machine. By the way, source code of kickstart is located in folder "&lt;span style="font-style: italic; color: rgb(51, 102, 255);"&gt;(l4-top-folder-name)/user/util/kickstart&lt;/span&gt;".&lt;br /&gt;&lt;br /&gt;The kickstart for IA-32 consists of following source files:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-style: italic; color: rgb(204, 0, 0);"&gt;crt0-ia32.S&lt;br /&gt;bootinfo.cc&lt;br /&gt;elf.cc&lt;br /&gt;ia32.cc&lt;br /&gt;kickstart.cc&lt;br /&gt;kipmgr.cc&lt;br /&gt;lib.cc&lt;br /&gt;mbi.cc&lt;br /&gt;mbi-ia32.cc&lt;br /&gt;mbi-loader.cc&lt;/blockquote&gt;&lt;br /&gt;There are some files in order to get the information from boot loader, e.g. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;crt0-ia32.S&lt;/span&gt;. Some are used to relocate the kernel, e.g. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;elf.cc&lt;/span&gt;, the elf loader. And other are used to initial kernel, e.g. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;bootinfo.cc&lt;/span&gt;, which is used to fill the boot information into "&lt;span style="font-style: italic; color: rgb(255, 102, 0);"&gt;kip&lt;/span&gt;" area of kernel. Otherwise, a library for IO will be linked with final binary. I will describe one by one later. In this article, let's see what &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;crt0-ia32.S&lt;/span&gt; does.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0); font-style: italic;"&gt;crt0-ia32.S&lt;/span&gt; contains the codes used to get control from multi-boot bootloader. "Grub" puts multi-boot information descriptor in register file &lt;span style="color: rgb(0, 0, 102); font-style: italic;"&gt;EBX&lt;/span&gt;. Furthermore, a flag for Multi-boot is contained in register &lt;span style="color: rgb(0, 0, 102); font-style: italic;"&gt;EAX&lt;/span&gt;. The following codes fetch these two descriptor and store them in static variable &lt;span style="font-style: italic;"&gt;grub_mbi_ptr&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;grub_mbi_flags&lt;/span&gt;.&lt;br /&gt;&lt;blockquote style="font-style: italic; color: rgb(204, 0, 0);"&gt;&lt;br /&gt;movl %ebx, grub_mbi_ptr&lt;br /&gt;movl %eax, grub_mbi_flags&lt;/blockquote&gt;One note is that, in assembly all undefined symbols, e.g. grub_mbi_* here, will be put into symbol table as external symbols. After these codes, kickstart initial the necessary segments with the value of current data segment for the further execution. The string index register(&lt;span style="color: rgb(0, 0, 153); font-style: italic;"&gt;ESI&lt;/span&gt;) and data seg index register(&lt;span style="color: rgb(0, 0, 153); font-style: italic;"&gt;EDI&lt;/span&gt;) is initialed with the address of &lt;span style="font-style: italic;"&gt;grub_mbi_flags&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;grub_mbi_ptr&lt;/span&gt;. Then the function "&lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;loader&lt;/span&gt;", which is implemented in &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;kickstart.cc&lt;/span&gt;, is called. In the end of &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;crt0-ia32.S&lt;/span&gt;, there is a _mini_stack region, which is also labeled as multi-boot header(&lt;span style="color: rgb(204, 0, 0);"&gt;.mbh&lt;/span&gt;) section. The &lt;span style="color: rgb(204, 0, 0);"&gt;.mbh&lt;/span&gt; region will be put in the start of kickstart binary. After grub loads kickstart, it will check the &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;__mb_header&lt;/span&gt; structure at the begin of kickstart to see if kickstart is a multi-boot kernel. However, after this check these information isn't useful anymore, so this region can be used as mini stack for the further execution. Because it is the first part of .text segment (see. &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;kickstart.ld&lt;/span&gt;),&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="color: rgb(204, 0, 0); font-style: italic;"&gt;.text : {&lt;br /&gt;_kickstart_begin = .;&lt;br /&gt;*(.mbh)&lt;br /&gt;*(.text)&lt;br /&gt;*(.*data*)&lt;br /&gt;_edata = .;&lt;br /&gt;}&lt;/blockquote&gt;a jmp instruction, i.e. "&lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;jmp _start&lt;/span&gt;", must exist in order to jump to the real start of kickstart.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-847649533011269212?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/847649533011269212/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=847649533011269212' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/847649533011269212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/847649533011269212'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/kickstart-kick-kernel-to-start-1.html' title='Kickstart - kick the kernel to start (1)'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-1039958025376938462</id><published>2008-02-01T07:36:00.000-08:00</published><updated>2008-02-01T09:21:12.863-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><category scheme='http://www.blogger.com/atom/ns#' term='bootloader'/><title type='text'>The start of all</title><content type='html'>Although boot loader is not part of L4 project, I still think it is better to know how it works before my deep watching into the microkernel. That might be not necessary at all, since the purpose of separating boot loader from OS development is similar to that of my idea, i.e. simplifying the development and save the effort of developer for constructing boot loading to more important things in other part of OS. However, because of my nature I am interested in everything that is necessary to bring up the machine. So the boot loader cannot escape from my sight. Although there are lots of boot loader projects, "grub" is the most popular general purpose boot loader.&lt;br /&gt;&lt;br /&gt;The whole "grub" project briefly consists of two parts, the installer and the boot loader. The former is used to install the latter into boot sector and locate the next further disk sectors for booting. The boot loader can be divided into three part, stage1, stage1.5 and stage 2. Stage1 is the start of all and resides in the boot sector and thus must be 512 bytes. Stage1.5 is file system specific part. It is optional and not always installed onto disk for booting. Stage2 is final loading stage of "grub" which finds and loads the real OS kernel into memory, changes real mode to protect mode(x86), pass the necessary information to OS kernel and hand off the control. My investigation focused on stage1, which is the smallest part of "grub", since this part is more common for all boot loader and the other two parts are more "grub" specific.&lt;br /&gt;&lt;br /&gt;The current PC boots itself by using BIOS. There is a small piece of codes reside in the BIOS ROM and will be executed when the machine is powered on. And then BIOS will look for bootable device in its hardware list. For simplicity, I only talk about the disk device here. Assuming there is only a bootable hard drive. BIOS checks the first sector (header 0, cylinder 0, sector 1) of the disk and look if it is a legal boot sector, which should end with signature "&lt;span style="color: rgb(204, 0, 0);"&gt;0xaa55&lt;/span&gt;".  By the way, just before this signature there is a 4-entry partition table for hard disk. The code in this boot sector will be loaded into memory started from 0x7c00 and executed in real mode, i.e. no more then 1M bytes segmentation. Since every instruction cannot be dynamically relocated in this stage, the address of "jmp" instruction should be absolutely calculated. That is why grub defines "&lt;span style="color: rgb(204, 0, 0);"&gt;ABS(x)&lt;/span&gt;" macro to help calculate the jmp's destination.&lt;br /&gt;&lt;br /&gt;Stage1's mission is to load the next boot sectors into memory. Obviously in the world stage1 living there are no helper except BIOS (OS are still sleeping on the hard disk). &lt;span style="color: rgb(204, 0, 0);"&gt;Int 0x13&lt;/span&gt; and &lt;span style="color: rgb(204, 0, 0);"&gt;Int 0x10&lt;/span&gt; are the most useful BIOS Interrupt Services for boot loader. Int 0x13 is responsible to read the sectors from disk. You can learn more from &lt;a href="http://www.ctyme.com/intr/int.htm"&gt;Interrupt Jump Table&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;One more thing must be mentioned here is that the generated stage1 binary is not the final binary installed into boot sector. The grub installer manipulates the binary, e.g. filling variables with actual values, eliminating the unnecessary codes before it is coped. One Example is the codes after label &lt;span style="font-style: italic; color: rgb(204, 0, 0);"&gt;boot_drive_check&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic; color: rgb(51, 51, 255);font-size:85%;" &gt;boot_driver_check:&lt;br /&gt;&lt;blockquote&gt;jmp 1f&lt;br /&gt;testb $0x80, %dl&lt;br /&gt;jnz 1f&lt;br /&gt;movb $0x80, %dl&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;"jmp 1f"&lt;/span&gt; must be removed when stage1 is copied into the boot sector of a hard disk, so that the next three instructions can work around some BIOS bogus value. The installer will manually replace this jmp instruction with &lt;span style="color: rgb(204, 0, 0);"&gt;nop (0x90)&lt;/span&gt; instruction.&lt;br /&gt;&lt;br /&gt;Another Example is that installer copies the master partition table of original boot sector into stage1 since it varies on different machines.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-1039958025376938462?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/1039958025376938462/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=1039958025376938462' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/1039958025376938462'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/1039958025376938462'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/02/start-of-all.html' title='The start of all'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-5983134515399563956</id><published>2008-01-31T13:18:00.000-08:00</published><updated>2008-02-01T07:51:08.267-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='L4'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><title type='text'>My way to understand the L4</title><content type='html'>I studied L4 not a long time ago, since I needed to know its internal to pass my final examination. During the preparation I found L4 is interesting, though everything I learned is only the concept. There are few implementation and source code explanations for student to understand how a L4 is really implemented. Especially it lacks of the introduction for the tools along with L4 project, which are mostly also implemented by L4 guys. So, in the next days, I would like to read more source codes and record my understanding about the organization of implementation of L4. If you find my pages occasionally, I beg your understanding for my poor English and some "beginner's" explanations. I will start with listing some essential knowledges, people need to know before starting read the source code.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;- How the binaries or executable files are created..&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;In the beginning I just thought there is a simple and nature answer, "using the compiler". But now I knew the thing is not as simple as I thought. As a system developer you really need to know not only the "gcc -o exename file" stuff, but also how to use the linker option to manipulate the final product. If you develop the things under Linux, reading the manual of LD is very useful for you to understand how the source codes are used for final binary. You can specify the final opcode schema by defining the linker script, usually suffixed with "lds", "ld" or "ldi" ( in L4 Project).&lt;br /&gt;&lt;br /&gt;Furthermore, some binary tools are also useful for developer to manipulate their binaries. For example, if you don't use a boot loader, you must create your own boot loader binary and put it into the boot sector to load your rest kernel. The codes settling in the boot sector must be a raw binary, i.e. no any kind of executable format's meta info. I didn't find a way that can directly create raw binary from a source code. So the way is converting a executable binary into raw binary by using "objcopy". An example is:&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;blockquote&gt;&lt;span style="color: rgb(255, 102, 102);font-size:85%;" &gt;    $ objcopy -O binary elf.exec raw.exec&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;- L4 is using Grub as its default boot loader, although it is not the official boot loader for L4 (you can also use other multi-bootable boot loader, which can load elf format binary).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;S&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-size:85%;"&gt;o you'd better to read the manual on gnu Grub site. It is very helpful for understanding the kickstart stuff, which will get over the job from Grub and load the rest of L4. What is multi-boot header? How a multi-bootable kernel should be organized, e.g. where the mult-boot header should be put in the binary. And how the boot information could be passed to the kernel? These are important in implementing a multi-bootable kernel following the multi-boot specification. I will answer these questions &amp;amp; explain more during the source code review of "kickstart" in L4.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;- How to compile the L4?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;There are two folders in L4 project contains the essential sources to build kernel and booting tools, i.e. "kernel" and "user". "kernel" contain the codes for L4 pistachio kernel. You cannot compile the kernel under its original folder. How to compile it? Try to compile the kernel under its original folder, the error message will tell your all. In the "user" folder contains the source codes for "kickstart" and "sigma0". "kickstart" is used to help load the L4 kernel, "sigma0" is used after kernel initialization and help user to create the root task. To build them, read the "INSTALL" under the "user" folder.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;- How to find out the core of L4?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Although the number of source code lines in L4 is very small, it is necessary to divide the essential source files and the additional source files for special features. To find out the core part of L4 distribution, you can compiling the source and go to the build directory and then look which object files are created. According to these obj files, you can know which source files are really used to create final kernel binary.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-5983134515399563956?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/5983134515399563956/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=5983134515399563956' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/5983134515399563956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/5983134515399563956'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/01/my-way-to-understand-l4.html' title='My way to understand the L4'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-6902161450602959293</id><published>2008-01-29T09:28:00.000-08:00</published><updated>2008-01-29T10:03:14.235-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><title type='text'>The brief architecture of the idea</title><content type='html'>The architecture is similar to some kind of para-virtualization system. It is divided at least three layer vertically. The bottom layer is probably a microkernel. The middle layer is virtualization layer, or I call it "bridge layer", which will uniform the hardware view to the upper layer and also bridge the communication between OS and driver pool. The up layer is the service layer. This layer can be divided into briefly two parts horizontally. One part is "Driver Pools". The middle layer will provide driver writer tools to implement driver to support different hardwares, there would be a way for driver writer to quickly install their driver into driver pool. The other part is OS region. OS developer can develop the system upon a set of "simple virtual hardware devices". OS developer should not concentrate on how the hardware can correctly work, because it should be resolved by driver pool. In contrast, OS developer should do more work how to use more efficiently use the CPU &amp; memory resource, how to let user be more satisfied with OS.&lt;br /&gt;&lt;br /&gt;Why will it be similar to para-virtualization. Since para-virtualization promises the performance and all OS will run in this environment will be dedicated for this environment (maybe not? If we provide full emulation of classic hardware, the OS can also run on bare machine within classic hardware installed. However this pulls down the performance.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-6902161450602959293?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/6902161450602959293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=6902161450602959293' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/6902161450602959293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/6902161450602959293'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2008/01/brief-architecture-of-idea.html' title='The brief architecture of the idea'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-8803848787388284361</id><published>2007-12-25T08:24:00.000-08:00</published><updated>2008-01-29T09:27:53.804-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><title type='text'>Microkernel, Virtuliazation &amp; OS</title><content type='html'>I have an idea at the end of this year to separate the traditional OS model into a more flexible and maybe equal efficient OS model, which will keep in touch with Microkernel, Virtualization techniques. I learned L4 Microkernel during my study in University Karlsruhe. Although the people there announce that this kernel can be faster than ever, it is still not used for most possible commercial OS. Despite the pay off problem for migrate current designate to new microkernel based designate, how to construct a efficient OS upon the microkernel and how complex this work is is also a big problem to stop people use microkernel. The OS complexity comes a lot from the diversity of hardware platform, however virtualization can hide this diversity and simplify the OS design and implementation problem. Otherwise virtualization can let the driver developer avoid the complexity of underlying OS in traditional OS architecture.&lt;br /&gt;&lt;br /&gt;Virtualization is recently used to virtually replicate a physical machine and support convenient commercial OS to achieve the most important purpose, i.e. Server consolidation. People usually still hang on the OS to provide I/O support, memory management support and so on.. So driver guys still need to develop drivers for new hardware in a developing OS environment, where they need to understand the complicated OS environment and to cooperate with OS architecture. On the other hand OS developer also need to think about interfaces provided to the driver developers, which increases the complexity of OS architecture. In this article, I think we can using virtualization more than an emulator but a revolutionist in the OS world. The microkernel idea is very similar to the virtualization, but the multi-servers architecture are much loose coupled, whereas in traditional OS system device services are too tight coupled. Virtualization technique stays in the middle of these two models, it may take the advantages of both and decrease the engineering efforts for both OS developer and hardware driver developer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-8803848787388284361?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/8803848787388284361/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=8803848787388284361' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/8803848787388284361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/8803848787388284361'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2007/12/microkernel-virtuliazation-os.html' title='Microkernel, Virtuliazation &amp; OS'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-4916941722911331546</id><published>2007-09-13T09:58:00.001-07:00</published><updated>2007-09-13T10:07:44.881-07:00</updated><title type='text'>inline function in C++</title><content type='html'>If you want to use inline function with a class, then the function body must be together with class definition. Either you write it inner the class definition together with the function declaration or you put the implementation outside the class, the body should always appear where the class definition appears. Otherwise, you will get a LINK error that tells you that linker cannot find the reference of the function declared with inline. This is quite similar as MACRO, since MACRO are mostly defined in header file. So just remember, using inline function "like" MACRO, i.e. writing it in header file, although they don't work in the same way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-4916941722911331546?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/4916941722911331546/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=4916941722911331546' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/4916941722911331546'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/4916941722911331546'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2007/09/inline-function-in-c.html' title='inline function in C++'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-494789287445348293</id><published>2007-03-02T01:59:00.000-08:00</published><updated>2007-03-02T02:07:10.709-08:00</updated><title type='text'>javax.xml.transform.TransformerException: java.io.FileNotFoundException:</title><content type='html'>I encountered this problem when I try to fix a web application.&lt;br /&gt;&lt;br /&gt;Situation:&lt;br /&gt;&lt;br /&gt;Using Transformer in javax.xml to transform xml file into fo file.&lt;br /&gt;&lt;br /&gt;Original Code:&lt;br /&gt;&lt;br /&gt;transformer.transform(xmlSource, new StreamResult(new File(filePath)));&lt;br /&gt;&lt;br /&gt;Problem:&lt;br /&gt;&lt;br /&gt;"javax.xml.transform.TransformerException: java.io.FileNotFoundException:" happens, although the file path is correct and file really exists.&lt;br /&gt;&lt;br /&gt;Solution:&lt;br /&gt;&lt;br /&gt;Using URI format.&lt;br /&gt;&lt;br /&gt;Code:&lt;br /&gt;&lt;br /&gt;File foFile = new File(filePath);&lt;br /&gt;Result foResult = new StreamResult(foFile.toURI().getPath());&lt;br /&gt;transformer.transform(xmlSource, foResult);&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-494789287445348293?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/494789287445348293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=494789287445348293' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/494789287445348293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/494789287445348293'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2007/03/javaxxmltransformtransformerexception.html' title='javax.xml.transform.TransformerException: java.io.FileNotFoundException:'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-1016634529949966381</id><published>2006-10-31T07:50:00.000-08:00</published><updated>2006-10-31T08:04:25.368-08:00</updated><title type='text'>a small notation for ANTLR ( wrong spelling )</title><content type='html'>Be careful when you use the ANTLR c++ version( I don't know if the problem happens in JAVA version ). You must care about the validation of every TOKEN name by yourself, ANTLR will not warn you, if the TOKEN is not really defined. It will simply create a new empty TOKEN for the undefined TOKEN. For exmaple:&lt;br /&gt;&lt;br /&gt;rule&lt;br /&gt;: SINGLE "hehe" // SINGLE doesn't appeared anywhere except here&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;SINGLE is actually not define in context. But ANTLR doesn't warn you that SINGLE is used but not defined as a parser rule or lexer rule. In constrat, ANTLR will create a new useless TOKEN named "SINGLE". Where is the problem? Think, if you occationally tipp a wrong TOKEN name, e.g. "SINGEL" for "SINGLE", and you don't mention it. After successful compiling, you may get an "unexpected TOKEN" exception. At this moment, you may confuse for a long time, why?, because all your defined rule is in the right way, where comes the exception? Check your word spell, you may find out the reason!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-1016634529949966381?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/1016634529949966381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=1016634529949966381' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/1016634529949966381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/1016634529949966381'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2006/10/small-notation-for-antlr-wrong-spelling.html' title='a small notation for ANTLR ( wrong spelling )'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-5833419720693603599</id><published>2006-10-25T10:11:00.000-07:00</published><updated>2006-10-25T11:14:23.135-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='antlr'/><title type='text'>Where is my AST node?</title><content type='html'>Recently I may find a bug in ANTLR c++ version. If i define a AST node, namely "as", as follow in parser, error message "as is undeclared" appears during the compiling phase:&lt;br /&gt;&lt;br /&gt;rule1&lt;br /&gt;: as:assignOperator COLON id:ID SEMI&lt;br /&gt;{ table-&gt;addFunctionPair(as-&gt;getText(), id-&gt;getText()); } // as not declared? id works well!&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;I read the c++ source file created by anrlt and found that "as" is really not declared as "id". For "id" there are two varibles related with it, "id" and "id_AST", but for "as" there is only one varbile named "as_AST". I don't know why. A bug? So I use "as_AST" instead of "as" in my code. This can work around.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-5833419720693603599?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/5833419720693603599/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=5833419720693603599' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/5833419720693603599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/5833419720693603599'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2006/10/where-is-my-ast-node.html' title='Where is my AST node?'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-7440153871345126520</id><published>2006-10-13T03:14:00.000-07:00</published><updated>2006-10-13T03:37:16.551-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='antlr'/><title type='text'>Add additional literal with with existed literal value</title><content type='html'>we now have literal "const", the corresponding literal value is represented by varible "LITERAL_const". Now problem is that in gcc "__const__" has the same meaning as "const". People can use alternative operator "|" in every place where "const" is required. We can write the codes as following.&lt;br /&gt;&lt;br /&gt;rule1&lt;br /&gt;&amp;nbsp;&amp;nbsp;: ("const"|"__const__") "int" ID&lt;br /&gt;&amp;nbsp;&amp;nbsp;;&lt;br /&gt;&lt;br /&gt;but if "const" is very frequently used, adding alternative operator will become complicated and unefficient. So people usually puts the alternative literal as ANTLRHashString into literals while the Lexer is initialized. With Anltr Java, you can do as follow:&lt;br /&gt;&lt;br /&gt;class SomeLexer extends Lexer;&lt;br /&gt;options&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;//initializing code&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;void initialize() // initializer must be called after the lexer is created.&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;literals.put(new ANTLRHashString("__const__", this),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new Integer(LITERAL_const);&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;In Antlr C++ we don't have ANTLRHashString class, but actually, it is simpler than in Java, because literals is a std:map(or similar) object in Antlr C++, what we need to do is just:&lt;br /&gt;&lt;br /&gt;class SomeLexer extends Lexer;&lt;br /&gt;options&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;//initializing code&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;void initialize()&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;literals["__const__"] = LITERAL_const;&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-7440153871345126520?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/7440153871345126520/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=7440153871345126520' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/7440153871345126520'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/7440153871345126520'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2006/10/add-additional-literal-with-with.html' title='Add additional literal with with existed literal value'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-7693666267579413578</id><published>2006-10-08T15:19:00.001-07:00</published><updated>2006-10-08T15:19:48.496-07:00</updated><title type='text'>I am lazy again, but tired...</title><content type='html'>Ok, i must say, I am lazy again now. I didn't do a lot of thing these days. But why do I feel always very busy? I am always on the way. On the way home, on the way to work, on the way to university and so on. I don't know where my time goes. I hope I can have more time a day, and I hope I can never feel so tired like now...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-7693666267579413578?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/7693666267579413578/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=7693666267579413578' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/7693666267579413578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/7693666267579413578'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2006/10/i-am-lazy-again-but-tired.html' title='I am lazy again, but tired...'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-9089730397462593748</id><published>2006-10-01T09:13:00.000-07:00</published><updated>2006-10-01T09:36:37.682-07:00</updated><title type='text'>Java... knocked me out.</title><content type='html'>It took me 10 hours to find out a "No Attribute is Implemented" Exception when I used "xml security for java" package to encrypt a xml data. The ONLY MISTAKE is just that I added a package, which appears as one of pre-requirement packages in the security package document, into my lib, and it raised a conflict with another package. After I removed  this package, everything went well. Surely I am a freshmeat in the java world, but I have at least five-year C/C++ expierence. And I never encounted a problem in C/C++ world raised by library confiliction. The inconsistance among different packages is the death point of java, I think. I hate to waste so much time just because a conflict of packages. I found out that if you want to avoid this waste your time, it is better to write everything yourself from the basic API provided by java. But sometime this may cost more time... No efficiency, More complex, these are how I feel with my first blick into java world. Much worse is that you may never know what's going wrong with your program, because it is not the duty of your program, but some silly mistakes in evironment setting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-9089730397462593748?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/9089730397462593748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=9089730397462593748' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/9089730397462593748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/9089730397462593748'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2006/10/java-knocked-me-out.html' title='Java... knocked me out.'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-5613748530896175214</id><published>2006-09-19T13:04:00.000-07:00</published><updated>2006-09-19T13:06:08.088-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='antlr'/><title type='text'>"=&gt;": predicator and more</title><content type='html'>On significant advantage in ANTLR is that you can use "=&amp;GT;" in parser to test the non-determinant grama. Look following example,&lt;br /&gt;&lt;br /&gt;rule1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:LCURLY rule3 RCURLY&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br /&gt;&lt;br /&gt;rule2&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:LCRULY LPAREN rule3 RPAREN RCURLY&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br /&gt;&lt;br /&gt;rule3...&lt;br /&gt;&lt;br /&gt;expr:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: rule1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;| rule2&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br /&gt;&lt;br /&gt;Then expr is non-determinant, because rule1 and rule2 both begin with LCRULY. You may increase look ahead varible "k" to solve the problem. But sometimes k is also useless and increases the complexity of parser. So we can use "=&amp;GT;" to predicate the expr. We can write expr as follow:&lt;br /&gt;&lt;br /&gt;expr:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: (rule1) =&gt; rule1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;| rule2&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br /&gt;&lt;br /&gt;ANTLR will try first rule1, if the input stream doesn't match rule1 then it must be rule2. One shortcome of this method is that rule1 will be executed twice. This also increases the complexity and hurts the performance. It is better to use some simple characteristic of different rules instead of whole rule for predication,&lt;br /&gt;&lt;br /&gt;expr:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: (LCURLY LPAREN)=&gt; rule2&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;| rule1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br /&gt;&lt;br /&gt;Changing the order of two rules and using LPAREN make expr-parsing more efficient.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-5613748530896175214?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/5613748530896175214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=5613748530896175214' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/5613748530896175214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/5613748530896175214'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2006/09/tricky-with.html' title='&quot;=&gt;&quot;: predicator and more'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-5815910598088123110</id><published>2006-09-18T10:56:00.000-07:00</published><updated>2006-09-18T11:57:36.370-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MobiNaf C#'/><title type='text'>customized "Delegate" or "EventHandler"?</title><content type='html'>In C# we can define an event handler in an interface. Here is a lesson from me. If you want to transfer your own information into the event handler, you must not use the EventHandler provided by C#.  As described in msdn, "&lt;b&gt;&lt;span style="background-color: rgb(69, 72, 83);"&gt;EventHandler&lt;/span&gt;&lt;/b&gt;  is a predefined delegate that specifically represents an event handler method  for an event that &lt;span style="font-weight: bold;"&gt;does not generate data&lt;/span&gt;." That means you can also not cast the EventArgs in EventHandler to any other class derived from EventArgs. But if EventArgs is used in your customized Delegate, it can be right casted. A Example for better explaination:&lt;br /&gt;&lt;br /&gt;// A customized EventArgs class&lt;br /&gt;public class MyEventArgs:EventArgs&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// A interface that contains a event handler&lt;br /&gt;interface ITest&lt;br /&gt;{&lt;br /&gt;event EventHandler receiverHandler;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class EventTrigger : ITest&lt;br /&gt;{&lt;br /&gt;  public EventHandler MyHanlder;&lt;br /&gt;  private callHandler(MyEventArgs arg)&lt;br /&gt;  {&lt;br /&gt;    MyHandler(this, arg); // down cast from MyEventArgs to EventArgs&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class EventReceiver&lt;br /&gt;{&lt;br /&gt;  public EventReceiver()&lt;br /&gt;  {&lt;br /&gt;    EventTrigger trigger = new EventTrigger();&lt;br /&gt;    trigger.receiverHanlder += new EventHandler(this.receiverHandler);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public receiverHandler(object this, EventArgs arg)&lt;br /&gt;  {&lt;br /&gt;   //Try to up cast arg to MyEventArgs&lt;br /&gt;    MyEventArgs cast_arg = (MyEventArgs)arg; //cast exception happens&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;You see the type casting exception happens because we use the EventHandler in Interface. If we define a customized handler, say MyEventHandler as follow,&lt;br /&gt;&lt;br /&gt;public delegate void MyEventHandler(object this, EventArgs arg);&lt;br /&gt;&lt;br /&gt;and declarate receiverHandler as MyEventHandler, then up casting operation in class EventReceiver will be permitted.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-5815910598088123110?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/5815910598088123110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=5815910598088123110' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/5815910598088123110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/5815910598088123110'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2006/09/customized-delegate-or-eventhandler.html' title='customized &quot;Delegate&quot; or &quot;EventHandler&quot;?'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-4499109019352823943</id><published>2006-09-15T06:05:00.000-07:00</published><updated>2006-09-15T06:26:27.205-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='antlr'/><title type='text'>a small tip on output stream.</title><content type='html'>For long time I suffered from the difficulty to turn on and turn off the output stream in my antlr emitter. Because antlr uses recusive detection, some rules may be called twice or more themselves in order to reach the aim. For Example, I need first get the AST refrence and then operate on it, I  did before as follow:&lt;br /&gt;&lt;br /&gt;expr1:&lt;br /&gt;{ bAuto = false; }// turn off the output, because I only want to get the reference&lt;br /&gt;pr:primaryExpr    // Get it!!&lt;br /&gt;{&lt;br /&gt;   bAuto = true; // after that, turn on the output&lt;br /&gt;  do some operation on pr and then...&lt;br /&gt;  primaryExpr(pr) // now the subrule will print the expression out&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;but Problem is, if primaryExpr can also call expr1 rule, then some additional string will be outputted before the right output. For a expresion a=b(), you may see b()a=b(). Now I use an additional local varible to solve this problem.&lt;br /&gt;&lt;br /&gt;expr1:&lt;br /&gt;{&lt;br /&gt;   bool bOldAuto = bAuto; // save the old setting&lt;br /&gt;  bAuto = false; // turn off the output whatever it is on or off.&lt;br /&gt;}&lt;br /&gt;pr:primaryExpr    // Get it!!&lt;br /&gt;{&lt;br /&gt;   bAuto = bOldAuto; // after that, restore the old setting&lt;br /&gt;  do some operation on pr and then...&lt;br /&gt;  primaryExpr(pr) // now whether the subrule will print&lt;br /&gt;                              // the expression out is dependent on bOldAuto&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This way ensures that only who turn off the ourput can turn on it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-4499109019352823943?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/4499109019352823943/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=4499109019352823943' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/4499109019352823943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/4499109019352823943'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2006/09/small-tip-on-output-stream.html' title='a small tip on output stream.'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-2112939519169733456</id><published>2006-09-03T14:32:00.000-07:00</published><updated>2006-09-03T14:40:12.126-07:00</updated><title type='text'>ifstream problem</title><content type='html'>I use ifstream class to access the user defined option in two different files. Problem is that if I use the same object of ifstream to access these two different files in turn, something went wrong when I access the second file. So I create different object of ifstream for each file, then everything goes well. At first I think people must use different ifstream object to access different file. But when I compile the old files on another machine, the problem happened on my laptop didn't appear. I was confused. I checked gcc version, this may be reason. The gcc version on my laptop is 3.4.6, on the other machine it is 4.1. I hope this is the bug in gcc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-2112939519169733456?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/2112939519169733456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=2112939519169733456' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/2112939519169733456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/2112939519169733456'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2006/09/ifstream-problem.html' title='ifstream problem'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-335881840959624696</id><published>2006-08-30T13:54:00.000-07:00</published><updated>2006-08-30T14:06:12.222-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='antlr'/><title type='text'>with # or without # in Anltr (using c++ antlr lib)</title><content type='html'>In ANTLR you can label your rules with an identifier , for example, lb:expRule. "lb" will represent ASTNode returned by rule "expRule". There are two ways to use "lb", without #, e.g. lb-&gt;getText(),  and with #, e.g. #lb-&gt;getText(). I always think #lb is the same as lb, but actually it is NOT! they represent two ASTNodes that clone the ASTNode returned by rule "expRule". Don't mixed using these two ways, It will confuse you why the changes I made doesn't work.&lt;br /&gt;&lt;br /&gt;A simple example:&lt;br /&gt;&lt;br /&gt;assignExpr: #( ao:NAssignOperator e1:expr { printContent(ao); } e2:expr )&lt;br /&gt;                      {&lt;br /&gt;                              e1-&gt;setText("test1");&lt;br /&gt;                              #e1-&gt;setText("test2");&lt;br /&gt;printf("%s", e1-&gt;getText());         // output: test1&lt;br /&gt;                     }&lt;br /&gt;                    ;&lt;br /&gt;&lt;br /&gt;I don't know whether it is a c++ version characteristic, because I did't use the java version.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-335881840959624696?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/335881840959624696/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=335881840959624696' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/335881840959624696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/335881840959624696'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2006/08/with-or-without-in-anltr-using-c-antlr.html' title='with # or without # in Anltr (using c++ antlr lib)'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-3110774939538001243</id><published>2006-08-30T13:28:00.000-07:00</published><updated>2006-08-30T13:49:40.529-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='antlr'/><title type='text'>Why does g++ not compile my changes with "automake"?</title><content type='html'>After I started to program  under linux, this is always a question symbol in my head. Today I find out the reason. An example for this question:&lt;br /&gt;&lt;br /&gt;I changed a in-place implemented function init() in a head file.  In order to make this changes to work with automake, the old object file that use this function should be deleted.&lt;br /&gt;&lt;br /&gt;So why? I guess the reason is, if you implement a method in the head file, it will only be compiled when a c++ source file use this method and added into the corresponding object file of this source file. If no one uses this method, this part of code may be simply ignored by compiler ( in the situation you use automake to batch the compiling work ) and not added into any output files for optimal reason -- because no one uses it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-3110774939538001243?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/3110774939538001243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=3110774939538001243' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/3110774939538001243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/3110774939538001243'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2006/08/why-does-g-not-compile-my-changes-with.html' title='Why does g++ not compile my changes with &quot;automake&quot;?'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-975103007691482821.post-2698394034593426694</id><published>2006-08-30T11:12:00.001-07:00</published><updated>2006-08-30T11:12:43.255-07:00</updated><title type='text'>A little step in my Life</title><content type='html'>A friend of mine sugguested me to start a technical blog so that I can remember solutions of the encounted problems during my programing life.  I have also thought about it before, but because of lazi.... I didn't start this blog until today. But from this momnet I will try my best to maintain this blog and record one part of my life. At first I will simply list the project I am and was working on.&lt;br /&gt;&lt;br /&gt;Project "pre-virtualization":&lt;br /&gt;&lt;br /&gt;This is a project of virtualization in University Karlsruhe where I am studying now. My master thesis is writing a gramma parser for pre-virtualization technique so that people can use the parser to analyz c source code, find the things they want and replace them as their wish. The major tool I use is ANTLR, a parser genarator.&lt;br /&gt;&lt;br /&gt;Language parsing and ANTLR are both new concept for me. I have struggled with them for about 2 months and at last get some little success. I will write down the expierence during the implementation later in this blog.&lt;br /&gt;&lt;br /&gt;Project "EQSIM":&lt;br /&gt;&lt;br /&gt;Also a project from University Karlsruhe. My job is kind of improving the ability of EQSIM server side application and developing the web interfaces and services for EQSIM project.  I didn't touch web developing before, so it is really a challenge for me. Web technique I used are php and Ajax.&lt;br /&gt;&lt;br /&gt;Project "MobiNaf"&lt;br /&gt;&lt;br /&gt;A mobile e-guider porject from FZK ( Forschungs Zentrum Karlsruhe ). I am responding to the GPS navigation module in this Project. The basic functionalities are implemented. Future work includes testing alarm functionality and integret the module into main project.  I learn a lot about project organization and software design from this project. I am also thinking over whether I promote this module into navigation software. only for fun and more expierences in mobile development.&lt;br /&gt;&lt;br /&gt;Project "SIPPS"&lt;br /&gt;&lt;br /&gt;An old project when I worked in Rapidsulotion Corp. From this project I really understood what is OO programing, how to use Visual Studio. Maybe I will write some usefule things from this project.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/975103007691482821-2698394034593426694?l=markustips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://markustips.blogspot.com/feeds/2698394034593426694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=975103007691482821&amp;postID=2698394034593426694' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/2698394034593426694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/975103007691482821/posts/default/2698394034593426694'/><link rel='alternate' type='text/html' href='http://markustips.blogspot.com/2006/08/little-step-in-my-life_30.html' title='A little step in my Life'/><author><name>Markus</name><uri>http://www.blogger.com/profile/12791311433450303946</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
