<?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-661364275739764944</id><updated>2011-07-07T16:51:17.192-07:00</updated><category term='x61t'/><category term='mini-notebook'/><category term='MID'/><category term='programming'/><category term='tablet'/><category term='softwares'/><category term='cloud'/><category term='N78'/><category term='X'/><category term='gnome'/><category term='Embedded'/><category term='GTK'/><category term='functional language'/><category term='shell'/><category term='Synchronization'/><category term='reading notes'/><category term='Linux'/><category term='debian'/><category term='video'/><category term='touchscreen'/><category term='Writing'/><category term='performance'/><category term='Emacs'/><category term='ereader'/><category term='Linux kernel'/><category term='zaurus'/><category term='OS'/><title type='text'>caritas' space</title><subtitle type='html'>I love programming and free software.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></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-661364275739764944.post-1774353994840092497</id><published>2010-03-29T04:56:00.000-07:00</published><updated>2010-03-29T05:00:07.170-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='X'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>X application startup script with wnck</title><content type='html'>&lt;p&gt;It is common that several X applications are involved for one task. For example, web browser is used for searching and help document, Emacs is used to edit, and X termainal is used for testing. Here, script can be used to startup several X programs with one command typing or click.&lt;/p&gt;&lt;p&gt;But simple shell script can only startup applications. You must arrange the screen layout by hand. In fact the screen layout can be program with script too. Python + &lt;a ref="http://library.gnome.org/devel/libwnck/stable/"&gt;wnck&lt;/a&gt; can be used for that.&lt;/p&gt; &lt;p&gt;The script as follow is an example. It startup pidgin and gnome-terminal, minimize pidgin and maximize gnome-terminal vertically. With wnck, you can arrage the layout of your X applications arbitrarily.&lt;/p&gt;&lt;pre class="example"&gt;#!/usr/bin/python&lt;br /&gt;&lt;br /&gt;import gobject&lt;br /&gt;import gtk&lt;br /&gt;import wnck&lt;br /&gt;import os&lt;br /&gt;import time&lt;br /&gt;&lt;br /&gt;def gtk_wait():&lt;br /&gt;    gobject.idle_add(gtk.main_quit)&lt;br /&gt;    gtk.main()&lt;br /&gt;&lt;br /&gt;def get_wnck_apps_from_wins(wins):&lt;br /&gt;    apps = set()&lt;br /&gt;    for win in wins:&lt;br /&gt;        app = win.get_application()&lt;br /&gt;        apps.add(app)&lt;br /&gt;    return list(apps)&lt;br /&gt;&lt;br /&gt;def screen_get_wnck_apps(s):&lt;br /&gt;    wins = s.get_windows()&lt;br /&gt;    return get_wnck_apps_from_wins(wins)&lt;br /&gt;&lt;br /&gt;def screen_find_windows_by_pid(s, pid):&lt;br /&gt;    wins = []&lt;br /&gt;    all_wins = s.get_windows()&lt;br /&gt;    for win in all_wins:&lt;br /&gt;        app = win.get_application()&lt;br /&gt;        if app.get_pid() == pid:&lt;br /&gt;            wins.append(win)&lt;br /&gt;    return wins&lt;br /&gt;&lt;br /&gt;def gtk_wait_timeout():&lt;br /&gt;    gtk_wait()&lt;br /&gt;    time.sleep(0.1)&lt;br /&gt;&lt;br /&gt;def apply_timeout(func, args, timeout = 10, wait = gtk_wait_timeout):&lt;br /&gt;    start = time.time()&lt;br /&gt;    res = None&lt;br /&gt;    while not res:&lt;br /&gt;        res = apply(func, args)&lt;br /&gt;        now = time.time()&lt;br /&gt;        if now - start &amp;gt; timeout:&lt;br /&gt;            break&lt;br /&gt;        wait()&lt;br /&gt;    return res&lt;br /&gt;&lt;br /&gt;def wait_child_proc():&lt;br /&gt;    try:&lt;br /&gt;        os.waitpid(-1, os.WNOHANG)&lt;br /&gt;    except OSError, err:&lt;br /&gt;        if err.errno == 10: # No child processes&lt;br /&gt;            pass&lt;br /&gt;&lt;br /&gt;def pid_is_valid(pid):&lt;br /&gt;    return os.path.exists('/proc/%d' % (pid,))&lt;br /&gt;&lt;br /&gt;def screen_find_windows_by_pid_timeout(s, pid):&lt;br /&gt;    while True:&lt;br /&gt;        wins = apply_timeout(screen_find_windows_by_pid, (s, pid), 0.5)&lt;br /&gt;        if wins:&lt;br /&gt;            break&lt;br /&gt;        wait_child_proc()&lt;br /&gt;        if not pid_is_valid(pid):&lt;br /&gt;            break&lt;br /&gt;    return wins&lt;br /&gt;&lt;br /&gt;def init():&lt;br /&gt;    global screen&lt;br /&gt;    screen = wnck.screen_get_default()&lt;br /&gt;    gtk_wait()&lt;br /&gt;&lt;br /&gt;class app(object):&lt;br /&gt;    def __init__(self, pid):&lt;br /&gt;        self.pid = pid&lt;br /&gt;        self.update()&lt;br /&gt;    def update(self):&lt;br /&gt;        self.wnck_wins = screen_find_windows_by_pid_timeout(screen, self.pid)&lt;br /&gt;        self.wnck_apps = get_wnck_apps_from_wins(self.wnck_wins)&lt;br /&gt;    def minimize(self):&lt;br /&gt;        for win in self.wnck_wins:&lt;br /&gt;            win.minimize()&lt;br /&gt;    def maximize(self):&lt;br /&gt;        for win in self.wnck_wins:&lt;br /&gt;            wt = win.get_window_type()&lt;br /&gt;            if wt == wnck.WINDOW_NORMAL:&lt;br /&gt;                win.maximize()&lt;br /&gt;    def maximize_vertically(self):&lt;br /&gt;        for win in self.wnck_wins:&lt;br /&gt;            wt = win.get_window_type()&lt;br /&gt;            if wt == wnck.WINDOW_NORMAL:&lt;br /&gt;                win.maximize_vertically()&lt;br /&gt;    def close(self):&lt;br /&gt;        for win in self.wnck_wins:&lt;br /&gt;            win.close(0)&lt;br /&gt;&lt;br /&gt;class app_info(object):&lt;br /&gt;    def __init__(self, start_argv, app_name):&lt;br /&gt;        object.__init__(self)&lt;br /&gt;        self.start_argv = start_argv&lt;br /&gt;        self.app_name = app_name&lt;br /&gt;    def get_instances(self):&lt;br /&gt;        pids = []&lt;br /&gt;        wnck_apps = screen_get_wnck_apps(screen)&lt;br /&gt;        for wnck_app in wnck_apps:&lt;br /&gt;            if wnck_app.get_name() == self.app_name:&lt;br /&gt;                pids.append(wnck_app.get_pid())&lt;br /&gt;        if pids:&lt;br /&gt;            return [app(pid) for pid in pids]&lt;br /&gt;        else:&lt;br /&gt;            return [self.new_instance()]&lt;br /&gt;    def new_instance(self):&lt;br /&gt;        argv = self.start_argv[:]&lt;br /&gt;        argv.insert(0, 'nohup')&lt;br /&gt;        pid = os.spawnvp(os.P_NOWAIT, 'nohup', argv)&lt;br /&gt;        return app(pid)&lt;br /&gt;&lt;br /&gt;def start_apps():&lt;br /&gt;    pidgin_info = app_info(['pidgin'], 'Pidgin')&lt;br /&gt;    terminal_info = app_info(['gnome-terminal'], 'Terminal')&lt;br /&gt;&lt;br /&gt;    os.system('rm -f nohup.out ~/nohup.out')&lt;br /&gt;&lt;br /&gt;    apps = pidgin_info.get_instances()&lt;br /&gt;    apps = pidgin_info.get_instances()&lt;br /&gt;    for app in apps:&lt;br /&gt;        app.close()&lt;br /&gt;&lt;br /&gt;    apps = terminal_info.get_instances()&lt;br /&gt;    for app in apps:&lt;br /&gt;        app.maximize_vertically()&lt;br /&gt;&lt;br /&gt;init()&lt;br /&gt;start_apps()&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-1774353994840092497?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/1774353994840092497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=1774353994840092497' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/1774353994840092497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/1774353994840092497'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2010/03/x-application-startup-script-with-wnck.html' title='X application startup script with wnck'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-9193786528625993853</id><published>2010-03-29T04:50:00.000-07:00</published><updated>2010-03-29T04:55:21.410-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux kernel'/><title type='text'>Disk reading performance with hdparm</title><content type='html'>&lt;p&gt;&lt;a href="http://hdparm.sourceforge.net/"&gt;hdparm&lt;/a&gt; can be used to get disk reading performance with following command line:&lt;/p&gt;  &lt;ul&gt; &lt;li&gt;hdparm -T &amp;lt;dev&amp;gt;. Get cached disk reading performance. In fact, the page cache performance is tested.&lt;/li&gt;  &lt;li&gt;hdparm -t &amp;lt;dev&amp;gt;. Get raw disk reading performance.&lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Implementation&lt;/h4&gt;  &lt;h5&gt;hdparm -T&lt;/h5&gt;  &lt;pre class="example"&gt;ioctl(devfd, BLKFLSBUF, NULL);&lt;br /&gt;read(devfd, buf, READING_SIZE)&lt;br /&gt;do {&lt;br /&gt; seek(devfd, 0, SEEK_SET);&lt;br /&gt; read(devfd, buf, READING_SIZE);&lt;br /&gt;} while (/* time is not over */);&lt;/pre&gt;  &lt;p&gt;Because the data to be read is in page cache always (if READING_SIZE &amp;lt;&amp;lt; memory size), the result is page cache performance.&lt;/p&gt;   &lt;h5&gt;hdparm -t&lt;/h5&gt;  &lt;pre class="example"&gt;ioctl(devfd, BLKFLSBUF, NULL);&lt;br /&gt;do {&lt;br /&gt; read(devfd, buf, READING_SIZE);&lt;br /&gt;} while (/* time is not over */);&lt;/pre&gt;  &lt;p&gt;Because the data to be read is not in page cache, and the bottleneck lies in raw disk reading speed, the result is raw disk reading performance.&lt;/p&gt;  &lt;pre class="example"&gt;reading prepare *         *         *&lt;br /&gt;memory copy          -         -&lt;br /&gt;raw disk read  ++++++++  ++++++++&lt;/pre&gt;  &lt;p&gt;As in above figure, reading reparation and memory copying in testing is neglectable, especially when readahead is considered.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-9193786528625993853?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/9193786528625993853/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=9193786528625993853' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/9193786528625993853'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/9193786528625993853'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2010/03/disk-reading-performance-with-hdparm.html' title='Disk reading performance with hdparm'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-470498567712494649</id><published>2010-03-29T04:46:00.000-07:00</published><updated>2010-03-29T04:50:09.214-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux kernel'/><title type='text'>Reading notes: Linux kernel perf event source</title><content type='html'>&lt;p&gt;For Linux kernel 2.6.33&lt;/p&gt;  &lt;h4&gt;perf event enumeration&lt;/h4&gt;  &lt;p class="first"&gt;Kernel has no hardware perf event enumeration interface.&lt;/p&gt;  &lt;ul&gt; &lt;li&gt;tools command line: perf list&lt;/li&gt;  &lt;li&gt;Available abstract hardware perf events are hard-coded in perf user space tool. Raw hardware perf events are not enumerated by the tool, they can be specified via a 64-bit number in the tool command line. Abstract hardware perf events are implemented with the raw hardware perf events. Whether the abstract hardware perf events are available can be queried via syscall perf_event_open.&lt;/li&gt;  &lt;li&gt;Software trace point are exported in debugfs (/debugfs/tracing/events)&lt;/li&gt; &lt;/ul&gt;   &lt;h4&gt;perf event management&lt;/h4&gt;  &lt;ul&gt; &lt;li&gt;There is at most one perf event context for each task and each CPU. This is used to manage all perf events inside one context (task or CPU).&lt;/li&gt;  &lt;li&gt;All perf events in a context are linked as list in context-&amp;gt;event_list.&lt;/li&gt;  &lt;li&gt;Perf events in one context are organized into groups. All group leaders in a context is linked as list in context-&amp;gt;group_list. All perf events in a group is linked as list in group_leader-&amp;gt;sibling_list.&lt;/li&gt;  &lt;li&gt;It seems that perf events in the group share some attributes, such as enable/disable, cpu, inherit, etc. In &amp;quot;perf record&amp;quot;, for task events, one group is created for perf events for one CPU. In __perf_event_sched_in, it is assumed perf events in one group is for one CPU. But in &amp;quot;perf_record&amp;quot;, group support can not be turned on now, that is, group is not used at all now.&lt;/li&gt;  &lt;li&gt;perf events inherited in child tasks are linked as list in parent_perf_event-&amp;gt;child_list.&lt;/li&gt;  &lt;li&gt;In &amp;quot;perf record&amp;quot;, for task profile, for one perf event type, one perf event is created for each task and each CPU. For perf event operation, it appears that one perf event for each task is sufficient, because one task can only run on one CPU at any time. But perf events may be inherited by children perf events in children tasks (forked tasks). The children perf events use the original perf events for sample output. To make sample ring buffer a per-CPU data structure, perf events are created for each CPU too. So that, when parent and child tasks run on different CPU simultaneously, they all use perf events in parent task for output, but they use different perf events for corresponding CPU.&lt;/li&gt; &lt;/ul&gt;   &lt;h4&gt;perf event state track&lt;/h4&gt;  &lt;ul&gt; &lt;li&gt;task schedule in/out (perf_event_task_sched_in/out). Record/disable counter before schedule out, restore/enable counter after schedule in. The schedule in/out event is recorded too.&lt;/li&gt;  &lt;li&gt;task fork  &lt;ul&gt; &lt;li&gt;perf_event_fork: record fork event.&lt;/li&gt;  &lt;li&gt;perf_event_init_task: perf_event-&amp;gt;attr.inherit control whether to inherit. If inheriting, child perf event will be created for child task. Children events information is accumulated in some statistics. The sample collected via children events are sent to corresponding parent events for same CPU.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;  &lt;li&gt;task exit  &lt;ul&gt; &lt;li&gt;perf_event_exit_task: feed back event values to parent events (child_total_time_running, etc). Free all resources for children events.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;  &lt;li&gt;fd closed, perf_release: free all resources. perf event in original task is managed by corresponding fd. Children perf events in children tasks are freed in perf_event_exit_task.&lt;/li&gt; &lt;/ul&gt;   &lt;h4&gt;Dataflow&lt;/h4&gt;  &lt;p class="first"&gt;For perf event samples:&lt;/p&gt;  &lt;pre class="example"&gt;hardware counter ---&amp;gt; perf event mmap data page -&amp;gt; user space tool (perf)&lt;br /&gt;                  |&lt;br /&gt;soft trace point -/&lt;/pre&gt;  &lt;p&gt;For ftrace and tracing point:&lt;/p&gt;  &lt;pre class="example"&gt; software trace point -&amp;gt; tracing ring buffer -&amp;gt; user space &lt;/pre&gt;   &lt;h4&gt;User space interface&lt;/h4&gt;  &lt;ul&gt; &lt;li&gt;File based interface. File descriptor is obtained via a new syscall perf_event_open. Because one file describptor is needed for each perf event. Perf event may for a specific task, cpu, etc.&lt;/li&gt;  &lt;li&gt;memory map. Sample data is passed from kernel to user space mainly via memory map. Used to implemend shared memory based ring buffer. Details are in ring buffer.&lt;/li&gt;  &lt;li&gt;ring buffer  &lt;ul&gt; &lt;li&gt;Work in both per-CPU and not-per-CPU mode&lt;/li&gt;  &lt;li&gt;write side in kernel, read side in user space. shared memory communication between kernel and user space. It has better performance than memory copy.&lt;/li&gt;  &lt;li&gt;lock-less write side, similar as Steven Rostedt's unified tracing buffer, perf_mmap_data.head is used to reserve space, while perf_mmap_data.user_page-&amp;gt;data_head is used for committed data.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt; &lt;/ul&gt;   &lt;h4&gt;Code generation for software tracing point&lt;/h4&gt;  &lt;ul&gt; &lt;li&gt;A set of macro is defined for software tracing point related code generation, such as binary format description, trace point function generation, etc.&lt;/li&gt;  &lt;li&gt;Some macros are un-defined and re-defined again and again, and some files are included again and again for different set of macro definitions. This is tricky but really powerful. Source code is in include/trace/define_trace.h and include/trace/ftrace.h.&lt;/li&gt; &lt;/ul&gt;   &lt;h4&gt;Tracing and perf event&lt;/h4&gt;  &lt;ul&gt; &lt;li&gt;Lock-less trace ring buffer is not used in perf event, another simple ring buffer implementation for mmap data pages is used instead.&lt;/li&gt;  &lt;li&gt;For software tracing point, the tracing point sample collecting code is shared between tracing and perf event.&lt;/li&gt; &lt;/ul&gt;   &lt;h4&gt;Random thought&lt;/h4&gt;  &lt;ul&gt; &lt;li&gt;ring buffer in perf event has some special features.  &lt;ul&gt; &lt;li&gt;work in both per-CPU and not-per-CPU mode&lt;/li&gt;  &lt;li&gt;shared memory communication between kernel and user space, with write side in kernel and read side in user space.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;  &lt;li&gt;In the code generation for software tracing point  &lt;ul&gt; &lt;li&gt;macro is un-defined and re-defined again and again, and some files are included again and again for different set of macro definitions.&lt;/li&gt; &lt;/ul&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/661364275739764944-470498567712494649?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/470498567712494649/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=470498567712494649' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/470498567712494649'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/470498567712494649'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2010/03/reading-notes-linux-kernel-perf-event.html' title='Reading notes: Linux kernel perf event source'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-4873680640683718863</id><published>2010-03-04T04:56:00.000-08:00</published><updated>2010-03-04T05:10:41.317-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>SWRAP: Session WRAPper</title><content type='html'>&lt;h3&gt;Why we need this?&lt;/h3&gt;  &lt;p class="first"&gt;Even when working on one project, usually multiple software are needed.  For example, in programming, emacs is used to edit source code, one bash is used for testing, another is used for compiling. It is tedious to startup them, open latest file, type latest command etc. screen and session management of the software can be used to facilitate this. Multiple software can be started by screen automatically if you specify them in ~/.screenrc, Latest opened files can be saved by emacs desktop mechanism, latest typed command can be remember by bash history.&lt;/p&gt;  &lt;p&gt;But it is common to work on multiple projects simultaneously. Even if you work on just one project, you may use your computer both for work and leisure. The configuration and saved state for different projects may conflict. For example, two project may use different coding style, so that different emacs configuration are needed. The bash history from one project may flush that from another project. swrap provides a way to manage mutiple configuration and saved state for each software using a simple directory based scheme. A group of software for one project can be managed with a directory hierarchy. While multiple projects are managed with multiple directory hierarchy.&lt;/p&gt;   &lt;h3&gt;Introduction&lt;/h3&gt;  &lt;p class="first"&gt;swrap stands for Session WRAPper, it provides a directory based session management for some software. The session here incude configuration files, saved state files etc. All configuration files, saved state files and other related files for each session are put into one directory. So that you can have multiple configuration, saved state at the same time. For example, you can have multiple bash histories, one for each session. This way, if you work on multiple projects simultaneously, bash history uses in one project will not flush the bash history used in another project.&lt;/p&gt;   &lt;h3&gt;Usage&lt;/h3&gt;  &lt;p class="first"&gt;swrap &amp;lt;command&amp;gt; &amp;lt;session directory&amp;gt; [&amp;lt;arg1&amp;gt; &amp;lt;arg2&amp;gt; ...]&lt;/p&gt;  &lt;p&gt;Where&lt;/p&gt;  &lt;ul&gt; &lt;li&gt;&amp;lt;command&amp;gt; is software that is wrapped.&lt;/li&gt;  &lt;li&gt;&amp;lt;session directory&amp;gt; is the directory to store session related file, which can be an absolute, relative path name or a directory under ~/sessions. The base name of the &amp;lt;session directory&amp;gt; will be used as the session name at least for screen.&lt;/li&gt;  &lt;li&gt;&amp;lt;arg1&amp;gt; &amp;lt;arg2&amp;gt; ... are arguments for &amp;lt;command&amp;gt;.&lt;/li&gt; &lt;/ul&gt;   &lt;h3&gt;Supported software&lt;/h3&gt;  &lt;h4&gt;Bash&lt;/h4&gt;  &lt;h5&gt;Configuration&lt;/h5&gt;  &lt;ul&gt; &lt;li&gt;.bashrc in session directory instead of the global one will be used if provided.&lt;/li&gt; &lt;/ul&gt;   &lt;h5&gt;Saved state&lt;/h5&gt;  &lt;ul&gt; &lt;li&gt;A dedicated .bash_history in session directory will be used instead of the global one.&lt;/li&gt; &lt;/ul&gt;    &lt;h4&gt;Emacs&lt;/h4&gt;  &lt;h5&gt;Configuration&lt;/h5&gt;  &lt;ul&gt; &lt;li&gt;emacs_init.el in session directory will be used as initialization file in addition to the default one.&lt;/li&gt; &lt;/ul&gt;   &lt;h5&gt;Saved state&lt;/h5&gt;  &lt;ul&gt; &lt;li&gt;Emacs desktop is used to save state, and saved state (.emacs.desktop) will be put into session directory instead of emacs startup directory or home directory.&lt;/li&gt; &lt;/ul&gt;    &lt;h4&gt;Screen&lt;/h4&gt;  &lt;h5&gt;Configuration&lt;/h5&gt;  &lt;ul&gt; &lt;li&gt;screenrc in session directory will be used as initialization file instead of default one, but the default one can be loaded in this file if desired.&lt;/li&gt;  &lt;li&gt;screen is used to manage other software, so screen session can be seen as a compound session, while software run inside screen can be seen as sub-sesssion. So it is natural to make session directories for software run inside screen the sub-directories of screen session directory. These sub-directories can be specified as session directories for software run in screen in screenrc.&lt;/li&gt; &lt;/ul&gt;   &lt;h5&gt;Saved state&lt;/h5&gt;  &lt;ul&gt; &lt;li&gt;No saved state is supported&lt;/li&gt; &lt;/ul&gt;     &lt;h3&gt;Example&lt;/h3&gt;  &lt;p class="first"&gt;Directory &amp;quot;example&amp;quot; shows a project session directory hierarchy managed by swrap. There are 3 software in project: screen, emacs and bash. &amp;quot;example&amp;quot; is session directory for screen, &amp;quot;example/screenrc&amp;quot; is screen configuration file. &amp;quot;example/0&amp;quot; is session directory for emacs, which is in window 0 of screen. &amp;quot;example/1&amp;quot; is session directory for bash, which is in window 1 of screen. &amp;quot;example/screenrc&amp;quot; is as follow:&lt;/p&gt;  &lt;pre class="example"&gt;source ~/.screenrc&lt;br /&gt;&lt;br /&gt;chdir ~/projects/mce/apei/firmwarekit/linuxfirmwarekit&lt;br /&gt;screen -t build 1&lt;br /&gt;stuff &amp;quot;exec swrap bash $SESSION_DIR/1&amp;quot;&amp;quot;^M&amp;quot;&lt;br /&gt;stuff &amp;quot;clear&amp;quot;&amp;quot;^M&amp;quot;&lt;br /&gt;&lt;br /&gt;screen -t emacs 0&lt;br /&gt;stuff &amp;quot;swrap emacs $SESSION_DIR/0 --no-window-system&amp;quot;&amp;quot;^M&amp;quot; &lt;/pre&gt;  &lt;p&gt;Where swrap is used to execute software in screen windows, and corresponding session directories are specified too.&lt;/p&gt;  &lt;p&gt;When you execute:&lt;/p&gt;  &lt;pre class="example"&gt;  swrap screen &amp;lt;path to&amp;gt;/example &lt;/pre&gt;  &lt;p&gt;or&lt;/p&gt;  &lt;pre class="example"&gt;  cp -r &amp;lt;path to&amp;gt;/example ~/sessions&lt;br /&gt;  sscreen example &lt;/pre&gt;  &lt;p&gt;You will return to your latest project state or a new project state will be created for you.&lt;/p&gt;   &lt;h3&gt;Download&lt;/h3&gt;  &lt;p class="first"&gt;swrap can be downloaded at &lt;a href="http://linux-mcr700.sourceforge.net/download/swrap_0.1.tar.bz2"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-4873680640683718863?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/4873680640683718863/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=4873680640683718863' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/4873680640683718863'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/4873680640683718863'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2010/03/swrap-session-wrapper.html' title='SWRAP: Session WRAPper'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-6965715827889638919</id><published>2010-03-04T04:52:00.000-08:00</published><updated>2010-03-04T04:55:34.667-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Reading notes: gnome desktop user guide</title><content type='html'>&lt;ul&gt; &lt;li&gt;Overall  &lt;ul&gt; &lt;li&gt;Shift and Alt is often used with mouse to change the default behavior.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;  &lt;li&gt;Keyboard shortcut  &lt;ul&gt; &lt;li&gt;Ctrl+Alt+D: show desktop&lt;/li&gt;  &lt;li&gt;Ctrl+Alt+Tab: switch focus between desktop and panels&lt;/li&gt;  &lt;li&gt;Alt+F9: Minimize window&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;  &lt;li&gt;In Open/Save File Dialog  &lt;ul&gt; &lt;li&gt;Show Hidden Files can be toggle with right click&lt;/li&gt;  &lt;li&gt;Bookmarks can be added/removed&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;  &lt;li&gt;When moving a panel object, alt and shift key can be used to change movement mode (switched, free, push).&lt;/li&gt;  &lt;li&gt;In Nautilus spatial mode, the folder can be opened with parent folder closed with &amp;quot;shift&amp;quot; pressed. I don't like leaving too much folder windows open or closing them by hand when navigating in file hierarchy.&lt;/li&gt;  &lt;li&gt;In Nautilus sptial mode, the browser mode can be entered with right click menu: &amp;quot;Browser Folder&amp;quot; on folder.&lt;/li&gt;  &lt;li&gt;Search can be saved with &amp;quot;File -&amp;gt; Save Search&amp;quot; in Nautilus.&lt;/li&gt;  &lt;li&gt;In Nautilus icon view, items can be sorted with &amp;quot;View -&amp;gt; Arrange Items -&amp;gt; ...&amp;quot;.&lt;/li&gt;  &lt;li&gt;In Nautilus, &amp;quot;glob&amp;quot; can be used to select items with &amp;quot;Edit -&amp;gt; Select Items Matching ...&amp;quot;.&lt;/li&gt;  &lt;li&gt;$HOME/Templates can be used to place arbitrary document templates, which can be used in &amp;quot;Create Document&amp;quot; menu in Nautilus.&lt;/li&gt;  &lt;li&gt;Nautilus sripts are placed in &amp;quot;$HOME/.gnome2/nautilus-scripts&amp;quot;. Some special environment variables are used to passes some infomation.&lt;/li&gt;  &lt;li&gt;Custom keyboard shortcut can be added in &amp;quot;Keyboard Shortcuts&amp;quot; preference dialog directly, need not gconf-editor.&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/661364275739764944-6965715827889638919?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/6965715827889638919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=6965715827889638919' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/6965715827889638919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/6965715827889638919'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2010/03/reading-notes-gnome-desktop-user-guide.html' title='Reading notes: gnome desktop user guide'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-1440482676492564847</id><published>2010-01-30T03:37:00.000-08:00</published><updated>2010-01-30T03:39:01.553-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Writing'/><category scheme='http://www.blogger.com/atom/ns#' term='Emacs'/><title type='text'>Revise muse-index</title><content type='html'>&lt;p&gt;&lt;a href="http://mwolson.org/projects/EmacsMuse.html"&gt;Muse&lt;/a&gt; is a document writing/publishing tool for Emacs.&lt;/p&gt;&lt;p&gt;Muse-index can be used to show all document in a muse project. But now the file name is shown and sorted by it. I think it will be more useful if document title and create or modify time is shown and sorted by create or modify time. So I revise the muse to do that. The code can be found &lt;a href="http://linux-mcr700.sourceforge.net/download/cmuse.el"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-1440482676492564847?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/1440482676492564847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=1440482676492564847' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/1440482676492564847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/1440482676492564847'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2010/01/revise-muse-index.html' title='Revise muse-index'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-4955689710257561746</id><published>2010-01-30T03:32:00.000-08:00</published><updated>2010-01-30T03:36:37.697-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Synchronization'/><category scheme='http://www.blogger.com/atom/ns#' term='N78'/><title type='text'>File Synchronization between N78 and PC</title><content type='html'>&lt;p&gt;My Nokia N78 have no WIFI support and local GPRS/3G data connection fee is quite high, so I can not synchronize large amount of data between N78 and PC with cloud service. I use N78 disk mode USB link to synchronize, details are as follow. Tested in Debian (gnome version 2.28).&lt;/p&gt;  &lt;p&gt;In fact, this is not N78 specific, and can be used to sync files with any devices mountable in Linux.&lt;/p&gt;  &lt;h5&gt;Setup gnome auto-mount VFAT options&lt;/h5&gt;  &lt;p&gt;Traditionally VFAT file system is case insensitive, but can preserve case optionally, on the other hand, Linux native file system is case sensitive. So VFAT should be mounted in case sensitive mode for synchronizing software to work properly.&lt;/p&gt;  &lt;p&gt;Gnome auto-mount VFAT options can be setup as follow:&lt;/p&gt;  &lt;p&gt;Start gconf-editor (System tools -&amp;gt; Configuration editor), check key: /system/storage/default_options/vfat/mount_options, make sure there is &amp;quot;shortname=mixed&amp;quot; instead of something like &amp;quot;shortname=lower&amp;quot; (default value for some distributions) in the value. And &amp;quot;iocharset=utf8&amp;quot; should be set in mount_options too.&lt;/p&gt;   &lt;h5&gt;Setup autorun upon USB connecting&lt;/h5&gt;  &lt;p&gt;In gnome, open nautilus-file-management-properties (System -&amp;gt; Preferences -&amp;gt; File management), select tab named &amp;quot;Media&amp;quot;, for media handling, set &amp;quot;Open Autorun Prompt&amp;quot; for &amp;quot;Software&amp;quot; media. I have thought gnome-volume-manager will be responsible for autorun script execution, but that is turned off in Debian, and autorun mechanism in nautilus is used instead.&lt;/p&gt;  &lt;p&gt;Create a file named &amp;quot;.autorun&amp;quot; in the root directory of the N78 micro-SD card. This is the synchronization script.&lt;/p&gt;   &lt;h5&gt;Unidirectional synchronization via rsync&lt;/h5&gt;  &lt;p&gt;Rsync can be used for unidirectional synchronization, such as backup some directories (photos, notes etc) from N78 to PC or push some directories (music, podcast etc) vice versa.&lt;/p&gt;  &lt;p&gt;One issue here is that VFAT time resolution is not enough for rsync. This can be fixed via specifying &amp;quot;&amp;mdash;modify-window=2&amp;quot; in command line.&lt;/p&gt;   &lt;h5&gt;Bidirectional synchronization&lt;/h5&gt;  &lt;p&gt;It seems that &lt;a href="http://www.cis.upenn.edu/~bcpierce/unison/"&gt;unison&lt;/a&gt; can be used for bidirectional synchronization. But I have not tried it. Unidirectional synchronization is enough for me.&lt;/p&gt;   &lt;h5&gt;My autorun script&lt;/h5&gt;  &lt;p&gt;.autorun in N78&lt;/p&gt;  &lt;pre class="example"&gt;#!/bin/sh&lt;br /&gt;&lt;br /&gt;/usr/local/bin/autorun_sync N78 &lt;/pre&gt;  &lt;p&gt;/usr/local/bin/autorun_sync&lt;/p&gt;  &lt;pre class="example"&gt;#!/bin/sh&lt;br /&gt;&lt;br /&gt;usage()&lt;br /&gt;{&lt;br /&gt; echo &amp;quot;Usage: $prog &amp;lt;media&amp;gt;&amp;quot;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;prog=$(basename $0)&lt;br /&gt;&lt;br /&gt;if [ $# -lt 1 ]; then&lt;br /&gt; usage&lt;br /&gt; echo -n &amp;quot;Press any key to continue:&amp;quot;&lt;br /&gt; read&lt;br /&gt; exit -1&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;media=$1&lt;br /&gt;mdir=/media/$media&lt;br /&gt;&lt;br /&gt;ldir=$HOME/sync/$media&lt;br /&gt;odir=$ldir/data_out&lt;br /&gt;idir=$ldir/data_in&lt;br /&gt;&lt;br /&gt;echo &amp;quot;----------------------------------------------&amp;quot;&lt;br /&gt;echo -n &amp;quot;Rsyncing ...&amp;quot;&lt;br /&gt;rsync -rutv --delete --modify-window=2 $odir/* $mdir/&lt;br /&gt;&lt;br /&gt;if [ -f $ldir/dirs.in ]; then&lt;br /&gt; while read d p; do&lt;br /&gt;  if [ -z &amp;quot;$d&amp;quot; ]; then&lt;br /&gt;   continue;&lt;br /&gt;  fi&lt;br /&gt;  rsync -rutv --modify-window=2 $p $mdir/$d $idir/&lt;br /&gt; done &amp;lt; $ldir/dirs.in&lt;br /&gt;fi&lt;br /&gt;echo &amp;quot;Done!&amp;quot;&lt;br /&gt;echo &amp;quot;----------------------------------------------&amp;quot;&lt;br /&gt;echo -n &amp;quot;Syncing ...&amp;quot;&lt;br /&gt;sync&lt;br /&gt;echo &amp;quot;Done!&amp;quot;&lt;br /&gt;echo &amp;quot;----------------------------------------------&amp;quot;&lt;br /&gt;echo -n &amp;quot;Unmounting ...&amp;quot;&lt;br /&gt;umount /media/$media&lt;br /&gt;echo &amp;quot;Done!&amp;quot;&lt;br /&gt;echo &amp;quot;----------------------------------------------&amp;quot;&lt;br /&gt;echo -n &amp;quot;Done! press any key to close:&amp;quot;&lt;br /&gt;read&lt;/pre&gt;  &lt;p&gt;$HOME/sync/N78/dirs.in&lt;/p&gt;  &lt;pre class="example"&gt;Sounds&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-4955689710257561746?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/4955689710257561746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=4955689710257561746' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/4955689710257561746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/4955689710257561746'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2010/01/file-synchronization-between-n78-and-pc.html' title='File Synchronization between N78 and PC'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-305671908572978544</id><published>2010-01-30T03:29:00.000-08:00</published><updated>2010-01-30T03:31:03.467-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cloud'/><title type='text'>Work with multiple devices</title><content type='html'>&lt;p&gt;One big issue of working with multiple devices is synchronizing necessary information among them. For example, synchronizing the document you are writing between multiple PC (notebook, desktop, netbook, handheld), so that you can write it in any time. Synchronizing the web site you are interested between multiple PC and your phone (has web accessing). So the information need to be synchronized should include:&lt;/p&gt;  &lt;ul&gt; &lt;li&gt;PIM information such as calendar, task and contacts etc.&lt;/li&gt;  &lt;li&gt;Mails&lt;/li&gt;  &lt;li&gt;Files, including the document you are writing and reading. The bookmark information about your reading progress is necessary too, this can be a reading application specific meta-data file.&lt;/li&gt;  &lt;li&gt;Web bookmarks, this can be used for URL you want to read but have no time now.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;One of the most convenient method to synchronize information amongst multiple devices so far is &amp;quot;cloud&amp;quot; based synchronization. One of the biggest advantages of this method is that it needs not turn on and connect two or more machines simultaneously for synchronization. The disadvantage of this method is the possibility to leak your privacy information, so should use encryption for sensitive information.&lt;/p&gt;  &lt;p&gt;I use following cloud services:&lt;/p&gt;  &lt;ul&gt; &lt;li&gt;Google PIM (contacts, calendar, tasks?) for PIM information. On my N78, Google PIM Moblie Sync can be setup as in &lt;a href="http://www.google.com/support/mobile/bin/answer.py?hl=en&amp;amp;answer=147951"&gt;Nokia Setup Instructions for Google Mobile Sync&lt;/a&gt;. Contacts, calendar is supported, but tasks is not supported. On Linux PC, Google PIM Sync can be setup as in &lt;a href="http://www.linux.com/news/software/applications/8226-how-to-sync-evolution-with-googles-pim-apps"&gt;How to sync Evolution with Google's PIM apps&lt;/a&gt;. Contacts, calendar is supported, but tasks is not supported too.&lt;/li&gt;  &lt;li&gt;Google GMail for mails. Google Mobile Sync support pushing mail, but my N78 does not support it. But I don't need that too. On Linux PC, GMail can be accessed with IMAP protocol.&lt;/li&gt;  &lt;li&gt;Dropbox for file synchronization. Dropbox is not opensource software, but UbuntuOne does not work under Debian so far. I may switch to UbuntuOne after it support Debian. Dropbox does not support N78. I use rsync based script to synchronize some data between N78 and my primary PC.&lt;/li&gt;  &lt;li&gt;Google bookmarks for web bookmarks. N78 can access google bookmarks via web browser, but it is not convenient. Firefox GMarks addon works good with Google bookmarks on PC.&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/661364275739764944-305671908572978544?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/305671908572978544/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=305671908572978544' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/305671908572978544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/305671908572978544'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2010/01/work-with-multiple-devices.html' title='Work with multiple devices'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-4335368938301645629</id><published>2010-01-30T03:14:00.000-08:00</published><updated>2010-01-30T03:15:36.223-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mini-notebook'/><title type='text'>Sony VAIO P</title><content type='html'>&lt;p&gt;Working on a Sony VAIO P for two days. Some thoughts are as follow.&lt;/p&gt;  &lt;ul&gt; &lt;li&gt;The screen is very good. The backlight is better than my Lenovo Thinkpad X61T, even readable under sun light. But the viewing angle is much worse than X61T. The resolution is good too. The screen size is OK for most tasks, but sometimes I want a bigger screen.&lt;/li&gt;  &lt;li&gt;It's very thin and light (about 700g?). I can hold it comfortable for hours. So it is very good to be used in holding style. X61T is a little heavy for me to hold (about 1.9kg).&lt;/li&gt;  &lt;li&gt;Keyboard and trackpoint is good, although the keyboard is a little small for my big hand. I think I can get more comfortable with the keyboard size after more usage. But I hate the position of right shift key. Don't know how long will it take for me to fit in with it. I think I will not programming with it.&lt;/li&gt;  &lt;li&gt;Terrible Linux support, mainly the graphics drivers. Why does Intel use such graphic card? Hope 2D open source driver ready soon.&lt;/li&gt;  &lt;li&gt;The CPU of the model I used is only 800MHZ. So the performance is not very good. Not too bad, but not satisfactory too.&lt;/li&gt;  &lt;li&gt;The battery life is too limited, only 2 to 3 hours.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;All in all, I think Sony VAIO P is not the right choice for me. A netbook or CULV notebook with bigger keyboard and screen, longer battery life, better performance and acceptable weight (about 1kg) is better for me.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-4335368938301645629?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/4335368938301645629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=4335368938301645629' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/4335368938301645629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/4335368938301645629'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2010/01/sony-vaio-p.html' title='Sony VAIO P'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-3233029176776150386</id><published>2010-01-30T03:11:00.000-08:00</published><updated>2010-01-30T03:29:02.647-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='softwares'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Linux Softwares for Desktop</title><content type='html'>&lt;h4&gt;Multimedia&lt;/h4&gt;  &lt;h5&gt;EBook management&lt;/h5&gt;  &lt;ul&gt; &lt;li&gt;I need an ebook management software, like rhythmbox for musics or f-spot for photos.&lt;/li&gt; &lt;/ul&gt;   &lt;h5&gt;Photo management&lt;/h5&gt;  &lt;ul&gt; &lt;li&gt;F-spot is an exellent software for photo management. I love it! But it is not very stable, hope it can improve with the time.&lt;/li&gt;  &lt;li&gt;Comix is good for comics, although I seldom use it.&lt;/li&gt; &lt;/ul&gt;   &lt;h5&gt;Music management&lt;/h5&gt;  &lt;ul&gt; &lt;li&gt;I think rhythmbox is good. It seems that MP3 ID3 tags editing changes some internal database instead of file itself.&lt;/li&gt;  &lt;li&gt;For convert the encoding of ID3 tag of MP3 file from GBK to UTF-8, you can use python-mutagen. Command line is: &amp;quot;mid3iconv -e gbk &lt;em&gt;.mp3&amp;quot;.&lt;/li&gt;  &lt;li&gt;To edit ID3 tags of MP3 file, exfalso is good. It seems that easytag is better?&lt;/li&gt; &lt;/ul&gt;   &lt;/em&gt;&lt;h4&gt;Backup&lt;/h4&gt;  &lt;ul&gt; &lt;li&gt;I think backup2l is good for me, because it is very easy to configure.&lt;/li&gt;  &lt;li&gt;I run backup2l in my working machine for periodic backuping, use rsync to synchronize the backup files to my portable backup hard disk.&lt;/li&gt;  &lt;li&gt;rsync is used to backup my N78 phone information. It will be run automatically upon plug via &amp;quot;.autorun&amp;quot; mechanism.&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/661364275739764944-3233029176776150386?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/3233029176776150386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=3233029176776150386' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/3233029176776150386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/3233029176776150386'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2010/01/linux-softwares-for-desktop.html' title='Linux Softwares for Desktop'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-3243110143461155313</id><published>2010-01-30T03:03:00.001-08:00</published><updated>2010-01-30T03:09:15.841-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Synchronization'/><category scheme='http://www.blogger.com/atom/ns#' term='N78'/><title type='text'>Import/sync N78 contacts into/with Evolution</title><content type='html'>&lt;h4&gt;Backup N78 contacts via vcard&lt;/h4&gt;&lt;p class="first"&gt;In address book of N78, contacts can be backupped from phone to memory card via menu. By default the backupped contacts is saved in Others/Contacts directory of micro-SD card. There is one vcard file (.vcf) for one contact.&lt;/p&gt;&lt;h4&gt;Import vcard into Evolution&lt;/h4&gt;&lt;p class="first"&gt;Vcard can be imported into Evolution, but only one vcard file once. To import vcard files generated by N78, the vcard files from N78 can be catenated into one vcard file, then imported into Evolution.&lt;/p&gt;&lt;p&gt;The vcard file generated by N78 is compatible with Evolution, that is, all information can be imported properly so far. But some information is not displayed in Evolution, and not available when accessed via python-evolution (should be not available in other libedata client too). After changing any field then change back to original value and save the &amp;quot;changes&amp;quot;, evething goes OK. Appears a BUG of Evolution, hopes that can be fixed in the future.&lt;/p&gt;&lt;p&gt;Multple contacts in Evolution can exported into one vcard file too. Just select multiple contacts, then click &amp;quot;Save Contact as VCard&amp;quot; in menu, Or save all contacts in one address book with &amp;quot;Save Address Book as VCard&amp;quot;.&lt;/p&gt;&lt;h4&gt;Import vcard into Evolution via python&lt;/h4&gt;&lt;p class="first"&gt;Because of the BUG of Evolution vcard importing, I try python-evolution and python-vobject to import N78 vcards into Evolution.&lt;/p&gt;&lt;p&gt;python-vobject is not completely compatible with the vcard 2.1 version, which is used by N78. This can be fixed with simple python scripting or via importing vcards into Evolution then exporting them because Evolution will export vcard 3.0 version file.&lt;/p&gt;&lt;p&gt;This method works good for me. But I encountered one issue too, the address can not be imported because EContactAddress is not wrapped properly in python-evolution yet. Hope that will be resolved in the future. Fortunately, there is only one not so important contact in my N78 address book has address field set.&lt;/p&gt;&lt;h4&gt;Import vcard into Evolution via opensync&lt;/h4&gt;&lt;pre class="example"&gt;msynctool --addgroup evo2-file&lt;br /&gt;msynctool --addmember evo2-file evo2-sync&lt;br /&gt;msynctool --addmember evo2-file file-sync&lt;br /&gt;msynctool --configure evo2-file 1&lt;br /&gt;#&lt;br /&gt;# You can keep it as default or use the address book URL in &amp;lt;address_path&amp;gt;&lt;br /&gt;#&lt;br /&gt;msynctool --configure evo2-file 2&lt;br /&gt;#&lt;br /&gt;# Set directory hold the vcard files from N78 in &amp;lt;path&amp;gt;&lt;br /&gt;#&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;There is issue for this method too. Some information such as phone number is not displayed in imported Evolution contacts, similar with importing vcard with Evolution itself, and can be fixed in same way too. But situation is much better here, that is, more information can be displayed, at least one phone number for each contact.&lt;/p&gt;&lt;h4&gt;Bidirectional synchronization with Evolution via opensync&lt;/h4&gt;&lt;p class="first"&gt;After testing, I found N78 can be bidirectionally synchronized with Evolution via N78 syncml over USB. But again, there is some issues for method too. Like file-Evolution sync via opensync, some information can not be displayed correctly. But among supported object type, contact has the best support, then calendar and task, but notes must be turned off, or opensync will hang.&lt;/p&gt;&lt;p&gt;Firstly, setup USB device file permission for opensync user space driver. Add following lines into udev rules file or put into a rule file under rules.d directory of udev.&lt;/p&gt;&lt;pre class="example"&gt;BUS==&amp;quot;usb&amp;quot;, SYSFS{idProduct}==&amp;quot;007b&amp;quot;, SYSFS{idVendor}==&amp;quot;0421&amp;quot;, MODE=&amp;quot;660&amp;quot;, GROUP=&amp;quot;plugdev&amp;quot;&lt;/pre&gt;&lt;p&gt;Command line as follow can be used to test the USB link.&lt;/p&gt;&lt;pre class="example"&gt;syncml-obex-client -u&lt;br /&gt;# Found 2 USB OBEX interfaces&lt;br /&gt;# Interface 0:&lt;br /&gt;#         Manufacturer: Nokia&lt;br /&gt;#         Product: N78&lt;br /&gt;#         Interface description: SYNCML-SYNC&lt;br /&gt;# Interface 1:&lt;br /&gt;#         Manufacturer: Nokia&lt;br /&gt;#         Product: N78&lt;br /&gt;#         Interface description: PC Suite Services&lt;br /&gt;syncml-obex-client -u 0 --identifier &amp;quot;PC Suite&amp;quot; --slow-sync text/x-vcard Contacts --wbxml&lt;br /&gt;syncml-obex-client -u 0 --identifier &amp;quot;PC Suite&amp;quot; --slow-sync text/x-vcalendar Calendar --wbxml&lt;br /&gt;syncml-obex-client -u 0 --identifier &amp;quot;PC Suite&amp;quot; --slow-sync text/plain Notes --wbxml&lt;/pre&gt;&lt;p&gt;Command line for setup is as follow.&lt;/p&gt;&lt;pre class="example"&gt;msynctool --addgroup n78-evo2&lt;br /&gt;msynctool --addmember n78-evo2 syncml-obex-client&lt;br /&gt;msynctool --addmember n78-evo2 evo2-sync&lt;br /&gt;msynctool --configure n78-evo2 1&lt;br /&gt;msynctool --configure n78-evo2 2&lt;br /&gt;#&lt;br /&gt;# You can keep it as default or use the address book URL in &amp;lt;address_path&amp;gt;&lt;br /&gt;#&lt;/pre&gt;&lt;p&gt;syncml-obex-client configuration is as follow. The notes database name should be left as empty, because notes synchronization for Evolution is not supported, opensync will hang if you set notes database name.&lt;/p&gt;&lt;pre class="example"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;config&amp;gt;&lt;br /&gt;  &amp;lt;!-- (Only for bluetooth) The bluetooth address if the bluetooth mode is selected --&amp;gt;&lt;br /&gt;  &amp;lt;bluetooth_address&amp;gt;&amp;lt;/bluetooth_address&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- (Only for bluetooth) The bluetooth channel to use. `sdptool browse $MAC` to search for the correct channel --&amp;gt;&lt;br /&gt;  &amp;lt;bluetooth_channel&amp;gt;&amp;lt;/bluetooth_channel&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- (Only for USB) The usb interface number of the SYNCML-SYNC target. use syncml-obex-client -u (you will need access to the USB raw device) to find it. --&amp;gt;&lt;br /&gt;  &amp;lt;interface&amp;gt;0&amp;lt;/interface&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- The string that the plugin will use to identify itself. Some devices need a special string here. --&amp;gt;&lt;br /&gt;  &amp;lt;identifier&amp;gt;PC Suite&amp;lt;/identifier&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- The syncml version to use: 0 for 1.0, 1 for 1.1 and 2 for 1.2 --&amp;gt;&lt;br /&gt;  &amp;lt;version&amp;gt;1&amp;lt;/version&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- if the plugin should use wbxml --&amp;gt;&lt;br /&gt;  &amp;lt;wbxml&amp;gt;1&amp;lt;/wbxml&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- The username to use. Leave empty to not require a username --&amp;gt;&lt;br /&gt;  &amp;lt;username&amp;gt;&amp;lt;/username&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- the password for the username --&amp;gt;&lt;br /&gt;  &amp;lt;password&amp;gt;&amp;lt;/password&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- sets the connection type to use. 5 means obex over usb, 2 means obex over bluetooth --&amp;gt;&lt;br /&gt;  &amp;lt;type&amp;gt;5&amp;lt;/type&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- If wbxml is enabled, defines wether the wbxml should use string tables --&amp;gt;&lt;br /&gt;  &amp;lt;usestringtable&amp;gt;0&amp;lt;/usestringtable&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- Never send ADD command, but send REPLACE (not needed normally) --&amp;gt;&lt;br /&gt;  &amp;lt;onlyreplace&amp;gt;0&amp;lt;/onlyreplace&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- Workaround around for mobile phones which only use local timestamps and _no_ UTC timestamps! --&amp;gt;&lt;br /&gt;  &amp;lt;onlyLocaltime&amp;gt;0&amp;lt;/onlyLocaltime&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- Sets the maximum allowed size in bytes of incoming messages (some device need this option set). Example: 10000 --&amp;gt;&lt;br /&gt;  &amp;lt;recvLimit&amp;gt;0&amp;lt;/recvLimit&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;maxObjSize&amp;gt;0&amp;lt;/maxObjSize&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- The name of the contacts db. Must be the same as the phones sends --&amp;gt;&lt;br /&gt;  &amp;lt;contact_db&amp;gt;Contacts&amp;lt;/contact_db&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- The name of the calendar db. Must be the same as the phones sends --&amp;gt;&lt;br /&gt;  &amp;lt;calendar_db&amp;gt;Calendar&amp;lt;/calendar_db&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- The name of the note db. Must be the same as the phones sends --&amp;gt;&lt;br /&gt;  &amp;lt;note_db&amp;gt;&amp;lt;/note_db&amp;gt;&lt;br /&gt;&amp;lt;/config&amp;gt;&lt;/pre&gt;&lt;h4&gt;Google Mobile Sync&lt;/h4&gt;&lt;p class="first"&gt;The last and the best so far. I use it now. The best features of this method are as follow:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Works good so far, although some information is not displayed inEvolution, similar with other Evolution importing method.&lt;/li&gt;&lt;li&gt;Synchronizing automatically, periodically.&lt;/li&gt;&lt;li&gt;Wireless, Evolution side uses WIFI, and N78 side uses GPRS (because my N78 has no WIFI). Some methods above can be done in wireless way too, such as with bluetooth, with some additional work.&lt;/li&gt;&lt;li&gt;You need not keep both PC and N78 on for synchronization, because you have the third side now, the Google, in other word, the cloud.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;To setup N78 side, you can refer to: &lt;a href="http://www.google.com /support/mobile/bin/answer.py?hl=en&amp;amp;answer=147951"&gt;Nokia Setup Instructions for Google Mobile Sync&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;To setup Evolution side, you can refer to: &lt;a href="http://www.linux.com /news/software/applications/8226-how-to-sync-evolution-with-googles-pim-apps"&gt;How to sync Evolution with Google's PIM apps&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-3243110143461155313?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/3243110143461155313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=3243110143461155313' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/3243110143461155313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/3243110143461155313'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2010/01/importsync-n78-contacts-intowith.html' title='Import/sync N78 contacts into/with Evolution'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-193858153423915433</id><published>2010-01-30T02:12:00.000-08:00</published><updated>2010-01-30T03:00:24.627-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ereader'/><title type='text'>Embolden font for PDF rendering</title><content type='html'>On E-ink devices, PDF seems to be rendered a little light, the readability will improve if it can be rendered a little darker. I found a way to do that, with the "FT_Outline_Embolden", the patch for poppler can be downloaded from &lt;a href="http://linux-mcr700.sourceforge.net/download/poppler-embolden.patch.gz"&gt;here&lt;/a&gt;.&lt;p&gt;Screenshots are as follow:&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_7TGbCpGfOQU/S2QI8vTjWPI/AAAAAAAAASg/f22vUeYkVcc/s1600-h/xixi-025.jpg"&gt;&lt;img src="http://4.bp.blogspot.com/_7TGbCpGfOQU/S2QI8vTjWPI/AAAAAAAAASg/f22vUeYkVcc/s400/xixi-025.jpg" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 425px; height: 550px;" alt="" id="BLOGGER_PHOTO_ID_5432476890099308786" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_7TGbCpGfOQU/S2QKPcKmL2I/AAAAAAAAASw/xNB_dMYn194/s1600-h/xixib-025.jpg"&gt;&lt;img src="http://2.bp.blogspot.com/_7TGbCpGfOQU/S2QKPcKmL2I/AAAAAAAAASw/xNB_dMYn194/s400/xixib-025.jpg" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 425px; height: 550px;" alt="" id="BLOGGER_PHOTO_ID_5432478310890614626" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Hope useful for E-ink PDF viewer or PDF to image converter.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-193858153423915433?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/193858153423915433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=193858153423915433' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/193858153423915433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/193858153423915433'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2010/01/on-e-ink-devices-pdf-seems-to-be.html' title='Embolden font for PDF rendering'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_7TGbCpGfOQU/S2QI8vTjWPI/AAAAAAAAASg/f22vUeYkVcc/s72-c/xixi-025.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-1938135879834629881</id><published>2010-01-30T02:08:00.000-08:00</published><updated>2010-01-30T02:12:48.963-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x61t'/><title type='text'>Cellwriter translucence and docking</title><content type='html'>&lt;p&gt;Cellwriter is my primary on screen virtual keyboard now. But the docking or translucence does not work for me until recently. Now I finally find a way to make it work.&lt;/p&gt;  &lt;h5&gt;Translucence&lt;/h5&gt;  &lt;p&gt;Translucence is not the cellwriter's business in fact. It is done by a composite window manager such as compiz. To configure it in compiz, using compizconfig setting manager:&lt;/p&gt;  &lt;ul&gt; &lt;li&gt;Enable &amp;quot;Regex Matching&amp;quot; under &amp;quot;Utility&amp;quot; section.&lt;/li&gt;  &lt;li&gt;Enable &amp;quot;Opacity, Brightness and Saturation&amp;quot; under &amp;quot;Accessibility&amp;quot; section. Configure this item:  &lt;ul&gt; &lt;li&gt;In &amp;quot;Opacity&amp;quot; tab page, add &amp;quot;Window specific settings&amp;quot;, &amp;quot;class=Cellwriter&amp;quot; for &amp;quot;Windows&amp;quot;, &amp;quot;50&amp;quot; for &amp;quot;Window values&amp;quot;.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt; &lt;/ul&gt;   &lt;h5&gt;Docking&lt;/h5&gt;  &lt;p&gt;Cellwriter has full docking support in fact. But it does not work properly in metacity on x86_64. Seems there is a bug of cellwriter and an issue of metacity of gtk+.&lt;/p&gt;  &lt;ul&gt; &lt;li&gt;Enable &amp;quot;window docking&amp;quot; in cellwriter setup.&lt;/li&gt;  &lt;li&gt;Invoking cellwriter with command line option &amp;quot;&amp;mdash;window-struts&amp;quot;.&lt;/li&gt;  &lt;li&gt;Apply the &lt;a href="http://linux-mcr700.sourceforge.net/download/cellwriter_patches.tar.gz"&gt;patches&lt;/a&gt; to cellwriter (1.3.4).&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;At first, I found _NET_WM_STRUT_PARTIAL has no effect. After comparing the window strut setting of cellwriter and gnome-panel, I found the main difference lies in data type of struts structure passed into XChangeProperty. Cellwriter uses int, while gnome-panel uses gulong. So I try gulong in cellwriter, and it works like a charm!&lt;/p&gt;  &lt;p&gt;Although the format of struts structure passed into XChangeProperty is 32, in &amp;quot;man XChangeProperty&amp;quot;, I found following words:&lt;/p&gt;  &lt;p&gt;&amp;quot;If the specified format is 32, the property data must be a long array.&amp;quot;&lt;/p&gt;  &lt;p&gt;So format 32 should be 64-bit on 64 bit machine in fact, and struts should be long instead of int.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-1938135879834629881?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/1938135879834629881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=1938135879834629881' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/1938135879834629881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/1938135879834629881'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2010/01/cellwriter-translucence-and-docking.html' title='Cellwriter translucence and docking'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-331554710687680517</id><published>2010-01-29T20:07:00.000-08:00</published><updated>2010-01-29T20:11:12.909-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='debian'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Switch network configuration in Debian</title><content type='html'>&lt;p&gt;Home and office have different network configuration, most lies in proxy setup. A simple script as follow is used to switch configuration. Hope it is useful for someone else too.&lt;/p&gt;  &lt;pre class="example"&gt;#!/bin/bash&lt;br /&gt;&lt;br /&gt;prog=$(basename $0)&lt;br /&gt;&lt;br /&gt;usage()&lt;br /&gt;{&lt;br /&gt; echo &amp;quot;Usage: $prog &amp;lt;home|work&amp;gt;&amp;quot;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if [ $# -ne 1 ]; then&lt;br /&gt; usage&lt;br /&gt; exit -1&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;tnet=$1&lt;br /&gt;if [ $tnet != &amp;quot;home&amp;quot; -a $tnet != &amp;quot;work&amp;quot; ]; then&lt;br /&gt; usage&lt;br /&gt; exit -1&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;if [ &amp;quot;$tnet&amp;quot; == &amp;quot;work&amp;quot; ]; then&lt;br /&gt; sudo cp /etc/apt/apt.conf.avail/99proxy /etc/apt/apt.conf.d&lt;br /&gt; gconftool-2 -s -t string /system/proxy/mode auto&lt;br /&gt;else&lt;br /&gt; sudo rm -f /etc/apt/apt.conf.d/99proxy&lt;br /&gt; gconftool-2 -s -t string /system/proxy/mode none&lt;br /&gt;fi&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-331554710687680517?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/331554710687680517/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=331554710687680517' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/331554710687680517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/331554710687680517'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2010/01/switch-network-configuration-in-debian.html' title='Switch network configuration in Debian'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-2037976764059530750</id><published>2010-01-29T20:05:00.000-08:00</published><updated>2010-01-29T20:07:30.953-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Gnome notify in command line</title><content type='html'>&lt;p&gt;Method is copied from somebody's blog, can't remember who.&lt;/p&gt;&lt;pre class="example"&gt;#!/usr/bin/python&lt;br /&gt;&lt;br /&gt;import pynotify&lt;br /&gt;import sys&lt;br /&gt;&lt;br /&gt;def notify(title=&amp;quot;Notify&amp;quot;, message=&amp;quot;&amp;quot;):&lt;br /&gt;    n = pynotify.Notification(title, message)&lt;br /&gt;    n.show()&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;if __name__ == '__main__':&lt;br /&gt;    pynotify.init(&amp;quot;cli notify&amp;quot;)&lt;br /&gt;    if len(sys.argv) &amp;gt; 1:&lt;br /&gt;        title = sys.argv[1]&lt;br /&gt;        msg = &amp;quot; &amp;quot;.join(sys.argv[2:])&lt;br /&gt;        notify(title, msg)&lt;br /&gt;    else:&lt;br /&gt;        notify()&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-2037976764059530750?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/2037976764059530750/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=2037976764059530750' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/2037976764059530750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/2037976764059530750'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2010/01/gnome-notify-in-command-line.html' title='Gnome notify in command line'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-4228818050585183764</id><published>2010-01-29T20:04:00.000-08:00</published><updated>2010-01-29T20:04:42.558-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='debian'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Switch distribution version in Debian</title><content type='html'>&lt;p&gt;Use testing version of Debian as my primary working environment. But some softwares are available only in sid version, and bugs are fixed in sid firstly. So switching between testing and sid is routine. A simple script as follow is used to simplify/accelerate the operation.&lt;/p&gt;  &lt;pre class="example"&gt;#!/bin/sh&lt;br /&gt;&lt;br /&gt;prog=$(basename $0)&lt;br /&gt;&lt;br /&gt;usage()&lt;br /&gt;{&lt;br /&gt;        echo &amp;quot;Usage: $prog &amp;lt;testing|sid&amp;gt;&amp;quot;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;current_dist()&lt;br /&gt;{&lt;br /&gt;        if grep sid /etc/apt/sources.list &amp;gt; /dev/null; then&lt;br /&gt;                echo sid&lt;br /&gt;        else&lt;br /&gt;                echo testing&lt;br /&gt;        fi&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if [ $# -ne 1 ]; then&lt;br /&gt;        usage&lt;br /&gt;        exit -1&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;tdist=$1&lt;br /&gt;if [ $tdist != &amp;quot;sid&amp;quot; -a $tdist != &amp;quot;testing&amp;quot; ]; then&lt;br /&gt;        usage&lt;br /&gt;        exit -1&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;cdist=$(current_dist)&lt;br /&gt;if [ &amp;quot;$tdist&amp;quot; != &amp;quot;$cdist&amp;quot; ]; then&lt;br /&gt;        cp /etc/apt/sources.list.$tdist /etc/apt/sources.list&lt;br /&gt;        mv /var/lib/apt/lists /var/lib/apt/lists.$cdist&lt;br /&gt;        if [ -d /var/lib/apt/lists.$tdist ]; then&lt;br /&gt;                mv /var/lib/apt/lists.$tdist /var/lib/apt/lists&lt;br /&gt;        fi&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;apt-get update&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-4228818050585183764?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/4228818050585183764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=4228818050585183764' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/4228818050585183764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/4228818050585183764'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2010/01/switch-distribution-version-in-debian.html' title='Switch distribution version in Debian'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-7574570858085269976</id><published>2009-06-23T06:04:00.000-07:00</published><updated>2009-06-23T06:07:56.655-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Debug bash function interactively</title><content type='html'>&lt;pre class="example"&gt;&lt;br /&gt;#!/bin/bash&lt;br /&gt;&lt;br /&gt;# processing command line parameters&lt;br /&gt;if [ $# -eq 2 ]; then&lt;br /&gt;    p1=$1&lt;br /&gt;    p2=$2&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;# setup some environment&lt;br /&gt;export A=a&lt;br /&gt;export B=b&lt;br /&gt;&lt;br /&gt;tmpfile=/tmp/myshell-$$-$RANDOM&lt;br /&gt;&lt;br /&gt;trap &amp;quot;rm $tmpfile&amp;quot; EXIT&lt;br /&gt;&lt;br /&gt;cat &amp;lt;&amp;lt;EOF &amp;gt; $tmpfile&lt;br /&gt;if [ -f /etc/bash.bashrc ]; then&lt;br /&gt;    source /etc/bash.bashrc&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;if [ -f $HOME/.bashrc ]; then&lt;br /&gt;    source $HOME/.bashrc&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;source &amp;lt;shell functions in this file&amp;gt;&lt;br /&gt;&lt;br /&gt;export PS1=&amp;quot;My Shell$ &amp;quot;&lt;br /&gt;EOF&lt;br /&gt;&lt;br /&gt;/bin/bash --rcfile $tmpfile&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-7574570858085269976?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/7574570858085269976/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=7574570858085269976' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/7574570858085269976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/7574570858085269976'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/debug-bash-function-interactively.html' title='Debug bash function interactively'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-1879908572143282031</id><published>2009-06-23T06:01:00.000-07:00</published><updated>2009-06-23T06:03:32.091-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Shell script parameters - a simpler way</title><content type='html'>&lt;pre class="example"&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;&lt;br /&gt;for param in &amp;quot;$@&amp;quot;; do&lt;br /&gt;    eval &amp;quot;$param&amp;quot;&lt;br /&gt;done&lt;br /&gt;&lt;br /&gt;param1=${param1:-param1}&lt;br /&gt;param2=${param2:-param2}&lt;br /&gt;param3=${param3:-param3}&lt;br /&gt;&lt;br /&gt;echo $param1 $param2 $param3&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Usage:&lt;/p&gt;&lt;pre class="example"&gt;&lt;br /&gt;param.sh param1=&amp;lt;param1&amp;gt; param2=&amp;lt;param2&amp;gt; param3=&amp;lt;param3&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-1879908572143282031?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/1879908572143282031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=1879908572143282031' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/1879908572143282031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/1879908572143282031'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/shell-script-parameters-simpler-way.html' title='Shell script parameters - a simpler way'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-5936121040814671533</id><published>2009-06-19T06:45:00.000-07:00</published><updated>2009-06-19T18:32:45.715-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>GNOME desktop layout for small screen</title><content type='html'>&lt;p&gt;Default GNOME desktop layout is for typical workstation screen (&amp;gt; XGA). For smaller screen such as netbook (typically 1024x600), too much vertical space is been occupied by two desktop panel and window title bar. This is worse for wide screen, which has relatively small vertical space.&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_7TGbCpGfOQU/SjuYRgNXF5I/AAAAAAAAAP0/Fcb-q2w9Trg/s1600-h/before.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 300px;" src="http://3.bp.blogspot.com/_7TGbCpGfOQU/SjuYRgNXF5I/AAAAAAAAAP0/Fcb-q2w9Trg/s400/before.png" alt="" id="BLOGGER_PHOTO_ID_5349036408903767954" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;center&gt;Desktop screenshot before optimizing&lt;/center&gt;&lt;/p&gt;&lt;p&gt;To optimize vertical space utility, the following method can be used:&lt;/p&gt;  &lt;ul&gt; &lt;li&gt;Remove bottom panel (or top panel)&lt;/li&gt;  &lt;li&gt;Replace expanded menubar in panel with collapsed one.&lt;/li&gt;  &lt;li&gt;Compile and install window-picker-applet, which provides a compact task icon list and focus task title.  &lt;p&gt;It can downloaded from &lt;a href="https://code.launchpad.net/window-picker-applet/+download"&gt;here&lt;/a&gt;. I write a small patch to add window maximizing toggling support to it, which can be downloaded from &lt;a href="http://linux-mcr700.sourceforge.net/download/wpa_toggle_max.patch"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;Remove window title bar for maximized window. For metacity this can be done via theme customization, that is, change the "frame_geometry" with name "normal_maximized" as follow:&lt;/li&gt; &lt;/ul&gt;  &lt;pre class="example"&gt; &amp;lt;frame_geometry name="normal_maximized" parent="normal"  rounded_top_left="false"&lt;br /&gt;rounded_top_right="false"  rounded_bottom_left="false" rounded_bottom_right="false"  has_title="false"&amp;gt;&lt;br /&gt; &amp;lt;!-- strip frame spacing off the normal geometry when maximized --&amp;gt;&lt;br /&gt; &amp;lt;distance name="left_width" value="0"/&amp;gt;&lt;br /&gt; &amp;lt;distance name="right_width" value="0"/&amp;gt;&lt;br /&gt; &amp;lt;distance name="bottom_height" value="0"/&amp;gt;&lt;br /&gt; &amp;lt;distance name="left_titlebar_edge" value="0"/&amp;gt;&lt;br /&gt; &amp;lt;distance name="right_titlebar_edge" value="0"/&amp;gt;&lt;br /&gt; &amp;lt;distance name="title_vertical_pad" value="0"/&amp;gt;&lt;br /&gt; &amp;lt;border name="title_border" left="0" right="0" top="0" bottom="0"/&amp;gt;&lt;br /&gt;&amp;lt;/frame_geometry&amp;gt; &lt;/pre&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_7TGbCpGfOQU/SjuYcT0Y-3I/AAAAAAAAAP8/KpXL_-VDLhk/s1600-h/after.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 300px;" src="http://3.bp.blogspot.com/_7TGbCpGfOQU/SjuYcT0Y-3I/AAAAAAAAAP8/KpXL_-VDLhk/s400/after.png" alt="" id="BLOGGER_PHOTO_ID_5349036594556369778" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;center&gt;Desktop screenshot after optimizing&lt;/center&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-5936121040814671533?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/5936121040814671533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=5936121040814671533' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/5936121040814671533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/5936121040814671533'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/gnome-desktop-layout-for-small-screen.html' title='GNOME desktop layout for small screen'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_7TGbCpGfOQU/SjuYRgNXF5I/AAAAAAAAAP0/Fcb-q2w9Trg/s72-c/before.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-2478473613749228062</id><published>2009-06-13T20:44:00.001-07:00</published><updated>2009-06-13T20:49:31.244-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='reading notes'/><title type='text'>Reading notes: optimizing Linux performance</title><content type='html'>&lt;h4&gt;Chapter 3&lt;/h4&gt;  &lt;ol&gt; &lt;li&gt;vmstat can show swap in/out pages. A simultaneously high swap-in and swap-out rate could indicate that the system does not have enough memory to handle all the running processes.&lt;/li&gt;  &lt;li&gt;slabtop is "top" for slab.&lt;/li&gt; &lt;/ol&gt;   &lt;h4&gt;Chapter 4&lt;/h4&gt;  &lt;ol&gt; &lt;li&gt;strace can show system call performance statistics too (strace -c).&lt;/li&gt;  &lt;li&gt;ltrace: performance statistics for library (like strace, but library function instead of system call).&lt;/li&gt;  &lt;li&gt;ld.so: dynamic load/link statistics for libraries. Example: &lt;code&gt;env LD_DEBUG=statistics LD_DEBUG_OUTPUT=lddebug gcalctool&lt;/code&gt;&lt;/li&gt; &lt;/ol&gt;   &lt;h4&gt;Chapter 6&lt;/h4&gt;  &lt;ol&gt; &lt;li&gt;iostate: show disk IO statistics&lt;/li&gt; &lt;/ol&gt;   &lt;h4&gt;Chapter 7&lt;/h4&gt;  &lt;ol&gt; &lt;li&gt;netstat -c: period update&lt;/li&gt;  &lt;li&gt;netstat -t: choose tcp protocol&lt;/li&gt;  &lt;li&gt;netstat -l, -a: listening sockets or listening + conntected.&lt;/li&gt; &lt;/ol&gt;   &lt;h4&gt;Chapter 8&lt;/h4&gt;  &lt;ol&gt; &lt;li&gt;script: record what you have done and the output, seems useful.&lt;/li&gt;  &lt;li&gt;gcc -g3: provide more debug information then gcc -g (default to  &lt;ul&gt; &lt;li&gt;g2), such as the macro definitions present in the source.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt; &lt;/ol&gt;   &lt;h4&gt;Chapter 11&lt;/h4&gt;  &lt;ol&gt; &lt;li&gt;Use gdb to check call chain:  &lt;ul&gt; &lt;li&gt;Set a breakpoint at check-point&lt;/li&gt;  &lt;li&gt;gdb can execute a given set of commands when it hits a breakpoint. By using the command command, we can tell gdb to execute bt; cont every time it hits the breakpoint.&lt;/li&gt;  &lt;li&gt;Conditional breakpoint can be implemented via gdb script (commands) too. For example, we can enable breakpoint 2, when we reach breakpoint 1.&lt;/li&gt;  &lt;li&gt;gdb output can be logged to a text file via: set logging on&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;  &lt;li&gt;oprofile reveals which function is hot, but do not show how many times it is called. ltrace or some other traces shows which function (including subfunctions) consumes most CPU time. This is from two perspective, and they can be combined to inspect the performance property.&lt;/li&gt;  &lt;li&gt;For Fedora and Enterprise Linux, Red Hat provides a set of debuginfo rpms that contain all the symbol information and sources that were generated by the compiler when the application was complied. Each binary package or library has a corresponding debuginfo rpm that contains the debugging information. This allows Red Hat to ship the binaries without the disk-space–consuming debugging information. However, it allows developers, or those investigating performance problems, to download the appropriate debuginfo packages and use them. In this case, Red Hat's version of oprofile will also recognize the debuginfo packages and pick up the symbols when profiling both an application, such a nautilus, and a library, such as gtk.  &lt;ul&gt; &lt;li&gt;Debian has similar binary debug symbol packages: -dbg&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt; &lt;/ol&gt;   &lt;h4&gt;Chapter 12&lt;/h4&gt;  &lt;ol&gt; &lt;li&gt;strace to find bottleneck of IO intensive application.  &lt;ul&gt; &lt;li&gt;Oprofile can be used only for CPU intensive application. Because IO is performed in kernel space, strace is the right tool to reveal which kind of IO application is performing.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt; &lt;/ol&gt;   &lt;h4&gt;Chapter 13&lt;/h4&gt;  &lt;ol&gt; &lt;li&gt;This call-tree tool would be useful even if it dramatically slowed down application performance as it runs. A common way of using this would be to run oprofile to figure out which functions in an application are "hot," and then run the call-tree program to figure out why the application called them.&lt;/li&gt; &lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-2478473613749228062?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/2478473613749228062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=2478473613749228062' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/2478473613749228062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/2478473613749228062'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/reading-notes-optimizing-linux.html' title='Reading notes: optimizing Linux performance'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-9167996842094525665</id><published>2009-06-13T20:42:00.000-07:00</published><updated>2009-06-13T20:49:00.266-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux kernel'/><category scheme='http://www.blogger.com/atom/ns#' term='reading notes'/><title type='text'>Reading notes of internals of the RT patch</title><content type='html'>&lt;ol&gt; &lt;li&gt;Real-time is something about predictability instead of performance, throughput or latency. That is, real-time system may have worse average throughput or latency, but it will have better largest latency or lowest throughput. Linux kernel have great average performance but the worst one is not so good.&lt;/li&gt;  &lt;li&gt;The drawback of Robert Love's kernel preemption patch is: A high priority process must still wait on a lower priority process while it is in a critical section, even if that same high priority process did not need to access that section.&lt;/li&gt;  &lt;li&gt;The RT patch is all about determinism and being able to have full control of the kernel. But, like being root, the more power you give the user the more likely they will destroy themselves with it. Such as, a user process can have higher priority than IRQ handler, if the process holding the CPU, system will hang.&lt;/li&gt; &lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-9167996842094525665?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/9167996842094525665/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=9167996842094525665' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/9167996842094525665'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/9167996842094525665'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/reading-notes-of-internals-of-rt-patch.html' title='Reading notes of internals of the RT patch'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-8713669675257198229</id><published>2009-06-13T20:41:00.001-07:00</published><updated>2009-06-13T20:41:38.591-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux kernel'/><title type='text'>Why NMI is not used widely in Linux kernel</title><content type='html'>&lt;p&gt;&amp;quot;There are some systems where NMIs are broken (e.g. a lot of ThinkPads explode when they get NMI inside SMI). This was one of the reasons the NMI watchdog is not enabled by default anymore.&amp;quot; From Andi Kleen.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-8713669675257198229?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/8713669675257198229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=8713669675257198229' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/8713669675257198229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/8713669675257198229'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/why-nmi-is-not-used-widely-in-linux.html' title='Why NMI is not used widely in Linux kernel'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-4119031049055398073</id><published>2009-06-13T20:39:00.000-07:00</published><updated>2009-06-13T20:40:51.838-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux kernel'/><title type='text'>force_sig_info</title><content type='html'>&lt;p&gt;Behavior of force_sig_info&lt;/p&gt;  &lt;ul&gt; &lt;li&gt;If SIGXXX is blocked or ignored: unblock SIGXXX, reset action to SIG_DFL&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Force_sig_info in some special environment&lt;/p&gt;  &lt;ul&gt; &lt;li&gt;kvm_arch_vcpu_ioctl_run(), SIGXXX is blocked  &lt;ul&gt; &lt;li&gt;SIGXXX is unblocked, but before returning from kernel:kvm_arch_vcpu_ioctl_run(), it is blocked again (restore host signal mask).&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;  &lt;li&gt;In sys_rt_sigtimedwait(), SIGXXX is blocked  &lt;ul&gt; &lt;li&gt;SIGXXX is unblocked, but before returning from sys_rt_sigtimedwait(), it is blocked again (restore to original signal mask).&lt;/li&gt; &lt;/ul&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/661364275739764944-4119031049055398073?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/4119031049055398073/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=4119031049055398073' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/4119031049055398073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/4119031049055398073'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/forcesiginfo.html' title='force_sig_info'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-618261282083943745</id><published>2009-06-13T20:38:00.000-07:00</published><updated>2009-06-13T20:39:00.980-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux kernel'/><title type='text'>Fast boot</title><content type='html'>&lt;p&gt;How to make Linux boot faster?&lt;/p&gt;  &lt;ol&gt; &lt;li&gt;Keep CPU and disk I/O usage rate to or near 100%, that is, take full advantage of CPU speed and disk I/O throughput.&lt;/li&gt;  &lt;li&gt;Reduce works needed in boot.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Previous, I think the method 2 is more important, such as substituting boot with resuming from hibernation. But I think Moblin team achieve a great result with mainly method 1.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-618261282083943745?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/618261282083943745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=618261282083943745' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/618261282083943745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/618261282083943745'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/fast-boot.html' title='Fast boot'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-1357703223517610394</id><published>2009-06-13T20:37:00.000-07:00</published><updated>2009-06-13T20:38:15.325-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux kernel'/><title type='text'>Audio and real-time</title><content type='html'>&lt;p&gt;Only audio playback and audio recording do not need much real-time capability of system. Because you can just need to prepare a buffer big enough until next refill (or re-consume).&lt;/p&gt;  &lt;p&gt;The real real-time demanding work is something like VOIP, a small buffer should be used to keep speak-to-hear lag low.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-1357703223517610394?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/1357703223517610394/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=1357703223517610394' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/1357703223517610394'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/1357703223517610394'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/audio-and-real-time.html' title='Audio and real-time'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-6283512889153158244</id><published>2009-06-13T20:36:00.001-07:00</published><updated>2009-06-13T20:36:47.904-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='zaurus'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>SNES9x for Zaurus Akita with rotate</title><content type='html'>&lt;p&gt;The resolution of zaurus akita is 480x640 (or 240x320) instead of 640x480 (or 320x240). While SNES9x uses resolution 640x480 or 320x240, so rotation should be implemented in some layer of the graphic stack. The possible graphic stacks are:&lt;/p&gt;  &lt;ol&gt; &lt;li&gt;SNES9x + X Window + frame buffer&lt;/li&gt;  &lt;li&gt;SNES9x + SDL + X Window + frame buffer&lt;/li&gt;  &lt;li&gt;SNES9x + SDL + frame buffer&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Rotation has been implemented in X window so for 1 and 2, there is no need to implement rotation in SDL or SNES9x. But the performance of 1 and 2 is worse than 3. So I implement the rotation in SNES9x. The patch can be downloaded &lt;a href="http://linux-mcr700.sourceforge.net/download/snes9x_rotate_akita.patch"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-6283512889153158244?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/6283512889153158244/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=6283512889153158244' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/6283512889153158244'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/6283512889153158244'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/snes9x-for-zaurus-akita-with-rotate.html' title='SNES9x for Zaurus Akita with rotate'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-8916732403363587553</id><published>2009-06-13T20:35:00.001-07:00</published><updated>2009-06-13T20:35:49.353-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x61t'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='tablet'/><title type='text'>Some software for tablet PC</title><content type='html'>&lt;ul&gt; &lt;li&gt;Stroke (gesture recognition)  &lt;ul&gt; &lt;li&gt;I find &lt;a href="http://easystroke.wiki.sourceforge.net/"&gt;easystroke&lt;/a&gt; is the best so far. To make it easier to enable/disable easytroke, (because several gesture recognition programs in system may conflict, for example, there is gesture recognition in firefox too.) I write a small patch to disable/enable easystroke with left button, which can be downloaded from &lt;a href="http://linux-mcr700.sourceforge.net/download/easystroke-0.3.1_left_btn_disable.patch"&gt;here&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;  &lt;li&gt;Note taking with pen  &lt;ul&gt; &lt;li&gt;I think &lt;a href="http://xournal.sourceforge.net/"&gt;xournal&lt;/a&gt; is very good. It can be used to add annotations to PDF files.&lt;/li&gt; &lt;/ul&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/661364275739764944-8916732403363587553?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/8916732403363587553/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=8916732403363587553' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/8916732403363587553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/8916732403363587553'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/some-software-for-tablet-pc.html' title='Some software for tablet PC'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-8515282090457072384</id><published>2009-06-13T20:33:00.000-07:00</published><updated>2009-06-13T20:34:38.066-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x61t'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='tablet'/><title type='text'>Firefox addons for tablet PC</title><content type='html'>&lt;ul&gt; &lt;li&gt;Grab and Drag  &lt;p&gt;Enables Adobe Acrobat-style grab and drag scrolling in Mozilla applications.&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;All-in-One Gestures  &lt;p&gt;This extension allows you to execute common commands using mouse (pen) gestures.&lt;/p&gt;  &lt;p&gt;Several mouse gestures programs may conflict each other, so I write a simple &lt;a href="http://linux-mcr700.sourceforge.net/download/aiog-control.xpi"&gt;AIOGControl&lt;/a&gt; (All-in-One Gestures) control addon to enable/disable All-in-One Gestures via a Firefox toolbar button. This is easier for pen to operate.&lt;/p&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/661364275739764944-8515282090457072384?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/8515282090457072384/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=8515282090457072384' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/8515282090457072384'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/8515282090457072384'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/firefox-addons-for-tablet-pc.html' title='Firefox addons for tablet PC'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-81941279552554590</id><published>2009-06-13T20:25:00.000-07:00</published><updated>2009-06-13T20:28:10.606-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='touchscreen'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='tablet'/><title type='text'>Finger friendly scrollbar in GTK+</title><content type='html'>&lt;p&gt;Standard GTK+ scrollbar is too small for finger, to make it bigger, you can put following code in your .gtkrc-2.0 or gtkrc file of theme.&lt;/p&gt;  &lt;pre class="example"&gt;style "big-scrolls" {&lt;br /&gt;  GtkRange::stepper-size = 50&lt;br /&gt;  GtkRange::slider-width = 50&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class "GtkScrollbar" style "big-scrolls"&lt;/pre&gt;  &lt;p&gt;Please refer to &lt;a href="http://www.roosmaa.net/index.php/2009/02/09/making-gtk-scrollbars-more-touchscreen-friendly/"&gt;http://www.roosmaa.net/index.php/2009/02/09/making-gtk-scrollbars-more-touchscreen-friendly/&lt;/a&gt; too.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-81941279552554590?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/81941279552554590/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=81941279552554590' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/81941279552554590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/81941279552554590'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/finger-friendly-scrollbar-in-gtk.html' title='Finger friendly scrollbar in GTK+'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-1271783759461193191</id><published>2009-06-13T20:21:00.000-07:00</published><updated>2009-06-13T20:47:49.556-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Comparison against overflow</title><content type='html'>&lt;p&gt;Time variables are subject to overflow. So, the comparison statement as follow will return incorrect result if t1 has overflowed and t2 has not overflowed.&lt;/p&gt;  &lt;p&gt;&lt;code&gt; unsigned long t1, t2;  if (t1 &amp;gt; t2)  printf("t1 &amp;gt; t2"); &lt;/code&gt;&lt;/p&gt;  &lt;p&gt;The code as follow can be used to deal with the above issue.&lt;/p&gt;  &lt;p&gt;&lt;code&gt; unsigned long t1, t2;  if ((long)(t1 - t2) &amp;gt; 0)  printf("t1 &amp;gt; t2"); &lt;/code&gt;&lt;/p&gt;  &lt;p&gt;Suppose sizeof(unsigned long) = 4, and t1 &amp;lt; t2, the result of t1 - t2 under the unsigned semantics is (0x100000000 + t1 - t2), because of borrow, if the result &amp;lt; 0x80000000, in signed semantics and complemental code, the result is positive.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-1271783759461193191?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/1271783759461193191/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=1271783759461193191' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/1271783759461193191'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/1271783759461193191'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/comparison-against-overflow.html' title='Comparison against overflow'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-6514570834812649410</id><published>2009-06-13T20:18:00.000-07:00</published><updated>2009-06-13T20:48:13.094-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Screen with title in status bar</title><content type='html'>&lt;p&gt;&lt;a href="http://www.gnu.org/software/screen/"&gt;screen&lt;/a&gt; is a nice terminal tool.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;cp example screenrc from doc to home directory&lt;/li&gt;&lt;li&gt;Add following lines to screenrc, window titles of current screen session will be shown in status bar with current window title hilighted.&lt;/li&gt;&lt;/ol&gt;&lt;pre class="example"&gt;hardstatus string "%h"&lt;br /&gt;caption always "%{=r}%?%{b}%-Lw%?%{+bu r}%n*%f %t%{R}%{-bu}%?%{b}%+Lw%: %?%{+b B}%=%C:%s"&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-6514570834812649410?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/6514570834812649410/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=6514570834812649410' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/6514570834812649410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/6514570834812649410'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/screen-with-title-in-status-bar.html' title='Screen with title in status bar'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-996141813786264627</id><published>2009-06-13T20:17:00.000-07:00</published><updated>2009-06-13T20:18:19.322-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Embedded'/><title type='text'>Mer: Comparison with desktop distributions</title><content type='html'>&lt;p&gt;Comes from a presentation of mer community.&lt;/p&gt;  &lt;p&gt;Is Mer just yet another linux distribution? Many people would disagree since we break quite a lot of things (Maemo GTK is a big one!), and I'll tell you some of the ways we differ.&lt;/p&gt;  &lt;p&gt;Like Maemo we focus on power saving, some things that make sense on desktop/laptop distributions simply doesn't make sense on mobile devices that's supposed to last on the same charge several days being always­connected.&lt;/p&gt;  &lt;p&gt;A tablet still comes with limited storage space, so there might be a need to shrink packages or dependancies (why do we need a weather library for NetworkManager?); but not hard as on an embedded system; there's miles difference between 256m flash and 64mb flash.&lt;/p&gt;  &lt;p&gt;Yes, you can't run Crysis on a tablet, it has CPU, memory and bandwidth constraints and apps should be suited towards that. But, what it can do is to be more powerful because of the environment and services surrounding it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-996141813786264627?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/996141813786264627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=996141813786264627' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/996141813786264627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/996141813786264627'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/mer-comparison-with-desktop.html' title='Mer: Comparison with desktop distributions'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-7178090410724156179</id><published>2009-06-13T20:15:00.000-07:00</published><updated>2009-06-13T20:16:56.820-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Hard disk image in qemu</title><content type='html'>&lt;h3&gt;create/update image&lt;/h3&gt;  &lt;p class="first"&gt;Install a mini linux system in &amp;lt;/sub-linux&amp;gt;. It is very easy to install debian inside another Linux.&lt;/p&gt;  &lt;h4&gt;Update image quickly&lt;/h4&gt;  &lt;p class="first"&gt;quick_upimg.sh&lt;/p&gt;  &lt;pre class="example"&gt; qemu-img create -b &amp;lt;hd.img&amp;gt; -f qcow2 &amp;lt;hd.qcow2&amp;gt; &lt;/pre&gt;   &lt;h4&gt;Update image&lt;/h4&gt;  &lt;p class="first"&gt;upimg.sh&lt;/p&gt;  &lt;pre class="example"&gt; sudo genext2fs -d &amp;lt;/sub-linux&amp;gt; -b 344800 &amp;lt;hd.img&amp;gt; chown &amp;lt;yourself&amp;gt;. &amp;lt;hd.img&amp;gt; quick_upimg.sh &lt;/pre&gt;  &lt;p&gt;If you use &amp;lt;hd.qcow2&amp;gt; in QEMU, &amp;lt;hd.img&amp;gt; will not changed for ordinary usage.&lt;/p&gt;   &lt;h4&gt;commit changes&lt;/h4&gt;  &lt;p class="first"&gt;You can explicitely commit changes to &amp;lt;hd.img&amp;gt; by qemu monitor command &amp;quot;commit&amp;quot;.&lt;/p&gt;   &lt;h4&gt;access qcow2 image&lt;/h4&gt;  &lt;pre class="example"&gt; $ qemu-nbd [-p &amp;lt;port&amp;gt;] hd.qcow2 $ sudo modprobe nbd nbds_max=&amp;lt;2&amp;gt; $ sudo nbd-client localhost &amp;lt;port&amp;gt; /dev/nbd0 $ sudo mount /dev/nbd0 /mnt &lt;/pre&gt;  &lt;p&gt;after using:&lt;/p&gt;  &lt;pre class="example"&gt; $ sudo umount /mnt $ sudo nbd-client -d /dev/nbd0 &lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-7178090410724156179?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/7178090410724156179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=7178090410724156179' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/7178090410724156179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/7178090410724156179'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/hard-disk-image-in-qemu.html' title='Hard disk image in qemu'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-7762400043275494519</id><published>2009-06-13T20:13:00.000-07:00</published><updated>2009-06-13T20:15:22.460-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Blog with muse</title><content type='html'>&lt;p&gt;Recently I decide to use muse as my primary composing tool. Because:&lt;/p&gt;  &lt;ul&gt; &lt;li&gt;Easy to use.&lt;/li&gt;  &lt;li&gt;Mark based instead of WYSIWYG. Full control of output and document structure.&lt;/li&gt;  &lt;li&gt;Can convert to many other format, including docbook and latex. So if formating capability of muse is not enough, we can use other format instead later.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;To use muse to write blog (mainly for blogspot):&lt;/p&gt;  &lt;ul&gt; &lt;li&gt;Instal muse-el&lt;/li&gt;  &lt;li&gt;Add "(require 'muse-blosxom)" into your .emacs&lt;/li&gt;  &lt;li&gt;Write your blog in emacs with muse mode.&lt;/li&gt;  &lt;li&gt;"C-c C-t" to generate output in blosxom-html format.&lt;/li&gt;  &lt;li&gt;Open generated blosxom-html, "C-x h" to mark whole buffer, "M-!" to run a external shell script on your current buffer to do some post-processing. The shell script can be as follow.&lt;/li&gt; &lt;/ul&gt;  &lt;pre class="example"&gt; sed -e '1d' -e '/^#postdate/d' | tr '\r\n' '  ' &lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-7762400043275494519?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/7762400043275494519/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=7762400043275494519' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/7762400043275494519'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/7762400043275494519'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/blog-with-muse.html' title='Blog with muse'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-5803273883066410597</id><published>2009-06-13T20:11:00.000-07:00</published><updated>2009-06-13T20:50:28.620-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>ACPI dump</title><content type='html'>&lt;ol&gt;&lt;li&gt;acpidump &amp;gt; &amp;lt;dump_file&amp;gt;&lt;/li&gt;&lt;li&gt;acpixtract -a &amp;lt;dump_file&amp;gt;&lt;/li&gt;&lt;li&gt;iasl -d &amp;lt;TAB&amp;gt;.dat&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-5803273883066410597?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/5803273883066410597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=5803273883066410597' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/5803273883066410597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/5803273883066410597'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/acpi-dump.html' title='ACPI dump'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-2126146788984187257</id><published>2009-06-13T20:08:00.000-07:00</published><updated>2009-06-13T20:10:25.692-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>New process group in shell script</title><content type='html'>&lt;p&gt;To create a new process group for a command (or another shell script) in bash script, the following method can be used.&lt;/p&gt;  &lt;pre class="example"&gt; b=$(bash -i -c "&amp;lt;command&amp;gt; &amp;amp; echo \$!") &lt;/pre&gt;  &lt;p&gt;This can be put in a shell script. String after -c will be executed by the (sub-)bash, while -i means the (sub-)bash will behave like a interactive bash. So "&amp;lt;command&amp;gt; &amp;amp;" in string will execute &amp;lt;command&amp;gt; in a new process group, just like "&amp;lt;command&amp;gt; &amp;amp;" is typed in a login shell. The "echo \$!" in string will print the process ID, that is, the new process group ID, so you can operate on the new created process group, such as send signal to process group via "kill -SIGNAL -$b".&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-2126146788984187257?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/2126146788984187257/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=2126146788984187257' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/2126146788984187257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/2126146788984187257'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/06/new-process-group-in-shell-script.html' title='New process group in shell script'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-5922042569431380134</id><published>2009-05-16T18:58:00.000-07:00</published><updated>2009-05-16T19:00:22.898-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>A new method to distinguish between ring buffer full and empty</title><content type='html'>&lt;p&gt;One design choice for ring buffer implementation is to distinguish&lt;br /&gt;between full buffer and empty buffer. Traditional methods including&lt;br /&gt;waste one entry for full (&lt;code&gt;head + 1 == tail&lt;/code&gt;), or use&lt;br /&gt;another flag for full. A new method is implemented as follow:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;#define RING_LEN   16&lt;br /&gt;#define RING_LIMIT (2 * RING_LEN - 1)&lt;br /&gt;&lt;br /&gt;struct ring_entry&lt;br /&gt;{&lt;br /&gt;  ...&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct ring&lt;br /&gt;{&lt;br /&gt;  int head;&lt;br /&gt;  int tail;&lt;br /&gt;  struct ring_entry entries[RING_LEN];&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int ring_index(int n)&lt;br /&gt;{&lt;br /&gt;  if (n &amp;gt; RING_LEN)&lt;br /&gt;      return n - RING_LEN;&lt;br /&gt;  else&lt;br /&gt;      return n;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int ring_get(struct ring *ring, struct ring_entry *entry)&lt;br /&gt;{&lt;br /&gt;  /* empty */&lt;br /&gt;  if (ring-&amp;gt;head == ring-&amp;gt;tail)&lt;br /&gt;      return 0;&lt;br /&gt;&lt;br /&gt;  *entry = ring-&amp;gt;entries[ring_index(ring-&amp;gt;tail)];&lt;br /&gt;&lt;br /&gt;  ring-&amp;gt;tail++;&lt;br /&gt;  if (ring-&amp;gt;tail &amp;gt; RING_LIMIT)&lt;br /&gt;      ring-&amp;gt;tail = 0;&lt;br /&gt;  return 1;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int ring_put(struct ring *ring, struct ring_entry *entry)&lt;br /&gt;{&lt;br /&gt;  int ihead, itail;&lt;br /&gt;&lt;br /&gt;  ihead = ring_index(ring-&amp;gt;head);&lt;br /&gt;  itail = ring_index(ring-&amp;gt;tail);&lt;br /&gt;&lt;br /&gt;  /* full */&lt;br /&gt;  if (ihead == itail &amp;amp;&amp;amp; ring-&amp;gt;head != ring-&amp;gt;tail)&lt;br /&gt;      return 0;&lt;br /&gt;&lt;br /&gt;  ring-&amp;gt;entries[ihead] = *entry;&lt;br /&gt;&lt;br /&gt;  ring-&amp;gt;head++;&lt;br /&gt;  if (ring-&amp;gt;head &amp;gt; RING_LIMIT)&lt;br /&gt;      ring-&amp;gt;head = 0;&lt;br /&gt;  return 1;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-5922042569431380134?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/5922042569431380134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=5922042569431380134' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/5922042569431380134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/5922042569431380134'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/05/new-method-to-distinguish-between-ring.html' title='A new method to distinguish between ring buffer full and empty'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-4832670866471399144</id><published>2009-05-16T17:54:00.000-07:00</published><updated>2009-05-16T17:55:47.031-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux kernel'/><title type='text'>Buffers in Linux kernel</title><content type='html'>&lt;p&gt;For 2.6.30&lt;/p&gt;  &lt;h4&gt;Oprofile Buffer&lt;/h4&gt;  &lt;ul&gt; &lt;li&gt;One cpu_buffer for each CPU  &lt;ul&gt; &lt;li&gt;NMI or IRQ handler add record to cpu_buffer&lt;/li&gt;  &lt;li&gt;Timer based per-cpu work queue remove record from cpu_buffer&lt;/li&gt;  &lt;li&gt;One reader and one writer, so it is easy for mutual exclusion and synchronization&lt;/li&gt;  &lt;li&gt;fix size, may overflow if write too much or not removed quickly enough&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;  &lt;li&gt;One event_buffer  &lt;ul&gt; &lt;li&gt;Timer based per-cpu work queue add record to event_buffer from that of cpu_buffer&lt;/li&gt;  &lt;li&gt;User space program remove record from event_buffer. User space program is waken up based on threshold.&lt;/li&gt;  &lt;li&gt;One reader and multiple writer, mutex is used on write side, because writers are in process context (work queue).&lt;/li&gt;  &lt;li&gt;fix size, may overflow if write too much or not read out quickly enough&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;  &lt;li&gt;Synchronization between cpu_buffer, event_buffer and use space program  &lt;ul&gt; &lt;li&gt;Used for profile, so record flow bandwidth is predictable  &lt;ul&gt; &lt;li&gt;Maximum bandwidth for cpu_buffer: CPU number * (cpu_buffer size / timer interval)&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt; &lt;/ul&gt;   &lt;h4&gt;Unified trace ring buffer&lt;/h4&gt;  &lt;ul&gt; &lt;li&gt;One ring_buffer_per_cpu for each CPU  &lt;ul&gt; &lt;li&gt;In fact two levels of records, the first level is struct buffer_page, the second level is struct ring_buffer_event.&lt;/li&gt;  &lt;li&gt;Preempt disabling is used to provide mutual exclusion between process contexts.&lt;/li&gt;  &lt;li&gt;Inside one struct buffer_page, atomic operation (local_add_return) is used to provide mutual exclusion for struct ring_buffer_event. Because process context can only be preempted by IRQ and NMI, and process context can not continue until IRQ and NMI finishes. The length of struct buffer_page is known (local_add_return may exceed buffer_page length).&lt;/li&gt;  &lt;li&gt;In writer side, "write" indicates allocated records, while "commit" indicates completed records.&lt;/li&gt;  &lt;li&gt;spinlock (ring_buffer_per_cpu-&amp;gt;lock) and IRQ disable is used to provide mutual exclusion for struct buffer_page (reader and writer). In NMI environment, if try_spin_lock failed, the record is discarded, this acceptable for tracing.&lt;/li&gt;  &lt;li&gt;At least 3 pages are needed for each CPU, 2 buffer_page, 1 reader page.&lt;/li&gt;  &lt;li&gt;ring_buffer_per_cpu-&amp;gt;reader_lock is used to provide mutual exclusion between multiple readers, while ring_buffer_per_cpu-&amp;gt;lock is used to provide mutual exclusion between reader and writer.&lt;/li&gt;  &lt;li&gt;fix size, may overflow if write too much or not consumed quickly enough&lt;/li&gt;  &lt;li&gt;Iterator (iter) can be used on reader side&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt; &lt;/ul&gt;   &lt;h4&gt;Mcelog buffer&lt;/h4&gt;  &lt;ul&gt; &lt;li&gt;One global buffer with fixed record length, fixed size. May overflow.&lt;/li&gt;  &lt;li&gt;Writer side lock-less, implemented using cmpxchg() + finished flag. Records are added in NMI/timer context.&lt;/li&gt;  &lt;li&gt;Memory order should be considered explicitly because of lock-less&lt;/li&gt;  &lt;li&gt;Reader side is protected by mutex, because normally there is only one reader. Records are removed in process context.&lt;/li&gt;  &lt;li&gt;Multiple writers, one reader, throughput bottleneck lies in reader side.&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/661364275739764944-4832670866471399144?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/4832670866471399144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=4832670866471399144' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/4832670866471399144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/4832670866471399144'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/05/buffers-in-linux-kernel.html' title='Buffers in Linux kernel'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-5947246270373549165</id><published>2009-05-16T16:59:00.000-07:00</published><updated>2009-05-16T17:01:32.214-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux kernel'/><title type='text'>SMP preemption -&gt; UP preemption</title><content type='html'>&lt;p class="first"&gt;Sometimes, a SMP environment can turn into a UP environment via per-CPU data structure. Such as unified trace ring buffer is a per-CPU data structure, so the mutual exclusion can be considered in UP model for each per-CPU buffer.&lt;/p&gt;   &lt;h4&gt;Preemption in UP&lt;/h4&gt;  &lt;p class="first"&gt;There are 3 kinds of contexts in UP environment.&lt;/p&gt;  &lt;ol&gt; &lt;li&gt;Process context&lt;/li&gt;  &lt;li&gt;IRQ context&lt;/li&gt;  &lt;li&gt;NMI context&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Where 1 can be preempted by 1, 2 or 3; 2 can be preempted by 2 or 3; 3 can not be preempted.&lt;/p&gt;  &lt;p&gt;If preempt is off in 1, 1 can only be preempted by 2 or 3. And there is no interleave between contexts, that is, if 1 is preempted by 2, 1 will not be resumed until 2 is finished, so do 2 and 3. This can be used to develop more efficient synchronization algorithm.&lt;/p&gt;  &lt;p&gt;If IRQ is off in 1 and 2, 1 and 2 can only be preempted by 3, without interleave.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-5947246270373549165?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/5947246270373549165/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=5947246270373549165' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/5947246270373549165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/5947246270373549165'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/05/smp-preemption-up-preemption.html' title='SMP preemption -&gt; UP preemption'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-2293973022481862677</id><published>2009-05-09T19:51:00.000-07:00</published><updated>2009-05-09T19:55:23.396-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux kernel'/><category scheme='http://www.blogger.com/atom/ns#' term='reading notes'/><title type='text'>Reading notes of on submit kennel patches (OLS)</title><content type='html'>&lt;h4&gt;!!! Important kernel design point !!!&lt;/h4&gt;  &lt;blockquote&gt; &lt;p class="quoted"&gt; Very generic notifiers and hooks tend to have a large maintenance impact because they have the potential to alter the &lt;strong&gt;&lt;em&gt;code flow&lt;/em&gt;&lt;/strong&gt; in unexpected ways, lead to lock order problems, bugs, and unexpected behavior, and generally making code harder to maintain and debug later.&lt;/p&gt;  &lt;/blockquote&gt;  &lt;p&gt;Linux kernel is a lock-based complex parallel system, the main method to prevent ABBA style dead-lock is enforcing lock order. But notifiers or hooks makes it hard to audit the order of locks.&lt;/p&gt;  &lt;p&gt;Notifiers or hooks in lower layer to call functions on higher layer should be avoided. One method to call higher layer function in lower layer is via work queue like asynchronous mechanism.&lt;/p&gt;  &lt;p&gt;Notifiers or hooks in higher layer to call functions on lower layer is OK. Such as struct file_operations is collections of function pointers (a kind of hooks?), it is only used as some kind of abstraction for lower layer, make adding new lower layer component more convenient.&lt;/p&gt;   &lt;h4&gt;Maintenance&lt;/h4&gt;  &lt;p class="first"&gt;For a project which is very complex like Linux kernel, (seems that most projects become more and more complex as time goes by), maintenance is something in the core of Linux kernel development.&lt;/p&gt;  &lt;p&gt;To make code maintainable, firstly, code should be made readable. The code is clean-upped and redesigned again and again to make it cleaner, thus more readable.&lt;/p&gt;  &lt;p&gt;It is much easier to add a component under the current design. Such as add a new device driver. If you need something to be changed in subsystem core, you should consider the design, maybe you need clean-up or redesign some part of the subsystem core to make code maintainable.&lt;/p&gt;  &lt;p&gt;A patch submitter should maintain his code at least for a short while after merging.&lt;/p&gt;  &lt;p&gt;Interface designs for user space programs is very important too. It should be stable for imaginable future.&lt;/p&gt;  &lt;blockquote&gt; &lt;p class="quoted"&gt; Changing a published interface later is much harder and often special backwards compatiblility code is required.&lt;/p&gt;  &lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-2293973022481862677?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/2293973022481862677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=2293973022481862677' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/2293973022481862677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/2293973022481862677'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/05/reading-notes-of-on-submit-kennel.html' title='Reading notes of on submit kennel patches (OLS)'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-6455608076974218469</id><published>2009-05-08T06:31:00.001-07:00</published><updated>2009-05-09T19:56:48.283-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MID'/><title type='text'>Why MID?</title><content type='html'>&lt;h4&gt;What I need for a Mobile device&lt;/h4&gt;  &lt;ul&gt; &lt;li&gt;Fast from picking up to using (Fast boot)&lt;/li&gt;  &lt;li&gt;light, easy for taking and hand holding&lt;/li&gt;  &lt;li&gt;Applications  &lt;ul&gt; &lt;li&gt;Web browsering&lt;/li&gt;  &lt;li&gt;Electric book&lt;/li&gt;  &lt;li&gt;Online video and offline video&lt;/li&gt;  &lt;li&gt;PIM&lt;/li&gt;  &lt;li&gt;Game&lt;/li&gt;  &lt;li&gt;GPS?&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt; &lt;/ul&gt;   &lt;h4&gt;MID vs Notebook&lt;/h4&gt;  &lt;h5&gt;pros:&lt;/h5&gt;  &lt;ul&gt; &lt;li&gt;Fast from picking up to using: fast boot time or always suspend to RAM instead of power off.&lt;/li&gt;  &lt;li&gt;lighter, easy for taking and hand holding&lt;/li&gt; &lt;/ul&gt;   &lt;h5&gt;cons:&lt;/h5&gt;  &lt;ul&gt; &lt;li&gt;Screen is too small for some applications, especially most web page, PDF, DJVU ebooks&lt;/li&gt;  &lt;li&gt;Notebook has better Linux support, some application has best usability on Notebook.&lt;/li&gt; &lt;/ul&gt;    &lt;h4&gt;MID vs Smartphone&lt;/h4&gt;  &lt;h5&gt;pros:&lt;/h5&gt;  &lt;ul&gt; &lt;li&gt;Screen is bigger, although smaller than Notebook, much better than smartphone's.&lt;/li&gt;  &lt;li&gt;OS is compatible with Desktop ones (Linux or Windows), most desktop applications can run on MID. Although Linux based smartphone can run most desktop applications too, the resource of most smartphone is not enough for desktop application.&lt;/li&gt;  &lt;li&gt;Computing resource of MID (CPU, RAM, storage) is much better than smartphone.&lt;/li&gt; &lt;/ul&gt;   &lt;h5&gt;cons:&lt;/h5&gt;  &lt;ul&gt; &lt;li&gt;Smartphone is all-in-one solution, that is, you can bring just smartphone or smartphone AND MID.&lt;/li&gt;  &lt;li&gt;Smartphone has GPRS support in China, while most MID has not.&lt;/li&gt;  &lt;li&gt;Some smartphone application is good for small screen, such as ucweb for web browsing. Some desktop application is not good for small screen, even bigger screen of MID.&lt;/li&gt; &lt;/ul&gt;    &lt;h4&gt;Comparison&lt;/h4&gt;  &lt;table class="muse-table" border="2" cellpadding="5"&gt;   &lt;tbody&gt;     &lt;tr&gt;       &lt;td&gt;&lt;/td&gt;       &lt;td&gt;Notebook(X61T)&lt;/td&gt;       &lt;td&gt;MID (no yet)&lt;/td&gt;       &lt;td&gt;Smartphone(N78)&lt;/td&gt;       &lt;td&gt;PDA (Zaurus)&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td&gt;Fast usage&lt;/td&gt;       &lt;td&gt;1&lt;/td&gt;       &lt;td&gt;4.5&lt;/td&gt;       &lt;td&gt;5&lt;/td&gt;       &lt;td&gt;4.5&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td&gt;Weight&lt;/td&gt;       &lt;td&gt;1&lt;/td&gt;       &lt;td&gt;4.5&lt;/td&gt;       &lt;td&gt;5&lt;/td&gt;       &lt;td&gt;5&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td&gt;Browsing&lt;/td&gt;       &lt;td&gt;5&lt;/td&gt;       &lt;td&gt;4 ~ 4.5&lt;/td&gt;       &lt;td&gt;3 (ucweb)&lt;/td&gt;       &lt;td&gt;2&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td&gt;EBook&lt;/td&gt;       &lt;td&gt;5&lt;/td&gt;       &lt;td&gt;3 ~ 3.5&lt;/td&gt;       &lt;td&gt;2.5 (screen)&lt;/td&gt;       &lt;td&gt;3&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td&gt;Online Video&lt;/td&gt;       &lt;td&gt;5&lt;/td&gt;       &lt;td&gt;4.5&lt;/td&gt;       &lt;td&gt;0 (no WIFI)&lt;/td&gt;       &lt;td&gt;0 (too slow)&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td&gt;Offline Video&lt;/td&gt;       &lt;td&gt;5&lt;/td&gt;       &lt;td&gt;4.5&lt;/td&gt;       &lt;td&gt;4&lt;/td&gt;       &lt;td&gt;3.5&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td&gt;PIM&lt;/td&gt;       &lt;td&gt;4&lt;/td&gt;       &lt;td&gt;4&lt;/td&gt;       &lt;td&gt;4&lt;/td&gt;       &lt;td&gt;3&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td&gt;Game&lt;/td&gt;       &lt;td&gt;5&lt;/td&gt;       &lt;td&gt;5&lt;/td&gt;       &lt;td&gt;2 (keypad)&lt;/td&gt;       &lt;td&gt;4&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td&gt;GPS&lt;/td&gt;       &lt;td&gt;0&lt;/td&gt;       &lt;td&gt;5 (maybe)&lt;/td&gt;       &lt;td&gt;5&lt;/td&gt;       &lt;td&gt;0&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt; &lt;/table&gt;   &lt;h4&gt;Conclusion&lt;/h4&gt;  &lt;ul&gt; &lt;li&gt;Although MID should be better than smartphone, there is no good choice until now. Aigo or Vilivs is too expensive. Smart Q5 is not better than Zaurus (No stable software too). Most functions of MID can be accomplished with smartphone.&lt;/li&gt;  &lt;li&gt;Notebook + smartphone is good for now, waiting for better MID.&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/661364275739764944-6455608076974218469?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/6455608076974218469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=6455608076974218469' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/6455608076974218469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/6455608076974218469'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/05/why-mid.html' title='Why MID?'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-728234515610974591</id><published>2009-04-26T02:18:00.000-07:00</published><updated>2009-04-26T06:22:59.065-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x61t'/><category scheme='http://www.blogger.com/atom/ns#' term='tablet'/><title type='text'>On screen keyboard</title><content type='html'>On screen keyboard is necessary for a tablet PC. Have tried several on screen keyboard implementation under X window, no one is perfect. Currently using one is cellwriter. Hope the one developed for Moblin will be better.&lt;br /&gt;&lt;br /&gt;Requirement for on screen keyboard:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Focus: the on screen keyboard should not be focused, and the faked key should be sent to the focused window.&lt;/li&gt;&lt;li&gt;Window placement: the on screen keyboard window should not be covered by other windows (for example to be the top-most window), and it should not cover other windows completely (semi-transparent or docked at the desktop side, but it seems docking is not supported well in my metacity 2.24.0).&lt;/li&gt;&lt;li&gt;Compatible with XIM. I am Chinese, I need use XIM to input Chinese.&lt;/li&gt;&lt;li&gt;Configurable layout (to keep only the needed keys).&lt;/li&gt;&lt;li&gt;Show/Hide can be controlled easily (via a panel button is preferable).&lt;/li&gt;&lt;li&gt;Support screen rotation. On screen keyboard should not outside the screen or bigger than screen after rotation.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Tried on screen keyboard software:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;xvkbd: does not handle focus perfectly, the xvkbd itself seem be focused too (titlebar highlighted), so need two click for one key; need to specify which widget faked keys go, not very conveniently.&lt;/li&gt;&lt;li&gt;matchbox-keyboard: good support for rotation, configurable laout, XIM, focus. Docking support for matchbox-wm is good. Original version does not support docking for metacity. I have a hack to support docking for metacity, but the hack doesn't support metacity 2.24.0. Show/Hide control can be done with daemon mode (-d) + &lt;a href="http://japiblog.dddgames.com/?p=15"&gt;matchbox-keyboard-toggler&lt;/a&gt; utility.&lt;/li&gt;&lt;li&gt;gok (gnome on screen keyboard): recommended by many guys, but not good for me. Appears not works with XIM, and not works well without pointer in/out event.&lt;/li&gt;&lt;li&gt;&lt;a href="https://wiki.ubuntu.com/Accessibility/Projects/onBoard"&gt;onboard&lt;/a&gt;: not used too much, I think it is good and simple.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;cellwriter: hand writing recoganizing program, but it is a good and simple on screen keyboard too. To use it as on screen keyboard add "--keyboard-only" to command line. Do no support configurable layout. Seems not support docking good.&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/661364275739764944-728234515610974591?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/728234515610974591/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=728234515610974591' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/728234515610974591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/728234515610974591'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/04/on-screen-keyboard.html' title='On screen keyboard'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-3931595734328547586</id><published>2009-04-26T02:09:00.000-07:00</published><updated>2009-04-26T02:17:48.334-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x61t'/><title type='text'>Lenovo Thinkpad X61 Tablet</title><content type='html'>Bought a Lenovo Thinkpad X61 Tablet recently. Will post some usage tips. Most useful links:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.thinkwiki.org/wiki/ThinkWiki"&gt;http://www.thinkwiki.org/wiki/ThinkWiki&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-3931595734328547586?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/3931595734328547586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=3931595734328547586' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/3931595734328547586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/3931595734328547586'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/04/bought-lenovo-thinkpad-x61-tablet.html' title='Lenovo Thinkpad X61 Tablet'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-7489397629617471176</id><published>2009-04-26T01:49:00.001-07:00</published><updated>2009-04-26T02:18:03.451-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='touchscreen'/><category scheme='http://www.blogger.com/atom/ns#' term='tablet'/><title type='text'>Evtouch configuration</title><content type='html'>This article is mainly for Tablet Classmate PC.&lt;br /&gt;&lt;br /&gt;Evtouch is a Xorg (X window system) input driver for touchscreen device with Linux kernel input/event driver. For example some USB touchscreen device with USBHID class.&lt;br /&gt;&lt;br /&gt;To use evtouch Xorg driver, xorg should be setup as follow:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;Section "InputDevice"&lt;br /&gt;    Identifier    "TOUCH"&lt;br /&gt;    Driver        "evtouch"&lt;br /&gt;    Option        "Device" "/dev/input/by-path/pci-0000:00:1d.3-usb-0:1:1.0-event-"&lt;br /&gt;&lt;br /&gt;    Option        "DeviceName" "touchscreen"&lt;br /&gt;    Option        "ReportingMode" "Raw"&lt;br /&gt;    Option        "MoveLimit" "10"&lt;br /&gt;    Option        "SendCoreEvents" "On"&lt;br /&gt;#       Option        "Calibrate" "1"&lt;br /&gt;    Option        "MinX"      "1"&lt;br /&gt;    Option        "MinY"      "1"&lt;br /&gt;    Option        "MaxX"      "4090"&lt;br /&gt;    Option        "MaxY"      "4090"&lt;br /&gt;    Option        "x0"        "-6"&lt;br /&gt;    Option        "y0"        "8"&lt;br /&gt;    Option        "x1"        "1"&lt;br /&gt;    Option        "y1"        "2"&lt;br /&gt;    Option        "x2"        "12"&lt;br /&gt;    Option        "y2"        "2"&lt;br /&gt;    Option        "x3"        "5"&lt;br /&gt;    Option        "y3"        "3"&lt;br /&gt;    Option        "x4"        "-6"&lt;br /&gt;    Option        "y4"        "3"&lt;br /&gt;    Option        "x5"        "-4"&lt;br /&gt;    Option        "y5"        "3"&lt;br /&gt;    Option        "x6"        "0"&lt;br /&gt;    Option        "y6"        "5"&lt;br /&gt;    Option        "x7"        "1"&lt;br /&gt;    Option        "y7"        "5"&lt;br /&gt;    Option        "x8"        "1"&lt;br /&gt;    Option        "y8"        "5"&lt;br /&gt;EndSection&lt;br /&gt;&lt;br /&gt;Section "ServerLayout"&lt;br /&gt;    ......&lt;br /&gt;    InputDevice     "TOUCH"&lt;br /&gt;EndSection&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;h3&gt;Calibrate by hand&lt;/h3&gt;&lt;br /&gt;Evtouch comes with a calibration utility. It works, but I find the result is not very accurate. In fact it can be calibrated further by editing xorg.conf directly.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;If you find when you touch the margin of the screen, the cursor is not at margin, you can change the "MinX", "MinY", "MaxX", "MaxY" in xorg.conf to calibrate.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;The x0-y0 to x9-y9 corresponds to 9 regions on screen, with the x0-y0 at the left-bottom corner, x2-y0 at the right-bottom corner, x9-y9 at the right-top corner. To calibrate the touch screen in the region, just the values of corresponding options.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h3&gt;Rotate screen&lt;/h3&gt;&lt;br /&gt;To rotate screen:&lt;br /&gt;xrandr --output LVDS --rotate left&lt;br /&gt;&lt;br /&gt;evtouch should have supported rotation automatically. But the evtouch-0.8.7 in my debian does not work. I write a small patch &lt;a href="http://linux-mcr700.sourceforge.net/download/08_fix_rotate.patch"&gt;08__fix_rotate.patch&lt;/a&gt; to fix this issue.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Suspend and Resume&lt;/h3&gt;&lt;br /&gt;My touchscreen device is a usb device. This means it will be removed by Linux kernel before suspend and re-plugged after resume. Evtouch xorg driver has suspend and resume support mechansim, but it does not work sometimes. From the error message in /var/log/Xorg.0.log, it seems that the underlaying usb kernel device is not ready when evtouch xorg driver is being initialized. Fortunatally, it works sometimes. So if it your touchscreen does not work after resume, just go suspend again and hope it works after next resume.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Right Button&lt;/h3&gt;&lt;br /&gt;I am not successful in configuring right button. Maybe a kernel input driver issue, usbhid can not report BTN_TOUCHED for my device. But it seems that the following configuration should work for correct kernel input drivers.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;Section "InputDevice"&lt;br /&gt;    Identifier      "TOUCH"&lt;br /&gt;    Driver          "evtouch"&lt;br /&gt;    ......&lt;br /&gt;    Option          "longtouched_action" "down"&lt;br /&gt;    Option          "longtouched_button" "3"&lt;br /&gt;EndSection&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-7489397629617471176?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/7489397629617471176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=7489397629617471176' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/7489397629617471176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/7489397629617471176'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/04/evtouch-configuration.html' title='Evtouch configuration'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-5068471434314353337</id><published>2009-04-02T05:22:00.000-07:00</published><updated>2009-04-02T05:47:15.112-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ereader'/><title type='text'>IBSuite</title><content type='html'>To read book on my PRS505 e-book reader, I write some tools. Now I collect these tools into IBSuite (Image Book Suite), and put that on sourceforge. You can download the source code from the git of sourceforge project. Hope that can be useful for somebody.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://sourceforge.net/projects/ibsuite/"&gt;http://sourceforge.net/projects/ibsuite/&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;IBSUITE&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;ibsuite stands for image book suite. It contains a set of tools to convert ebook in various format (pdf, chm, html) into a set of images, reformat the images (crop, embold, divide, etc), and assemble the result images into a new ebook.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;COMPONENTS&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ibhtml2img: convert html to image with xulrunner&lt;/li&gt;&lt;li&gt;ibhtml2pdf: convert html to pdf with xulrunner&lt;/li&gt;&lt;li&gt;iblineparser: parser input image, extract line information&lt;/li&gt;&lt;li&gt;ibpdfinfo: get some meta-information from pdf file, such as title, author, table of contents etc.&lt;/li&gt;&lt;li&gt;ibpy: python module, which is the driver of the whole system, it uses above programs to convert input file to image, extract line information from image, dilate image, and re-assemble lines into a new image, generate output e-book.&lt;/li&gt;&lt;li&gt;ibtools: A set of utilities and tools, some of them are used internal by ibsuite, others are user command provided by ibsuite.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;USAGE&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The most important command of ibsuite is ibreformat, the basic usage is as follow:&lt;br /&gt;&lt;br /&gt;ibreformat [options] &amp;lt;input file&amp;gt;&lt;br /&gt;&lt;br /&gt;In most cases, something like following:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  ibreformat -o &lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;output file&amp;gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt; &lt;output&gt; --iprof=&lt;iprof&gt;&amp;lt;iprof&amp;gt; --oprof=&lt;oprof&gt;&lt;/oprof&gt;&lt;/iprof&gt;&lt;/output&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;oprof&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    --pprof=&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;pprof&amp;gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;pprof&gt; &lt;/pprof&gt;&lt;/span&gt;&amp;lt;input file&amp;gt;&lt;br /&gt;&lt;br /&gt;Where &amp;lt;input file&amp;gt; is input file name, &lt;span style="font-family:courier new;"&gt;&amp;lt;output file&amp;gt;&lt;/span&gt;&lt;output&gt; is output file name, &lt;/output&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;iprof&amp;gt;&lt;/span&gt;&lt;output&gt;&lt;iprof&gt; is input profile, &lt;/iprof&gt;&lt;/output&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;pprof&amp;gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;pprof&gt;&lt;/pprof&gt;&lt;/span&gt;&lt;output&gt;&lt;iprof&gt;&lt;oprof&gt; is output profile, &lt;pprof&gt; is &lt;/pprof&gt;&lt;/oprof&gt;&lt;/iprof&gt;&lt;/output&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;pprof&amp;gt; &lt;/span&gt;&lt;output&gt;&lt;iprof&gt;&lt;oprof&gt;&lt;pprof&gt;processing profile.&lt;br /&gt;&lt;br /&gt;Available input/output/processing profiles are as follow:&lt;br /&gt;&lt;br /&gt;&lt;/pprof&gt;&lt;/oprof&gt;&lt;/iprof&gt;&lt;/output&gt;&lt;br /&gt;&lt;output style="font-weight: bold;"&gt;&lt;iprof&gt;&lt;oprof&gt;&lt;pprof&gt;input profiles:&lt;/pprof&gt;&lt;/oprof&gt;&lt;/iprof&gt;&lt;/output&gt;&lt;br /&gt;&lt;output&gt;&lt;iprof&gt;&lt;oprof&gt;&lt;pprof&gt;img: for scanned book&lt;/pprof&gt;&lt;/oprof&gt;&lt;/iprof&gt;&lt;/output&gt;&lt;br /&gt;&lt;br /&gt;&lt;output style="font-weight: bold;"&gt;&lt;iprof&gt;&lt;oprof&gt;&lt;pprof&gt;output profiles:&lt;/pprof&gt;&lt;/oprof&gt;&lt;/iprof&gt;&lt;/output&gt;&lt;br /&gt;&lt;output&gt;&lt;iprof&gt;&lt;oprof&gt;&lt;pprof&gt;prs505p: for Sony PRS505 in portrait mode&lt;/pprof&gt;&lt;/oprof&gt;&lt;/iprof&gt;&lt;/output&gt;&lt;br /&gt;&lt;output&gt;&lt;iprof&gt;&lt;oprof&gt;&lt;pprof&gt;prs505l: for Sony PRS505 in landscape mode&lt;/pprof&gt;&lt;/oprof&gt;&lt;/iprof&gt;&lt;/output&gt;&lt;br /&gt;&lt;output style="font-weight: bold;"&gt;&lt;iprof&gt;&lt;oprof&gt;&lt;pprof&gt;&lt;br /&gt;processing profiles:&lt;/pprof&gt;&lt;/oprof&gt;&lt;/iprof&gt;&lt;/output&gt;&lt;br /&gt;&lt;output&gt;&lt;iprof&gt;&lt;oprof&gt;&lt;pprof&gt;divide2: divide one line into two line (a kind of simple reflow)&lt;/pprof&gt;&lt;/oprof&gt;&lt;/iprof&gt;&lt;/output&gt;&lt;br /&gt;&lt;output&gt;&lt;iprof&gt;&lt;oprof&gt;&lt;pprof&gt;resize: Resize and dilate pages&lt;/pprof&gt;&lt;/oprof&gt;&lt;/iprof&gt;&lt;/output&gt;&lt;br /&gt;&lt;output&gt;&lt;iprof&gt;&lt;oprof&gt;&lt;pprof&gt;repage: Re-page input book, without much other processing such as dilate.&lt;/pprof&gt;&lt;/oprof&gt;&lt;/iprof&gt;&lt;/output&gt;&lt;br /&gt;&lt;output&gt;&lt;iprof&gt;&lt;oprof&gt;&lt;pprof&gt;&lt;br /&gt;For other command line options, please refer to "ibreformat -h".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Some useful command line option combinations:&lt;br /&gt;&lt;br /&gt;For scanned book on PRS505:&lt;br /&gt;&lt;br /&gt;ibsuite -o &lt;output&gt; -iprof=img -pprof=resize -oprof=prs505l &lt;/output&gt;&lt;/pprof&gt;&lt;/oprof&gt;&lt;/iprof&gt;&lt;/output&gt;&amp;lt;input file&amp;gt;&lt;br /&gt;&lt;output&gt;&lt;iprof&gt;&lt;oprof&gt;&lt;pprof&gt;&lt;output&gt;&lt;br /&gt;For chm file on PRS505:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  ibchm2imb &lt;xxx&gt;.chm&lt;/xxx&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When it finishs, &lt;xxx&gt;.imb will be generated, then&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  ibsuite -o &lt;output&gt; -pprof=repage --oprof=prs505l &lt;xxx&gt;.imb&lt;/xxx&gt;&lt;/output&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;INSTALL&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Currently, only Linux is supported, but I think it may work on some unix enviroment (including cygwin on Windows) after some work. Currently only install from source code is supported.&lt;br /&gt;&lt;br /&gt;Pre-requirement:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;gcc, g++, bash, make&lt;/li&gt;&lt;li&gt;libfontconfig-dev, libnetpbm-dev, libgtk-dev&lt;/li&gt;&lt;li&gt;python, python-imaging&lt;/li&gt;&lt;li&gt;imagemagick&lt;/li&gt;&lt;li&gt;for HTML/CHM support: python-chm, xulrunner&lt;/li&gt;&lt;li&gt;for scanned book: unpaper&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Build:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;./configure [--prefix=&lt;prefix&gt;]&lt;/prefix&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;make [PREFIX=&lt;prefix&gt;] [NO_XUL=1]&lt;/prefix&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Install:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;# become root&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;make install [PREFIX=&lt;prefix&gt;]&lt;/prefix&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/xxx&gt;&lt;/output&gt;&lt;/pprof&gt;&lt;/oprof&gt;&lt;/iprof&gt;&lt;/output&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-5068471434314353337?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/5068471434314353337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=5068471434314353337' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/5068471434314353337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/5068471434314353337'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2009/04/ibsuite.html' title='IBSuite'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-7551131204765885561</id><published>2008-11-24T18:17:00.000-08:00</published><updated>2008-11-24T18:27:34.845-08:00</updated><title type='text'>Google notebook</title><content type='html'>I find google notebook is a convenient tool. You can take note quite freely during surfing. And you can share your notebook quite easy too. I think it is even easier than Blog. Some of my exported notebook:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.google.com/notebook/public/14468981592936108290/BDRKWDAoQqNKCxtoj"&gt;Programming&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.google.com/notebook/public/14468981592936108290/BDQ18DAoQsJLPotgj"&gt;Smart phone&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-7551131204765885561?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/7551131204765885561/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=7551131204765885561' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/7551131204765885561'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/7551131204765885561'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2008/11/google-notebook.html' title='Google notebook'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-9218821004744579506</id><published>2008-07-18T23:31:00.000-07:00</published><updated>2008-07-18T23:36:56.813-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ereader'/><title type='text'>An algorithm to render PDF on small devices</title><content type='html'>I am interested in ebook reader for quite a while. But after trying with a 6-inch e-ink reader (Hanlin V3), I found it is almost useless to read normal PDF files (A4 size) on these devices. The font size is too small, while the page size is too wide.  So, a method to render PDF for these small devices is thought about and prototyped. The details are as follow:  &lt;ol id="gl2l3"&gt;&lt;li id="gl2l4"&gt;Convert pdf to image. I use pdftoppm of xpdf. Such as: pdftoppm -r 180 -f 245 -l 245 -gray -aa yes a.pdf a&lt;/li&gt;&lt;li id="gl2l5"&gt;Analyze the generated images. Break page into lines.&lt;/li&gt;&lt;li id="gl2l6"&gt;Divide each line long enough to two segments.&lt;/li&gt;&lt;li id="gl2l7"&gt;Rearrange the segments into a new page, with half of the width.&lt;/li&gt;&lt;/ol&gt; A full functional PDF re-flow algorithm is very difficult to implemented. But a more simplified version as above is much easier.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-9218821004744579506?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/9218821004744579506/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=9218821004744579506' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/9218821004744579506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/9218821004744579506'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2008/07/i-am-interested-in-ebook-reader-for.html' title='An algorithm to render PDF on small devices'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-4796164445177450884</id><published>2008-07-18T23:04:00.000-07:00</published><updated>2008-07-18T23:34:01.193-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='functional language'/><title type='text'>No state updating: functional language</title><content type='html'>The programming model of command language is state machine. Such as in C, every variable is a state, one of the most common statements are assigning new value to a variable, that is, state updating. But in functional programming language, there is no state updating, how to program without state updating? Let's begin with a simple example of bank account management system.  &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;struct account&lt;br /&gt;{&lt;br /&gt;    char *name;&lt;br /&gt;    int remain;&lt;br /&gt;    struct account *next;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;#define OP_NOP         0&lt;br /&gt;#define OP_WITHDRAW    1&lt;br /&gt;#define OP_DEPOSIT     2&lt;br /&gt;#define OP_PRINT       3&lt;br /&gt;#define OP_EXIT        4&lt;br /&gt;&lt;br /&gt;void deposit(struct account *account, int val)&lt;br /&gt;{&lt;br /&gt;    account-&gt;remain += val;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void withdraw(struct account *account, int val)&lt;br /&gt;{&lt;br /&gt;    account-&gt;remain -= val;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;    struct account *accounts = NULL;&lt;br /&gt;    char *name;&lt;br /&gt;    int op = OP_NOP, val;&lt;br /&gt;&lt;br /&gt;    while (op != OP_EXIT) {&lt;br /&gt;        op = read_operation();&lt;br /&gt;        case OP_WITHDRAW:&lt;br /&gt;        case OP_DEPOSIT:&lt;br /&gt;            name = read_name();&lt;br /&gt;            account = list_find(accounts, name);&lt;br /&gt;            val = read_val();&lt;br /&gt;            if (op == OP_WITHDRAW)&lt;br /&gt;                withdraw(account, val);&lt;br /&gt;            else&lt;br /&gt;                deposit(account, val);&lt;br /&gt;            break;&lt;br /&gt;        case OP_NEW:&lt;br /&gt;            name = read_name();&lt;br /&gt;            account = malloc(sizeof(struct account));&lt;br /&gt;            account-&gt;name = name;&lt;br /&gt;            account-&gt;remain = 0;&lt;br /&gt;            list_add(&amp;accounts, account);&lt;br /&gt;            break;&lt;br /&gt;        case OP_PRINT:&lt;br /&gt;            /* a macro to iterate every element of list */&lt;br /&gt;            list_for_each(accounts, account) {&lt;br /&gt;                printf("Name: %s\tRemain: %d\n", account-&gt;name, account-&gt;remain);&lt;br /&gt;            }&lt;br /&gt;            break;&lt;br /&gt;        case OP_EXIT:&lt;br /&gt;            break;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In erlang, a functional programming language:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-module(bank).&lt;br /&gt;-export([service/1]).&lt;br /&gt;&lt;br /&gt;deposit(Account, Val) -&gt;&lt;br /&gt;    {Name, Remain} = Account,&lt;br /&gt;    {Name, Remain + Val}.&lt;br /&gt;&lt;br /&gt;withdraw(Account, Val) -&gt;&lt;br /&gt;    {Name, Remain} = Account,&lt;br /&gt;    {Name, Remain - Val}.&lt;br /&gt;&lt;br /&gt;print_account({Name, Remain}) -&gt;&lt;br /&gt;    io:format("Name: ~s Remain: ~B~n", [Name, Remain]).&lt;br /&gt;&lt;br /&gt;service(Accounts) -&gt;&lt;br /&gt;    {ok, [Operation|_]} = io:fread("Operation: ", "~a"),&lt;br /&gt;    if&lt;br /&gt;    Operation == deposit; Operation == withdraw -&gt;&lt;br /&gt;        {ok, [Name|_]} = io:fread("Name: ", "~s"),&lt;br /&gt;        {ok, [Val|_]} = io:fread("Val: ", "~d"),&lt;br /&gt;        case lists:keysearch(Name, 1, Accounts) of&lt;br /&gt;        false -&gt;&lt;br /&gt;            io:format("Error: no such account.~n"),&lt;br /&gt;            NewAccounts = Accounts;&lt;br /&gt;        {value, Account} -&gt;&lt;br /&gt;            case Operation of&lt;br /&gt;            deposit -&gt;&lt;br /&gt;                NewAccount = deposit(Account, Val);&lt;br /&gt;            withdraw -&gt;&lt;br /&gt;                NewAccount = withdraw(Account, Val)&lt;br /&gt;            end,&lt;br /&gt;            NewAccounts = lists:keyreplace(Name, 1, Accounts,&lt;br /&gt;                           NewAccount)&lt;br /&gt;        end,&lt;br /&gt;        service(NewAccounts);&lt;br /&gt;    Operation == new -&gt;&lt;br /&gt;        {ok, [Name|_]} = io:fread("Name: ", "~s"),&lt;br /&gt;        case lists:keymember(Name, 1, Accounts) of&lt;br /&gt;        true -&gt;&lt;br /&gt;            NewAccounts = Accounts,&lt;br /&gt;            io:format("Error: account already exist.~n");&lt;br /&gt;        false -&gt;&lt;br /&gt;            NewAccounts = [{Name, 0} | Accounts]&lt;br /&gt;        end,&lt;br /&gt;        service(NewAccounts);&lt;br /&gt;    Operation == print -&gt;&lt;br /&gt;        lists:foreach(fun print_account/1, Accounts),&lt;br /&gt;        service(Accounts);&lt;br /&gt;    Operation == exit -&gt;&lt;br /&gt;        ok;&lt;br /&gt;    true -&gt;&lt;br /&gt;        io:format("Error: unknown operation~n"),&lt;br /&gt;        service(Accounts)&lt;br /&gt;    end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Notes: &lt;br /&gt;&lt;ul id="vwzp2"&gt;&lt;li id="vwzp3"&gt;In functional programming language, instead of updating object (value) in-place, every time a new object (value) is constructed. In example above, in C, deposit() change account-&amp;gt;remain directly, while in erlang, a new account is constructed and returned. &lt;/li&gt;&lt;li id="f4tu0"&gt;If data of program is organized in a hierarchical way, to change the data in leaf, in command language, only the leaf is changed in place; in functional language, all data structure from that leaf to root will be reconstructed. In example above, in C, during deposit operation, only the corresponding account object is changed in-place, while in erlang, both corresponding account object and the whole account list will be re-constructed. With the help of carefully designed implementation, althought the performance of that in functional language is wrose, it is not so bad as it appears. &lt;/li&gt;&lt;li id="ts7c"&gt;In functional programming language, instead of updating the binding of variable name to new value directly, a new scope is constructed and in the new scope, same variable name is binded to a new value. In example above, during "new" operation, accounts may be bind to a new value, in erlang, a new scope is constructed by "recursing", that is, the new constructed account list is bind to Accounts in a new scope. Thanks to the "tail recursing" optimization, the performance is not so bad.&lt;/li&gt;&lt;/ul&gt;  Questions: &lt;ul id="zr0a1"&gt;&lt;li id="zr0a2"&gt;How to shared objects in functional programming language? Such as in a database system, the cached database table should be shared between service threads. &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/661364275739764944-4796164445177450884?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/4796164445177450884/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=4796164445177450884' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/4796164445177450884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/4796164445177450884'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2008/07/no-state-updating-functional.html' title='No state updating: functional language'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-883157884392399877</id><published>2007-04-28T00:25:00.000-07:00</published><updated>2007-05-19T08:32:24.682-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OS'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>OS as parallel system</title><content type='html'>    &lt;ol&gt;   &lt;li&gt;     There are subsystems as following in Linux kernel   &lt;ul&gt;     &lt;li&gt;       process management (virtual memory system, kernel entry point)     &lt;/li&gt;     &lt;li&gt;       physical memory management system     &lt;/li&gt;     &lt;li&gt;       file system     &lt;/li&gt;     &lt;li&gt;       device driver, device management     &lt;/li&gt;     &lt;li&gt;       network system     &lt;/li&gt;   &lt;/ul&gt;   &lt;/li&gt;   &lt;li&gt;     The subsystems in Linux kernel like the "server" in micro-kernel operating     system. They can be seen as multi-thread server too. Although the Linux kernel provides multi-process environment for user space, the kernel itself should be seen as a multi-thread program, because everything is shared.&lt;br&gt;&lt;/li&gt;   &lt;li&gt;     Most resources are not shared between processes in process management     system, i.e., the virtual memory system is not shared between processes,     while they are shared between threads.   &lt;/li&gt;   &lt;li&gt;     Process/thread is used as one of the parallel roles, the other parallel     roles include IRQ handler, softirq, tasklet, work queue, timer operations.     The subsystems in Linux kernel can be seen as multi-thread server system.   &lt;/li&gt;   &lt;li&gt;     If multiple threads access different objects, such as the different file,     there will be no conflict.   &lt;/li&gt;   &lt;li&gt;     Copy, cache, transaction technologies in parallel system can be used in Linux kernel     too, such as the per CPU cache in slab subsystem.&lt;br&gt;   &lt;/li&gt; &lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-883157884392399877?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/883157884392399877/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=883157884392399877' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/883157884392399877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/883157884392399877'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2007/04/there-are-subsystems-as-following-in.html' title='OS as parallel system'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-999916323292712920</id><published>2007-04-28T00:03:00.000-07:00</published><updated>2007-04-28T00:32:30.988-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OS'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Scheduler for all "threads"</title><content type='html'>In operating system, not only the traditional process and thread are schedule-able entities, but also the IRQ handler, software IRQ, tasklet, timer operations and work queue should be the schedule-able entities too, conceptually.&lt;br&gt;&lt;br&gt;Some threads can have higher priority than some tasklets, so, it can preempt these tasklets. It can even have higher priority than some IRQ handler, so that the IRQ is not serviced during thread executing. I think this is a useful concept in real-time system. I think the thread-style IRQ handing in FreeBSD maybe follow the same concept.&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-999916323292712920?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/999916323292712920/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=999916323292712920' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/999916323292712920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/999916323292712920'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2007/04/in-operating-system-not-only.html' title='Scheduler for all &quot;threads&quot;'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-4791763028445679161</id><published>2007-04-28T00:02:00.001-07:00</published><updated>2007-04-28T00:33:43.541-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><title type='text'>Video pipeline</title><content type='html'>&lt;ol&gt;   &lt;li&gt;     Video capture   &lt;/li&gt;   &lt;ol&gt;     &lt;li&gt;       Analog video &lt;br&gt;&lt;/li&gt;          &lt;ol&gt;&lt;li&gt;Tuner&lt;br&gt;&lt;/li&gt;&lt;li&gt;       ADC     &lt;/li&gt;&lt;li&gt;       Analog video decoder (PAL, NTSC)&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Digital video&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Digital tuner&lt;/li&gt;&lt;li&gt;Demodulating&lt;/li&gt;&lt;li&gt;Demux&lt;/li&gt;&lt;li&gt;Decoder&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;   &lt;/ol&gt;   &lt;li&gt;     Video processing&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Video clip&lt;br&gt;&lt;/li&gt;&lt;li&gt;Video scaling&lt;/li&gt;&lt;li&gt;Video scan type/scan rate conversion&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Frame/field rate conversion&lt;/li&gt;&lt;li&gt;Interleaved -&amp;gt; progressive, progressive -&amp;gt; interleaved&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Color space conversion&lt;/li&gt;&lt;ol&gt;&lt;li&gt;RGB -&amp;gt; YUV&lt;/li&gt;&lt;li&gt;YUV -&amp;gt; RGB&lt;/li&gt;&lt;li&gt;Brightness, contrast, Hue/Tint, color temperature conversion&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Video enhancement&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Histogram equilization&lt;/li&gt;&lt;li&gt;Flesh tone correction&lt;/li&gt;&lt;li&gt;Noise reduction&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Video blending&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Chroma keying&lt;/li&gt;&lt;li&gt;video mixer&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;   &lt;li&gt;     Video display&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Gamma correction&lt;/li&gt;&lt;li&gt;Converting to panel signal format (Panel timing control)&lt;br&gt;&lt;/li&gt;&lt;/ol&gt; &lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-4791763028445679161?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/4791763028445679161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=4791763028445679161' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/4791763028445679161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/4791763028445679161'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2007/04/video-capture-analog-video-tuner-adc.html' title='Video pipeline'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-285243055091638873</id><published>2007-04-28T00:02:00.000-07:00</published><updated>2007-04-28T00:13:36.950-07:00</updated><title type='text'>Cancelable operations</title><content type='html'>There are many cancelable operations in software system with user interaction, such as cancel auto tunning in TV. The implementation mechanisms of cancelable operations are as follow:&lt;br/&gt; &lt;br/&gt; &lt;ol&gt;   &lt;li&gt;     message&lt;br/&gt;     The "cancel" message is sent to thread which do long-time job if necessary.     While the function which do long-time job must check whether there are     "cancel" message received, if so, the function must stop working and return.&lt;br/&gt;     &lt;br/&gt;     Cons:&lt;br/&gt;     &lt;ul&gt;       &lt;li&gt;         It isn't native programming model in Linux/Unix, so third party software         will not use it.       &lt;/li&gt;       &lt;li&gt;         Can't cancel work in kernel (for example the sleep or block read can not         be interrupted)&lt;br/&gt;       &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;   &lt;li&gt;     signal / real time signal&lt;br/&gt;     The "cancel" signal is sent to thread which do long-time job if neccesary.     Upon the signal is received, the blocked operation (such as sleep, blocked     read, etc) will be interrupted and a signal action function will be called     which set a flag to indicate the canel signal is received by the thread. The     function which do long-time job must check the flag to see whether there are     "cancel" signal received, if so, the function must stop working and return.&lt;br/&gt;     &lt;br/&gt;     Pros:&lt;br/&gt;     &lt;ul&gt;       &lt;li&gt;         Native programming model in Linux/Unix, easy to cooperate with third         party software.       &lt;/li&gt;       &lt;li&gt;         Can cancel work in kernel.&lt;br/&gt;       &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ol&gt; &lt;br/&gt; Problems:&lt;br/&gt; &lt;ul&gt;   &lt;li&gt;     race conditions !!!   &lt;/li&gt; &lt;/ul&gt; &lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-285243055091638873?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/285243055091638873/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=285243055091638873' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/285243055091638873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/285243055091638873'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2007/04/there-are-many-cancelable-operations-in.html' title='Cancelable operations'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-2824183080942243831</id><published>2007-04-27T23:40:00.000-07:00</published><updated>2007-04-27T23:40:56.666-07:00</updated><title type='text'>Message mechanism implementation in POSIX system</title><content type='html'>&lt;p&gt;   The message mechanism is widely used for inter-thread (process) communication.   Some implementation mechanisms of message are as follow: &lt;br&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt; &lt;ol&gt;   &lt;li&gt;     pipe (anonymous or named)     &lt;ul&gt;       &lt;li&gt;         Pros:         &lt;ul&gt;           &lt;li&gt;             Can be used for inter-process and inter-thread message           &lt;/li&gt;           &lt;li&gt;             Can suspend on get message (desired)           &lt;/li&gt;           &lt;li&gt;             Support non-block operation           &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;       &lt;li&gt;         Cons:         &lt;ul&gt;           &lt;li&gt;             Can not support message priority           &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;   &lt;li&gt;     Socket (stream or datagram)&lt;br&gt;     Used by X Window system message system. Almost same as pipe, with following     additional pros and cons     &lt;ul&gt;       &lt;li&gt;         Pros:         &lt;ul&gt;           &lt;li&gt;             Can be used in network environment (not important now)           &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;       &lt;li&gt;         Cons:         &lt;ul&gt;           &lt;li&gt;             Need kernel networking support.           &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;   &lt;li&gt;     POSIX message queue     &lt;ul&gt;       &lt;li&gt;         Pros:         &lt;ul&gt;           &lt;li&gt;             Can be used for inter-process and inter-thread message           &lt;/li&gt;           &lt;li&gt;             Can suspend on get message (desired)           &lt;/li&gt;           &lt;li&gt;             Support time out           &lt;/li&gt;           &lt;li&gt;             Support message priority           &lt;/li&gt;           &lt;li&gt;             Support non-block operation           &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;       &lt;li&gt;         Cons:         &lt;ul&gt;           &lt;li&gt;             Need new kernel (&amp;gt; 2.6.6)           &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;   &lt;li&gt;     SysV message queue &lt;ul&gt;   &lt;li&gt;     Pros: &lt;ul&gt;   &lt;li&gt;     Can be used for inter-process and inter-thread message   &lt;/li&gt;   &lt;li&gt;     Can suspend on get message (desired)   &lt;/li&gt;   &lt;li&gt;     Support message priority   &lt;/li&gt;   &lt;li&gt;     Support non-block operation   &lt;/li&gt; &lt;/ul&gt;   &lt;/li&gt;&lt;li&gt;     Cons:   &lt;/li&gt;    &lt;/ul&gt;   &lt;/li&gt; &lt;/ol&gt;&lt;br&gt;Conclusion:&lt;br&gt; &lt;ul&gt;   &lt;li&gt;     The function of mechanisms above is almost same, the POSIX message queue or     SysV message queue is preferred if available because they are more similar     to message then need less implementation effort.   &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/661364275739764944-2824183080942243831?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/2824183080942243831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=2824183080942243831' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/2824183080942243831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/2824183080942243831'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2007/04/message-mechanism-is-widely-used-for.html' title='Message mechanism implementation in POSIX system'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-119191880170587856</id><published>2007-04-27T20:38:00.000-07:00</published><updated>2007-04-27T20:42:39.811-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Embedded'/><title type='text'>Simple component system for embedded system</title><content type='html'>&lt;h3&gt;   1. Objective &lt;/h3&gt; &lt;ul&gt;   &lt;li&gt;     Separate interface and implementation     &lt;ul&gt;       &lt;li&gt;         User depends on only interface not implementation, the implementation         can evolve without breaking user.       &lt;/li&gt;       &lt;li&gt;         User can use several implementation of one interface simultaneously.       &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;   &lt;li&gt;     Modular     &lt;ul&gt;       &lt;li&gt;         Component is a special module, more modular.       &lt;/li&gt;       &lt;li&gt;         Manage the dependency relationship of software modules.       &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;   &lt;li&gt;     Testable     &lt;ul&gt;       &lt;li&gt;         The component is the test unit.       &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;   &lt;li&gt;     Position transparent (single-thread/multi-thread transparent)     &lt;ul&gt;       &lt;li&gt;         local/remote, same thread/different thread transparent       &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt; &lt;h3&gt;   2. Interface &lt;/h3&gt; &lt;ul&gt;   &lt;li&gt;     Describe in IDL formally: language neutral   &lt;/li&gt;   &lt;li&gt;     Binary standard: vtable   &lt;/li&gt;   &lt;li&gt;     Implementation in C: function pointer structure     &lt;pre&gt;typedef struct&lt;br&gt;{&lt;br&gt;    void (*dvFooInit)(dvFooIntf intf);&lt;br&gt;    void (*dvFooDestroy)(dvFooIntf intf,&lt;br&gt;        FOO_DESCRIPTION sFooDesc);&lt;br&gt;    void (*dvFooBarEnable)(dvFooIntf intf, BOOL bEnable);&lt;br&gt;    ...&lt;br&gt;} dvFooOps;&lt;br&gt;&lt;br&gt;typedef struct&lt;br&gt;{&lt;br&gt;    dvFooOps *ops;&lt;br&gt;} dvFoo;&lt;br&gt;&lt;br&gt;typedef dvFoo *dvFooIntf;&lt;/pre&gt;   &lt;/li&gt;   &lt;li&gt;     Implementation in C++: class with only pure virtual method     &lt;pre&gt;class dvFoo&lt;br&gt;{&lt;br&gt;public:&lt;br&gt;    virtual void dvFooInit(void) = 0;&lt;br&gt;    virtual int32 dvFooDesctroy(FOO_DESCRIPTION desc) = 0;&lt;br&gt;    virtual void dvFooBarEnable(BOOL bEnable) = 0;&lt;br&gt;    ...&lt;br&gt;};&lt;br&gt;&lt;br&gt;typedef dvFoo *dvFooIntf;&lt;br&gt;&lt;/pre&gt;   &lt;/li&gt;   &lt;li&gt;     A tool can be developed to generate C++ and C implementation of interface     from IDL automatically.&lt;br&gt;   &lt;/li&gt; &lt;/ul&gt; &lt;h3&gt;   3. Component (object) &lt;/h3&gt; &lt;ul&gt;   &lt;li&gt;     Properties:     &lt;ul&gt;       &lt;li&gt;         Software module that implement one or several interfaces. The interfaces         is the API of component and should be stable.       &lt;/li&gt;       &lt;li&gt;         The source code, document, configuration information, test code of         component is organized in individual folder.       &lt;/li&gt;       &lt;li&gt;         Every component has its own version number and can evolve individually.       &lt;/li&gt;       &lt;li&gt;         Can be selected and configured via a configuration tool.       &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;   &lt;li&gt;     Implementation     &lt;ul&gt;       &lt;li&gt;         Implementation in C: fill function pointer structure         &lt;pre&gt;dvFooOps opsfoo = {&lt;br&gt;    dvLisaFooInit,&lt;br&gt;    dvLisaFooDesctory,&lt;br&gt;    dvLisaFooBarEnable,&lt;br&gt;    ...&lt;br&gt;};&lt;br&gt;&lt;br&gt;typedef struct&lt;br&gt;{&lt;br&gt;    dvFooOps *ops;&lt;br&gt;    /* data members for Lisa */&lt;br&gt;} dvLisaFoo;&lt;br&gt;&lt;br&gt;dvLisaFoo foo = {&lt;br&gt;    &amp;amp;opsfoo,&lt;br&gt;    /* data members for Lisa */&lt;br&gt;};&lt;/pre&gt;         For driver implementation, instance number can be used as the data         member.       &lt;/li&gt;       &lt;li&gt;         Implementation in C++: inherit implemented interfaces         &lt;pre&gt;class dvLisaFoo : public dvFoo&lt;br&gt;{&lt;br&gt;    /* data members for Lisa */&lt;br&gt;public:&lt;br&gt;    void dvFooInit(void);&lt;br&gt;    int32 dvFooDestroy(FOO_DESCRIPTION desc);&lt;br&gt;    void dvFooBarEnable(BOOL bEnable);&lt;br&gt;    ...&lt;br&gt;};&lt;/pre&gt;         For driver implementation, instance number can be used as the data         member.       &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt; &lt;h3&gt;   4. Usage &lt;/h3&gt; After getting the pointer to the interface of the component, user of component can use the component via direct function call without need to know the implementation of component. (C user can use C++ implementation).  &lt;pre&gt;#define dvFooInit(intf) (intf)-&amp;gt;ops-&amp;gt;dvFooInit((intf))&lt;br&gt;#define dvFooDestroy(intf, sFooDesc) &lt;br&gt;    (intf)-&amp;gt;ops-&amp;gt;dvFooDesctroy((intf), (sFooDesc))&lt;br&gt;&lt;br&gt;dvFooIntf intf;&lt;br&gt;/* Get interface */&lt;br&gt;dvFooInit(intf);&lt;br&gt;dvFooDestroy(intf, sFooDesc);&lt;br&gt;&lt;/pre&gt; &lt;h3&gt;   5. Inter-thread (inter-process) component &lt;/h3&gt; If the the user and implementer of component is resided in different thread (or process), it is not sufficient to use direct function call simply. To use component across thread (process), the following mechanism is provided.&lt;br&gt;&lt;ul&gt;&lt;li&gt;A proxy is provided in user thread (process), which is the representative of the component which implemented in different thread (process). The user can use the proxy in same way of component in single thread environment. The proxy implement the interface with inter-thread (inter-process) communication (such as message sending and receiving).&lt;/li&gt;&lt;li&gt;A stub is provided in implementation thread (process), which is the representative of the user which is in different thread (process). The stub use the component in the same way of user in single thread environment. The stub simulate the user with inter-thread (inter-process) communication (such as message receiving and sending).&lt;/li&gt;&lt;li&gt;A simple implementation of inter-thread inter-process provides a simple mutual exclusion resolution like crude force serialization between all functions of one component.&lt;/li&gt;&lt;li&gt;In implementation, the implementing thread id can be used in proxy as the data member.&lt;/li&gt;&lt;li&gt;A tool can be developed to generate proxy and stub implementation of interface from IDL automatically.&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;   6. Component manager (component directory/component factory) &lt;/h3&gt; In order to get the interface of component, a component manager should be provided. The simplest component manager is as follow:&lt;br&gt;&lt;ul&gt;&lt;li&gt;Create all components before using components. Such as, all device driver components are created using the source code generated by configuration tool. All middleware components are created using the source code generated by configuration tool too.&lt;/li&gt;&lt;li&gt;Component managers have lists of all components of system. Such as the device driver manager has the list of all device driver components.&lt;/li&gt;&lt;li&gt;Component manager provide a interface to get the interfaces of components. Such as all the interfaces of device driver components can be gotten from device driver manager.&lt;/li&gt;&lt;li&gt;For inter-thread (inter-process) components, the proxy and stub is created before using as that of the component. The proxy instead of component itself is in the list of components in component manager. The user of component will get the proxy, it is desirable.&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/661364275739764944-119191880170587856?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/119191880170587856/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=119191880170587856' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/119191880170587856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/119191880170587856'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2007/04/1.html' title='Simple component system for embedded system'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-8967378765982897962</id><published>2007-04-27T01:27:00.001-07:00</published><updated>2007-04-27T01:30:08.482-07:00</updated><title type='text'>Auto Shanghai 2007</title><content type='html'>Photos of Auto Shanghai 2007: &lt;a href="http://picasaweb.google.com/huang.ying.caritas/AutoShanghai2007"&gt;http://picasaweb.google.com/huang.ying.caritas/AutoShanghai2007&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-8967378765982897962?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/8967378765982897962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=8967378765982897962' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/8967378765982897962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/8967378765982897962'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2007/04/auto-shanghai-2007_27.html' title='Auto Shanghai 2007'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-7790905477052699134</id><published>2007-04-15T01:47:00.001-07:00</published><updated>2007-04-15T02:03:07.906-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OS'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>virtualization</title><content type='html'>1. Virtualization level&lt;br /&gt;&lt;br /&gt;a. Timing-accurate virtualization&lt;br /&gt;&lt;br /&gt;The timing logic is simulated by software. It is mainly used for chip&lt;br /&gt;verification. The performance is lowest.&lt;br /&gt;&lt;br /&gt;b. Full virtualization&lt;br /&gt;&lt;br /&gt;It is instruction-accurate CPU virtualization and necessary peripheral&lt;br /&gt;virtualization. The "unmodified" guest operating system can be run on&lt;br /&gt;it.&lt;br /&gt;&lt;br /&gt;Examples: Bochs, Qemu, Skyeye, Xcopilot.&lt;br /&gt;&lt;br /&gt;c. Para-virtualization&lt;br /&gt;&lt;br /&gt;It is instruction-accurate CPU virtualization and necessary peripheral&lt;br /&gt;virtualization but with some modification to real hardware&lt;br /&gt;architecture, so that the guest operating system must be "modified" to&lt;br /&gt;run on it.&lt;br /&gt;&lt;br /&gt;Examples: Xen, UML.&lt;br /&gt;&lt;br /&gt;d. Operating system level virtulization&lt;br /&gt;&lt;br /&gt;Some instruction (most non-privilege instruction) of CPU and the&lt;br /&gt;operating system interface (mostly system call interface) is&lt;br /&gt;virtualized. The target application can be run on it. Same or&lt;br /&gt;different operating system interface as that of host operating system&lt;br /&gt;may be virtualized.&lt;br /&gt;&lt;br /&gt;Examples with same OS interface as that of host OS: Linux vserver,&lt;br /&gt;FreeBSD jail, Qemu user space emulation.&lt;br /&gt;&lt;br /&gt;Examples with different OS interface as that of host OS: Linux binary&lt;br /&gt;compatibility support on FreeBSD, Wine.&lt;br /&gt;&lt;br /&gt;2. Implementation&lt;br /&gt;&lt;br /&gt;a. Hardware based or OS based implementation&lt;br /&gt;&lt;br /&gt;Some virtulization systems work as a user space application (perhaps&lt;br /&gt;with some kernel space components) on a host OS, which are called OS&lt;br /&gt;based implementation, while others work on bare hardware directly,&lt;br /&gt;which are called hardware based implementation.&lt;br /&gt;&lt;br /&gt;b. Interpretation based implementation&lt;br /&gt;&lt;br /&gt;It is mainly used for full virtualization. The core of virtualization&lt;br /&gt;system usually is a loop to fetch an instruction, interpret the&lt;br /&gt;instruction, execute the instruction and advance the PC, perhaps with&lt;br /&gt;some pipeline handling.&lt;br /&gt;&lt;br /&gt;Interpretation based virtualization system is usually good on&lt;br /&gt;portability, if it is programmed in portable language.&lt;br /&gt;&lt;br /&gt;Example: Bochs, Skyeye, Xcopilot&lt;br /&gt;&lt;br /&gt;c. Dynamic translation based implementation&lt;br /&gt;&lt;br /&gt;In dynamic translation based virtualization system, the target binary&lt;br /&gt;code is translated into host binary code first, then the translated&lt;br /&gt;code is executed on host CPU directly.&lt;br /&gt;&lt;br /&gt;In general, its performance is better than interpretation based&lt;br /&gt;implementation with good portability.&lt;br /&gt;&lt;br /&gt;It can be used for full virtualization, in which, both the kernel&lt;br /&gt;space code and user space code is translated before execution. It can&lt;br /&gt;also be used for operating system level virtualization, in which, only&lt;br /&gt;the user space code is translated and the OS interface (system call)&lt;br /&gt;is implemented through calling the host system OS interface directly.&lt;br /&gt;&lt;br /&gt;Examples: Qemu, Qemu user space virtualization.&lt;br /&gt;&lt;br /&gt;d. Monitor based implementation&lt;br /&gt;&lt;br /&gt;In monitor based virtualization system, the target CPU must be same as&lt;br /&gt;host CPU. The target code is executed on host CPU directly but usually&lt;br /&gt;with lower priority. Some privileged instruction or some resource&lt;br /&gt;access will trap into monitor, which usually is executed with highest&lt;br /&gt;priority, then, the monitor do some check and complete the privileged&lt;br /&gt;operation or resource access for target code and return to guest code.&lt;br /&gt;&lt;br /&gt;Its performance can reach nearly native, but its main constraint is&lt;br /&gt;that the guest CPU must be same as the host CPU.&lt;br /&gt;&lt;br /&gt;Examples: KQemu.&lt;br /&gt;&lt;br /&gt;e. Para-virtualization implementation&lt;br /&gt;&lt;br /&gt;On para-virtualization system, the "unmodified" guest code can not be&lt;br /&gt;run directly. Instead, usually the guest OS must be "modified" to be&lt;br /&gt;implemented based on para-virtualization system instead of real&lt;br /&gt;hardware. Some privileged operation or resource access are done&lt;br /&gt;through calling the para-virtualization system instead of direct&lt;br /&gt;hardware programming.&lt;br /&gt;&lt;br /&gt;Examples: Xen, UML, coLinux.&lt;br /&gt;&lt;br /&gt;f. Implement the API of another OS in user space&lt;br /&gt;&lt;br /&gt;This can be used for operating system level virtualization.&lt;br /&gt;&lt;br /&gt;Examples: wine.&lt;br /&gt;&lt;br /&gt;g. Implement the system call of another OS in kernel space&lt;br /&gt;&lt;br /&gt;This can be used for operating system level virtualization.&lt;br /&gt;&lt;br /&gt;Examples: Linux binary compatibility support on FreeBSD.&lt;br /&gt;&lt;br /&gt;h. Partition resources between processes&lt;br /&gt;&lt;br /&gt;Some resources such as file system, CPU time, network address and&lt;br /&gt;memory is partitioned between processes. Such that, some processes&lt;br /&gt;works on the restricted resources only.&lt;br /&gt;&lt;br /&gt;Examples: Linux vserver, FreeBSD jail.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-7790905477052699134?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/7790905477052699134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=7790905477052699134' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/7790905477052699134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/7790905477052699134'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2007/04/virtualization_15.html' title='virtualization'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-5933305898167813015</id><published>2007-01-30T07:23:00.000-08:00</published><updated>2007-01-30T07:28:07.740-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GTK'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Embedded'/><title type='text'>GTK+ Map Viewer</title><content type='html'>Recently, I developed a simple map viewer for my Zaurus with GTK+.&lt;br /&gt;&lt;br /&gt;Because most map image file is very big, from several MB to tens MB, it is very inconvenient to view map with ordinary image viewer, especially for embedded system like PDA and mobile phone.&lt;br /&gt;&lt;br /&gt;This program is developed to facilitate map viewing, the basic idea behind it is:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The big map image file is splitted into many small image files, loaded on demand to reduce memory requirement.&lt;/li&gt;&lt;li&gt;The big map image file is pre-scaled too, because scaling a big image file is also a memory/CPU hungry task.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Some other useful feature for a map viewer is also provided. For example, personal marks can be added to a map. A map making tools is also provided to facilitate splitting and scaling the big map image file.&lt;br /&gt;&lt;br /&gt;The source code of the program can be download from:&lt;br /&gt;&lt;span class="q" id="q_1107396adf97625c_4"&gt;&lt;/span&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://linux-mcr700.sourceforge.net/gviewmap-0.1.tar.gz" target="_blank"&gt;http://linux-mcr700.sourceforg&lt;wbr&gt;e.net/gviewmap-0.1.tar.gz&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-5933305898167813015?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/5933305898167813015/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=5933305898167813015' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/5933305898167813015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/5933305898167813015'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2007/01/gtk-map-viewer.html' title='GTK+ Map Viewer'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-7432381045484270088</id><published>2007-01-29T06:31:00.000-08:00</published><updated>2007-04-27T20:42:39.811-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OS'/><category scheme='http://www.blogger.com/atom/ns#' term='Embedded'/><title type='text'>Stack-less multi-task system (2) -- implementation</title><content type='html'>&lt;span style="font-weight: bold;"&gt;The basic idea behind implementation:&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Replace implicit C stack with explict link stack.&lt;/li&gt;&lt;li&gt;Use label to record PC.&lt;/li&gt;&lt;li&gt;Store task state in heap instead of stack.&lt;/li&gt;&lt;li&gt;Only functions will sleep directly or indirectly need to deal with stack explictly, other functions aren't affected.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Performance comparison:&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Task stack space is saved, only one stack is needed.&lt;/li&gt;&lt;li&gt;Task switching time may be a little longer because of task swithing executing path will go through all functions invoked before sleep. But, if the task is small enough and function invoking depth is short, the task switching time will be affordable.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Sample Code:&lt;/span&gt;&lt;pre&gt;&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;#include &amp;lt;string.h&amp;gt;&lt;br /&gt;&lt;br /&gt;struct stack&lt;br /&gt;{&lt;br /&gt; short   stk_label;&lt;br /&gt; void    *stk_data;&lt;br /&gt; struct stack *stk_prev;&lt;br /&gt; struct stack *stk_next;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;#define TASK_STATE_RUN         0&lt;br /&gt;#define TASK_STATE_SLEEP       1&lt;br /&gt;&lt;br /&gt;struct task&lt;br /&gt;{&lt;br /&gt; short    tsk_state;&lt;br /&gt; void     (*tsk_entry)(void);&lt;br /&gt; struct stack tsk_stk;&lt;br /&gt; struct stack *tsk_stk_curr;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;extern struct task tasks[];&lt;br /&gt;struct task *task_curr;&lt;br /&gt;&lt;br /&gt;void sleep(void)&lt;br /&gt;{&lt;br /&gt; task_curr-&gt;tsk_state = TASK_STATE_SLEEP;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void wakeup(int task_id)&lt;br /&gt;{&lt;br /&gt; tasks[task_id].tsk_state = TASK_STATE_RUN;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/* return code */&lt;br /&gt;#define RC_SUCCESS    0&lt;br /&gt;#define RC_FAILED     1&lt;br /&gt;#define RC_PENDING    2&lt;br /&gt;&lt;br /&gt;void push_stack()&lt;br /&gt;{&lt;br /&gt; if (!task_curr-&gt;tsk_stk_curr-&gt;stk_next) {&lt;br /&gt;  struct stack *stk;&lt;br /&gt;&lt;br /&gt;  stk = malloc(sizeof(struct stack));&lt;br /&gt;  assert(stk);&lt;br /&gt;  memset(stk, 0, sizeof(*stk));&lt;br /&gt;  stk-&gt;stk_prev = task_curr-&gt;tsk_stk_curr;&lt;br /&gt;  task_curr-&gt;tsk_stk_curr-&gt;stk_next = stk;&lt;br /&gt; }&lt;br /&gt; task_curr-&gt;tsk_stk_curr = task_curr-&gt;tsk_stk_curr-&gt;stk_next;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void pop_stack()&lt;br /&gt;{&lt;br /&gt; struct stack *stk;&lt;br /&gt;&lt;br /&gt; stk = task_curr-&gt;tsk_stk_curr-&gt;stk_prev;&lt;br /&gt; assert(stk-&gt;stk_next-&gt;stk_next == NULL);&lt;br /&gt; free(stk-&gt;stk_next);&lt;br /&gt; stk-&gt;stk_next = NULL;&lt;br /&gt; task_curr-&gt;tsk_stk_curr = stk;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#define TEST_TASK_LABEL1    0&lt;br /&gt;#define TEST_TASK_LABEL2    1&lt;br /&gt;#define TEST_TASK_LABEL3    2&lt;br /&gt;&lt;br /&gt;#define TEST_TASK_SUB_LABEL1   0&lt;br /&gt;#define TEST_TASK_SUB_LABEL2   1&lt;br /&gt;&lt;br /&gt;void test_task_label1(void)&lt;br /&gt;{&lt;br /&gt; /* everything as normal, without sleep */&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int test_task_label2(void)&lt;br /&gt;{&lt;br /&gt; int rc = RC_SUCCESS;&lt;br /&gt;&lt;br /&gt; push_stack();&lt;br /&gt;&lt;br /&gt; switch (task_curr-&gt;tsk_stk_curr-&gt;stk_label) {&lt;br /&gt; case TEST_TASK_SUB_LABEL1:&lt;br /&gt;  task_curr-&gt;tsk_stk_curr-&gt;stk_label = TEST_TASK_SUB_LABEL2;&lt;br /&gt;  rc = RC_PENDING;&lt;br /&gt;  sleep();&lt;br /&gt;  break;&lt;br /&gt; case TEST_TASK_SUB_LABEL2:&lt;br /&gt;  break;&lt;br /&gt; }&lt;br /&gt; if (rc != RC_PENDING)&lt;br /&gt;  pop_stack();&lt;br /&gt; return rc;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void test_task(void)&lt;br /&gt;{&lt;br /&gt; switch (task_curr-&gt;tsk_stk.stk_label) {&lt;br /&gt; case TEST_TASK_LABEL1:&lt;br /&gt;  test_task_label1();&lt;br /&gt;  task_curr-&gt;tsk_stk.stk_label = TEST_TASK_LABEL2;&lt;br /&gt;  task_curr-&gt;tsk_stk.stk_data = malloc(10);&lt;br /&gt;  sleep();&lt;br /&gt;  break;&lt;br /&gt; case TEST_TASK_LABEL2:&lt;br /&gt;  if (test_task_label2() == RC_PENDING) {&lt;br /&gt;   break;&lt;br /&gt;  }&lt;br /&gt;  task_curr-&gt;tsk_stk.stk_label = TEST_TASK_LABEL3;&lt;br /&gt; case TEST_TASK_LABEL3:&lt;br /&gt;  break;&lt;br /&gt; default:&lt;br /&gt;  assert(0);&lt;br /&gt;  break;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void test_task2(void)&lt;br /&gt;{&lt;br /&gt; wakeup(0);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;struct task tasks[2] =&lt;br /&gt;{&lt;br /&gt; {&lt;br /&gt;  TASK_STATE_RUN,&lt;br /&gt;  test_task,&lt;br /&gt;  { 0, NULL, NULL, NULL },&lt;br /&gt;  NULL,&lt;br /&gt; },&lt;br /&gt; {&lt;br /&gt;  TASK_STATE_RUN,&lt;br /&gt;  test_task2,&lt;br /&gt;  { 0, NULL, NULL, NULL},&lt;br /&gt;  NULL,&lt;br /&gt; },&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;void schedule(void)&lt;br /&gt;{&lt;br /&gt; int i;&lt;br /&gt;&lt;br /&gt; for (i = 0; i &amp;lt; 2; i++) {&lt;br /&gt;  if (tasks[i].tsk_state == TASK_STATE_RUN) {&lt;br /&gt;   task_curr = &amp;tasks[i];&lt;br /&gt;   task_curr-&gt;tsk_stk_curr = &amp;task_curr-&gt;tsk_stk;&lt;br /&gt;   tasks[i].tsk_entry();&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt; for (;;)&lt;br /&gt;  schedule();&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/string.h&gt;&lt;/assert.h&gt;&lt;/stdlib.h&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-7432381045484270088?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/7432381045484270088/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=7432381045484270088' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/7432381045484270088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/7432381045484270088'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2007/01/stack-less-multi-task-system-2.html' title='Stack-less multi-task system (2) -- implementation'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-7604059437374608754</id><published>2007-01-14T05:41:00.000-08:00</published><updated>2007-04-27T20:42:39.812-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OS'/><category scheme='http://www.blogger.com/atom/ns#' term='Embedded'/><title type='text'>Stack-less multi-task system</title><content type='html'>&lt;span style="font-size:100%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:MS Sans Serif;"&gt;In traditional multi-task operating system, there is one stack for one task. The stack is mainly used for storing call chain, function parameters and local variables, that is, the context of the task. When task is switched, the stack of task is switched too.&lt;br /&gt;&lt;br /&gt;The problem of stack based multi-task system is the size of stack should be the maximum possible size that the stack maybe grow to. In Linux system, the size of kernel task stack is 4kB or 8kB. But, in 99% condition, only small part of whole stack is used. The efficiency of stack memory usage is low.&lt;br /&gt;&lt;br /&gt;Another solution is that all tasks share the same stack. When task is executed, the stack is used for storing call chain, function parameters and local variables as that of task based multi-task. When task is about to be switched out of CPU, it saves all state (context) needed to continue the work elsewhere (such as global variable, malloced memory) and hands the stack to the task to be switched into CPU. The new task will ruin all the contents in the stack and use it exclusively until the next switching.&lt;br /&gt;&lt;br /&gt;The problem of stack-less multi-task system is that when switching point is deeply nested, it is hard to storing all state needed in a modular way. For example, when a "page fault" occurs in a memory mapped page, the handler will go through memory subsystem and file system and maybe be switched out of CPU for waiting for disk reading. How can the task save the state of memory subsystem and file system in a modular way? So, the stack-less multi-task system is used mainly in the kernel of micro-kernel operating system, because there are only few simple subsystems, the state saving can be done in a modular or manageable way.&lt;br /&gt;&lt;br /&gt;A resolution is adaptive stack scheme. If task is working for a system call that have very small stack usage (such as the wait in POSIX), all the state needed is stored elsewhere and the stack is freed, otherwise the stack is preserved. But this resolution is not very effective if most system calls use more stack.&lt;br /&gt;&lt;br /&gt;I think another possible resolution is split task into more small tasks. Because every task is so small, its state can be stored without refer to other subsystem, that is in a modular way. And because the overhead of task is much less than before, the total overhead is not too much. Perhaps one small task corresponds one subsystem in traditional system. For example, the memory system, file system can be tasks too. In this system, create a process turns to create several tasks.&lt;br /&gt;&lt;br /&gt;&lt;/span&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/661364275739764944-7604059437374608754?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/7604059437374608754/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=7604059437374608754' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/7604059437374608754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/7604059437374608754'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2007/01/stack-less-multi-task-system.html' title='Stack-less multi-task system'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-661364275739764944.post-8448692477639856822</id><published>2006-12-05T05:35:00.000-08:00</published><updated>2007-04-28T19:25:13.673-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='OS'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Gadmei UTV 330 on Linux</title><content type='html'>Recently, I bought a Gadmei UTV 330 USB TV Box. Because I want to know more about video capturing while it is the cheapest USB TV Box I can find.&lt;br /&gt;&lt;br /&gt;The basic hardware information is as follow (gotten from V4L wiki: http://www.linuxtv.org/v4lwiki/index.php/Em2820/gadmei_utv_310 and driver log information (dmesg)):&lt;br /&gt;&lt;br /&gt;Tuner: TNF 5323&lt;br /&gt;Decoder: Philip SAA7113&lt;br /&gt;USB bridge: Empia em2860&lt;br /&gt;&lt;br /&gt;Thanks the great work of V4L guys, the card almost works out of box. It can be recognized correctly under Linux and accept NTSC video input. But the TV broadcast standard used in my country is PAL, so I added the PAL standard to card configuration in driver, and it works for PAL video immediately. The data driven design makes adding new card support so easy.&lt;br /&gt;&lt;br /&gt;The sound and IR doesn't work out of box, and Gadmei corporation doesn't release hardware specification, so the work method to add sound and IR support is to do USB snooping under Windows.&lt;br /&gt;&lt;br /&gt;After reviewing the USB standard and studying the source code of existing driver, adding sound and IR support is a fairly easy work.&lt;br /&gt;&lt;br /&gt;The sound control is through register 0x08 of em2860, the effect of different value is as follow:&lt;br /&gt;&lt;br /&gt;0xfc: switch to line in (composite video or svideo)&lt;br /&gt;0xfd: switch to tuner&lt;br /&gt;0xfe: turn off sound&lt;br /&gt;&lt;br /&gt;The IR is turn on through writing 0x07 to register 0x0f. The key press and release are gotten through pulling register 0x45 periodically. The only remaining thing is a correct key map.&lt;br /&gt;&lt;br /&gt;The maintainer of em28xx driver is Markus Rechberger. It is very kind of him to review and revise my patch.&lt;br /&gt;&lt;br /&gt;Many USB TV Box is based on Empia em28xx series chip. The em28xx driver information can be found on V4L wiki: http://www.linuxtv.org/v4lwiki/index.php/Em2880.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/661364275739764944-8448692477639856822?l=caritas-space.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caritas-space.blogspot.com/feeds/8448692477639856822/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=661364275739764944&amp;postID=8448692477639856822' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/8448692477639856822'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/661364275739764944/posts/default/8448692477639856822'/><link rel='alternate' type='text/html' href='http://caritas-space.blogspot.com/2006/12/gadmei-utv-330-on-linux.html' title='Gadmei UTV 330 on Linux'/><author><name>caritas</name><uri>http://www.blogger.com/profile/09224216414103167558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://lh6.google.com/image/huang.ying.caritas/RicTf9sf3TI/AAAAAAAAACE/P_ye8IiKEVE/philosophical-gnu-sm-sm.JPG'/></author><thr:total>1</thr:total></entry></feed>
