Hamid Fadishei's Blog

July 9, 2013

iMX233 and Full-disk Encryption of Linux on SD Card

Filed under: Uncategorized — fadishei @ 2:54 pm
Tags: , , ,

After weeks of work, I finally was able to boot my iMX233 ARM processor from a fully encrypted linux partition… and most importantly, I was able to use the hardware-stored encryption key for this purpose. What a pleasure!

iMX233 features a hardware engine (known as DCP) which can perform 128-bit AES encryption using either a software-provided or the hardware-stored key. The latter key is burnt into the CPU’s OTP ROM and can be made totally hidden from software. This adds extra security: cryptography without any chance of revealling the encryption key.

To me, an ultimate disk encryption method for protecting an embedded application is one whose boot procedure does not include any non-encrypted stage. Otherwise, a malicious user can use her own modified version of that non-encrypted stage in order to boot her own code and try to break the encryption key by generating lot of plain/cipher patterns. The first boot stage of iMX233 (booting kernel from first SD partition) can be encrypted using the same OTP key (see elftosb -k parameter). Then the next stage of booting an encrypted Linux from the second partition was what I was looking for.

I had several obstacles to overcome:

  • First of all, I had to write my own version of kernel crypto module that can use the OTP hard-key instead of always expecting a soft-key to be provided [see this quesion].
  • Second, the original dm-crypt essiv IV method was not possible without modification in my case. Why? because it relies on the explicit value of the key for IV generation, and as I said, the key value is burried into hardware fuses and unknown to software.
  • Finally, I needed to add my custom initramfs into my compiled Freescale’s kernel. It is responsible to cryptsetup, mount the encrypted root partition, and switch_root to it.

March 20, 2013

Know The Hardware Crypto Engine of iMX23 ARM9 Platform Better!

Filed under: Uncategorized — fadishei @ 10:55 am
Tags: , , , ,

Introduction

The iMX233 ARM processor from Freescale comes with a Data Coprocessor (DCP) which contains a cryptography acceleration engine. It can offload some hashing/encryption/decryption algorithms from CPU core. Using my iMX233-Olinuxino-Micro board running Arch Linux ARM I am going to shed some light on this part of that processor.

Kernel Drivers

The iMX kernel tree well integrates the engine into standard linux crypto layer (see drivers/crypto/dcp.c, and drivers/crypto/dcp.h). Thus you can inspect what you have by issuing this command from shell and looking for dcp driver names:

> cat /proc/crypto
name         : sha1
driver       : sha1-dcp
module       : kernel
priority     : 300
refcnt       : 1
selftest     : passed
type         : shash
blocksize    : 64
digestsize   : 20

name         : cbc(aes)
driver       : dcp-cbc-aes
module       : kernel
priority     : 400
refcnt       : 1
selftest     : passed
type         : blkcipher
blocksize    : 16
min keysize  : 16
max keysize  : 32
ivsize       : 16
geniv        :

...

Judging from the priority values we can say that hardware accelerated dcp drivers take precedence over generic kernel implementations.

AES with Key in OTP ROM

One scarcely discussed feature that I am going to talk more about is the AES with OTP key. What’s that? iMX233 can perform hardware AES with the encryption key stored somewhere in its One-Time-Programmable (OTP) ROM. This key is not directly accessible by software running on the processor. Running software can only request encryption/decryption of their data without knowing what the key is. You can burn a key specific to each device into OTP and hide it totally by locking the key permanently. Security people know what treasure this feature is!

Manipulating the OTP key

In order to see what the key value of your device is, you’ll need to access the board in recovery mode by connecting your it via USB to a PC running the BitBurner software. The VCC pin of the USB cable needs to be disconnected (Only connect D+, D-, GND) and the SD card should be removed. Then power up the board and select HID device in BitBurner. You will see 4 32-bit ROM words CRYPTO0..CRYPTO3. You can see the current value of the key (the default key value is 0x00000000000000000000000000000000). You can also program your desired key value. But remember! It’s One-Time-Programmable! I haven’t dared enough to program a key myself yet! There are also lock bits that can be set in order to hide the key even from BitBurner. I have’nt dared to play with them either!

Kernel Drivers for AES with OTP Key

Unfortunately, AES with OTP key is not integrated into kernel crypto layer due to its different nature. See drivers/crypto/dcp_bootstream_ioctl.h. The name comes from the fact that Freescale uses this feature mainly for bootstream encryption. The driver provides an IOCTL for userspace programs. Some information on using this IOCTL is given in the Freescale iMX233 Evaluation Kit Reference Manual. I wrote a sample otpcrypt tool for demonstrating usage of AES with OTP key. Compile the code on your board and run it like this to encrypt/decrypt data:

> echo fadishei | otpcrypt | base64
oUP5IdEbv4RePVo7mF4hZw==
> echo oUP5IdEbv4RePVo7mF4hZw== | base64 -d | otpcrypt -d
fadishei

I used base64 coding for encrypted data above in order to make it possible to see it on terminal. In order to verify the correctness of the result, you can compare it with OpenSSL encryption results on any computer:

> echo fadishei | openssl enc -aes-128-ecb -K 00000000000000000000000000000000 | base64
oUP5IdEbv4RePVo7mF4hZw==
> echo oUP5IdEbv4RePVo7mF4hZw== | base64 -d | openssl enc -d -aes-128-ecb -K 00000000000000000000000000000000
fadishei

Notes on ECB mode and IV

iMX23 OTP AES is only capable of doing basic AES128 ECB mode on 128-bit data blocks. ECB is not quite secure. CBC is a more secure mode in which every data bloack is XORed with previous block result prior to encryption. A unique IV (Init Vector) is suggested to be used for each data item under encryption in order to have different ciphers for similar plaintexts. The OTP AES IOCTL does not feature CBC and IV. It should be implemented separately in software and needs some knowledge about AES algorithm and data padding. Refer to my otpcrypt tool to see how I managed to do that in a user-space applicaiton.

Request for Information

If you have further information on the DCP crypto engine of iMX233, specially the OTP AES, please comment!

November 24, 2012

Why does jbd2 constantly accesses my partition?

Filed under: Uncategorized — fadishei @ 5:46 pm
Tags: , , , ,

Are you frustrated by your HDD LED blinking constantly after mounting your newly formatted ext4 partition? Don’t go any further by killing innocent suspect processes! mkfs.ext4 holds some init ops for when you mount the fs to be done in background. You could disable such behavior by using -E lazy_itable_init=0.

October 13, 2012

Emulate OLinuxino Archlinux Image

Filed under: Uncategorized — fadishei @ 11:14 pm
Tags: , , , ,

OLinuxino is getting more and more popular for offering a good price-performance-size tradeoff. Archlinux now officially supports OLinuxino which means you have access to many prebuilt packages (openjdk, multimedia recorders and players, web servers, etc, etc) ready to be installed by the ‘pacman’ command.
A problem that you may still face as a developer is that due to the limited board resources, compiling programs and building new packages consumes lots of time, if possible at all.
If you want to use the power of your PC in develping for OLinuxino you can either setup a cross compilation environment or an emulation environment. In this post I describe an easy method for emulating the official Archlinux image of OLinuxino.

1. Download kernel, initrd, and filesystem provided by aurel32 for debian emulation from here
kernel: vmlinuz-2.6.32-5-versatile
initrd: initrd.img-2.6.32-5-versatile
filesystem image: debian_squeeze_armel_standard.qcow2

2. mount the first partition of debian_squeeze_armel_standard.qcow2 in /mnt (see here if you don’nt know how)

3. backup /mnt/lib/modules/* somewhere safe, then remove all the files in /mnt

4. extract the official OLinuxino Archlinux filesystem as root into /mnt

5. restore the the backup modules/* folder into /mnt/usr/lib/modules

6. Adjust the filesystem for changes posed by the emulation environment, such as:
change ttyAMA0 to tty1 in /mnt/etc/inittab
change usb0 to eth0 in /etc/rc.conf

7. unmount debian_squeeze_armel_standard.qcow2 and rename it to archlinux_olinuxino.qcow2

8. startup your emulated environment:
sudo qemu-system-arm -M versatilepb -kernel vmlinuz-2.6.32-5-versatile -initrd initrd.img-2.6.32-5-versatile -hda archlinux_olinuxino.qcow2 -append “root=/dev/sda1”

April 7, 2012

Transferring A Directory Tree Between Servers Using rsync without Passwordless SSH

Filed under: Linux — fadishei @ 7:29 am
Tags: , , , ,

Linux server administrators occasionally need to transfer files between servers. scp is a handy command line for this purpose. But there is a better approach, rsync, which will give you two advantages: First, you can resume broken transfers (even in case of multiple files and directories). Second, it skips transferring the files that are similar between source and target. Thus you may re-transfer content after modifications optimally.
rsync uses an externall remote shell, ssh in the case of this tutorial. One annoying thing is that many tutorials over the net require you to setup passwordless SSH (public key encryption) from between source and target machine which, in my opinion, is a real chore to be done as a prerequisite for a simple file transfer.
Instead, I suggest using sshpass utility which allows you to enter ssh password in command line. Don’t worry for you password being stored in bash_history! Linux has a solution for this: add a blank character at the start of the command and it will never go into ~/.bash_histry.

$ sudo apt-get install sshpass
$ [type a blank here] nohup rsync -avzl -e "sshpass -p dst_pass ssh" /path/to/src dst_user@dst_ip:/path/to/dst &

nohup is used to let you logout after issueing the command without the transfer operation being stopped. You may monitor the transfer progress at any time by using this command:

$ tail -f nohup.out

March 22, 2012

ZK MVVM Design Pattern and Server-Side Paging

Filed under: Java — fadishei @ 1:34 pm
Tags: , , ,

MVVM (Model/View/ViewModel) is a brilliant variant of the well known MVC (Model/View/Controller) design pattern. ZK has recently added support for this pattern. For an intruduction to MVVM in ZK you may want to see this page.
On the other hand, server-side paging is a technique for showing a huge list of records without fetching and transferring all the data from database to the client. ZK has some good documents and tutorials for implementing this technique using MVC pattern. But so far I could not find any good tutorial for pagination in MVVM projects. Thus I decided to have a short howto for that in my blog. I assume that you are familiar with ZK and Spring framework.
Assume you want to show a list of people in your rich Internet application. The Person POJO is defined as follows:

package ir.fadishei.examples.zk.paging.model;

public class Person
{
	Integer id;
	String firstName;
	String lastName;
	
	// Setters and getters come here
}

The example WITHOUT server-side paging

First, I show how you display the list of people without server-side paging. This will fetch all the records and transfer them to the client which is not a good idea in case of huge lists. I will use my favorite library, myBatis, for mapping between my sqlite person database table and the Person POJO. You may want to use other ones like Hibernate instead.

package ir.fadishei.examples.zk.paging.model;

import java.util.List;
import org.apache.ibatis.annotations.Select;

public interface PersonMapper
{
	@Select("SELECT * FROM person)
	List<Person> getPersons();
}

Now we write a ZUL page for displaying the people list:

<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
<zk>
<window title="List of people" border="normal" width="600px" apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('ir.fadishei.examples.zk.paging.viewmodel.PersonVM')">
	<vbox hflex="true">
		<listbox model="@bind(vm.persons)" hflex="true" height="200px" mold="paging">
			<listhead>
				<listheader label="Id"/>
				<listheader label="First Name"/>
				<listheader label="Last Name"/>				
			</listhead>
			<template name="model" var="person">
				<listitem >
					<listcell label="@bind(person.id)"/>				
					<listcell label="@bind(person.firstName)"/>
					<listcell label="@bind(person.lastName)"/>
				</listitem>
			</template>
		</listbox>
	</vbox>
</window>
</zk>

Finally, we need the ViewModel for brdging the view to the model:

package ir.fadishei.examples.zk.paging.viewmodel;

import ir.fadishei.examples.zk.paging.model.Person;
import ir.fadishei.examples.zk.paging.model.PersonMapper;
import java.util.List;
import org.zkoss.zk.ui.select.annotation.WireVariable;

public class PersonVM
{
	@WireVariable
	PersonMapper personMapper;

	public List<Person> getPersons()
	{
		return personMapper.getPersons();
	}
}

The example with server-side paging

Now we modify the previous example for making it able to paginate at server side. First of all, we should change the database mapper to be able to fetch a specific page from person table. It should also have a method that returns the total number of records. This is required to find out the total number of pages displayed in the view:

package ir.fadishei.examples.zk.paging.model;

import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

public interface PersonMapper
{
	@Select("SELECT * FROM person limit #{limit} offset #{offset}")
	List<Person> getPersonPage(@Param("offset") Integer offset, @Param("limit") Integer limit);

	@Select("SELECT COUNT(*) FROM person")
	Integer getPersonCount();
}

Next, we modify the view and remove the paging capability from the listbox. instead, we add a separate paging component:

<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
<zk>
<window title="List of people" border="normal" width="600px" apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('ir.fadishei.examples.zk.paging.viewmodel.PersonVM')">
	<vbox hflex="true">
		<paging pageSize="@load(vm.pageSize)" totalSize="@load(vm.totalSize)" activePage="@save(vm.activePage)"/>
		<listbox model="@bind(vm.persons)" hflex="true" height="200px">
			<listhead>
				<listheader label="Id"/>
				<listheader label="First Name"/>
				<listheader label="Last Name"/>				
			</listhead>
			<template name="model" var="person">
				<listitem >
					<listcell label="@bind(person.id)"/>				
					<listcell label="@bind(person.firstName)"/>
					<listcell label="@bind(person.lastName)"/>
				</listitem>
			</template>
		</listbox>
	</vbox>
</window>
</zk>

Our ViewModel should get activePage from view and give pageSize, totalSize, and active page contents to the view:

package ir.fadishei.examples.zk.paging.viewmodel;

import ir.fadishei.examples.zk.paging.model.Person;
import ir.fadishei.examples.zk.paging.model.PersonMapper;
import java.util.List;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.select.annotation.WireVariable;

public class PersonVM
{
	int pageSize = 10;
	int activePage = 0;
	@WireVariable
	PersonMapper personMapper;
	
	public int getTotalSize()
	{
		return personMapper.getPersonCount();
	}
	
	public Integer getPageSize()
	{
		return pageSize;
	}

	@NotifyChange("persons")
	public void setActivePage(int activePage)
	{
		this.activePage = activePage;
	}

	public List<Person> getPersons()
	{
		return personMapper.getPersonPage(activePage*pageSize, pageSize);
	}
}

Alternatively, you could handle onPaging event of the paging component instead of binding its activePage to the ViewModel. But I think this would be a little messier!

January 29, 2012

Adding RTL (Right-to-Left) Support to Zotero

Filed under: Research,Uncategorized — fadishei @ 3:09 am
Tags: , , , , ,

Update (2012-08-16): I’ve patched the Zotero source and posted a pull request on github. I asked Zotero developers to add this feature to the main distribution. Please support it by asking the Zotero developers to merge the pull request via email or forum.

Pull request page: https://github.com/zotero/zotero/pull/157
Related forum post: http://forums.zotero.org/discussion/10879

In a previous post, I wrote about Zotero and the lack for supporting RTL languages in its note editor and how to work around this problem. In this post a better procedure for adding RTL support to Zotero is presented that also works in newer versions of Firefox.
The procedure is similar to the previous post with one difference: This time, you modify the Zotero plugin before installing it in Firefox.

mkdir ~/work
cd ~/work
wget http://download.zotero.org/extension/zotero-2.1.10.xpi
unzip -d xpi zotero-2.1.10.xpi
mkdir jar
cd jar
jar -xf ../xpi/chrome/zotero.jar
cd ..
wget http://downloads.sourceforge.net/project/tinymce/TinyMCE/3.3.9.2/tinymce_3_3_9_2.zip
unzip tinymce_3_3_9_2.zip
cp -au tinymce/jscripts/tiny_mce/* jar/content/zotero/tinymce/
sed -i 's/paste,contextmenu/paste,contextmenu,directionality/g' jar/content/zotero/tinymce/note.html
sed -i 's/sup,|,forecolor/sup,|,ltr,rtl,|,forecolor/g' jar/content/zotero/tinymce/note.html
cd jar
jar -c0f ../xpi/chrome/zotero.jar *
cd ../xpi
zip -r ../zotero-2.1.10-rtl.xpi *

The above procedure worked for me on Zotero 2.1.10 and Firefox 9.0.1.
The version of TinyMCE that should be downloaded can be determined by inspecting the file jar/content/zotero/tinymce/tiny_mce.js before downloading it.

July 8, 2011

perf_events and the secret behind very very large outlier values

During my research on power/performance analysis of computational workloads, I frequently use the perf_events kernel subsystem to get a graph of relevant performance counter values such as cache misses and instructions retired. You can examine this if you want by installing the libpfm4 library on a Linux machine with an enough up-to-date kernel. For me, Ubuntu 10.10 or newer works perfect. After compilation of libpfm4, you can find a “syst” tool in the “perf_examples” folder which can be used to examine the perf_events. A sample output of this command is given below (Note: the long output lines seem a mess on small monitors. If this is the case for you, copy and paste them in a text editor with line wrapping disabled):

$ sudo ./syst -c 0 -e PERF_COUNT_HW_CACHE_L1D:MISS,PERF_COUNT_HW_CACHE_L1I:MISS,PERF_COUNT_HW_CACHE_LL:MISS,PERF_COUNT_HW_CACHE_L1D:ACCESS,PERF_COUNT_HW_CACHE_L1I:ACCESS,PERF_COUNT_HW_CACHE_LL:ACCESS
------------------------
CPU0 val=409989               raw=199299 ena=2000395421 run=972407540 ratio=0.49 delta=369213          PERF_COUNT_HW_CACHE_L1D:MISS
CPU0 val=203841               raw=99091 ena=2000432800 run=972446620 ratio=0.49 delta=164564           PERF_COUNT_HW_CACHE_L1I:MISS
CPU0 val=211172               raw=844 ena=2000444925 run=7995247 ratio=0.00 delta=105590               PERF_COUNT_HW_CACHE_LL:MISS
CPU0 val=16091475             raw=8108192 ena=2000465017 run=1007996718 ratio=0.50 delta=9654365       PERF_COUNT_HW_CACHE_L1D:ACCESS
CPU0 val=42724654             raw=21784141 ena=2000484350 run=1019992634 ratio=0.51 delta=30353998     PERF_COUNT_HW_CACHE_L1I:ACCESS
CPU0 val=10031112             raw=100233 ena=2000504170 run=19989462 ratio=0.01 delta=10031112         PERF_COUNT_HW_CACHE_LL:ACCESS
------------------------
CPU0 val=501430               raw=261466 ena=3000602105 run=1564635603 ratio=0.52 delta=91441          PERF_COUNT_HW_CACHE_L1D:MISS
CPU0 val=347087               raw=182375 ena=3000612244 run=1576652337 ratio=0.53 delta=143246         PERF_COUNT_HW_CACHE_L1I:MISS
CPU0 val=375206               raw=5499 ena=3000615126 run=43976828 ratio=0.01 delta=164034             PERF_COUNT_HW_CACHE_LL:MISS
CPU0 val=33934452             raw=14475612 ena=3000617370 run=1279990387 ratio=0.43 delta=17842977     PERF_COUNT_HW_CACHE_L1D:ACCESS
CPU0 val=64070808             raw=29722497 ena=3000619469 run=1391989674 ratio=0.46 delta=21346154     PERF_COUNT_HW_CACHE_L1I:ACCESS
CPU0 val=2344440              raw=112486 ena=3000622062 run=143969520 ratio=0.05 delta=18446744073701864944 PERF_COUNT_HW_CACHE_LL:ACCESS
------------------------
CPU0 val=693081               raw=273320 ena=4000722671 run=1577704276 ratio=0.39 delta=191651         PERF_COUNT_HW_CACHE_L1D:MISS
CPU0 val=567389               raw=227722 ena=4000729723 run=1605693997 ratio=0.40 delta=220302         PERF_COUNT_HW_CACHE_L1I:MISS
CPU0 val=509063               raw=8139 ena=4000731389 run=63964418 ratio=0.02 delta=133857             PERF_COUNT_HW_CACHE_LL:MISS
CPU0 val=48617260             raw=21047221 ena=4000733390 run=1731984034 ratio=0.43 delta=14682808     PERF_COUNT_HW_CACHE_L1D:ACCESS
CPU0 val=67881736             raw=40027485 ena=4000739182 run=2359095923 ratio=0.59 delta=3810928      PERF_COUNT_HW_CACHE_L1I:ACCESS
CPU0 val=852461               raw=141288 ena=4000745498 run=663088489 ratio=0.17 delta=18446744073708059637 PERF_COUNT_HW_CACHE_LL:ACCESS
------------------------
CPU0 val=1271202              raw=406130 ena=5000845112 run=1597694641 ratio=0.32 delta=578121                 PERF_COUNT_HW_CACHE_L1D:MISS
CPU0 val=812083               raw=316607 ena=5000851173 run=1949682622 ratio=0.39 delta=244694                 PERF_COUNT_HW_CACHE_L1I:MISS
CPU0 val=68883                raw=14204 ena=5000856091 run=1031189733 ratio=0.21 delta=18446744073709111436    PERF_COUNT_HW_CACHE_LL:MISS
CPU0 val=45801721             raw=21607567 ena=5000861964 run=2359222674 ratio=0.47 delta=18446744073706736077 PERF_COUNT_HW_CACHE_L1D:ACCESS
CPU0 val=87662128             raw=41579483 ena=5000865063 run=2371986478 ratio=0.47 delta=19780392             PERF_COUNT_HW_CACHE_L1I:ACCESS
CPU0 val=1364606              raw=188820 ena=5000867812 run=691967970 ratio=0.14 delta=512145                  PERF_COUNT_HW_CACHE_LL:ACCESS
------------------------
CPU0 val=1427100              raw=511222 ena=6000961317 run=2149690055 ratio=0.36 delta=155898               PERF_COUNT_HW_CACHE_L1D:MISS
CPU0 val=979620               raw=350930 ena=6000967977 run=2149729928 ratio=0.36 delta=167537               PERF_COUNT_HW_CACHE_L1I:MISS
CPU0 val=89669                raw=18827 ena=6000969658 run=1259961587 ratio=0.21 delta=20786                 PERF_COUNT_HW_CACHE_LL:MISS
CPU0 val=57523422             raw=26794792 ena=6000974528 run=2795293771 ratio=0.47 delta=11721701           PERF_COUNT_HW_CACHE_L1D:ACCESS
CPU0 val=131362760            raw=56725304 ena=6000980367 run=2591354160 ratio=0.43 delta=43700632           PERF_COUNT_HW_CACHE_L1I:ACCESS
CPU0 val=1733386              raw=305015 ena=6000983863 run=1055962131 ratio=0.18 delta=368780               PERF_COUNT_HW_CACHE_LL:ACCESS

The delta values reported above state the counted values within the periods of 1s. One odd thing about that output is the very large outlier values such as the last-level cache misses of 18446744073701864944 in the second measurement interval. It got me quite a time until I found the reason for getting such values. First of all, if you look at the source code, you will see that they are not big outliers, but in fact small negative values which are interpreted as unsigned 64-bit integers. For example, 18446744073701864944 is in fact -7686672 when interpreted as unsigned integer. But why do we get negative numbers at all?
The root of the problem lies in a concept known as “event multiplexing”. The number or CPU performance counters are limited. For example, my Core 2 Quad Intel CPU only allows two cache-related events to be counted simultaneously. To overcome this limitation, the counters are time-shared among the desired counted events in software (in perf_events kernel subsystem). Thus, an event is in fact counted at only a fraction of the real time passed. For the fraction in which a counter is not counted, the value is estimated based on the other fraction. This causes some error in the event counting, which obviously may deviate the value into a negative number. We, in fact, trade accuracy for counting more events.

February 25, 2011

Writing RTL Notes on Zotero

Filed under: Research — fadishei @ 10:45 am
Tags: , , , , ,

Update (2012-08-16): I’ve patched the Zotero source and posted a pull request on github. I asked Zotero developers to add this feature to the main distribution. Please support it by asking the Zotero developers to merge the pull request via email or forum.

Pull request page: https://github.com/zotero/zotero/pull/157
Related forum post: http://forums.zotero.org/discussion/10879

Update: The procedure in this post does not work on new Firefox versions as it disables plugins which are modified after installation. For an updated and better procedure, please visit here.

Zotero is the software for researchers and in my opinion, it is a must. It helps you organize your references, add tags and notes to them, search them, and do a lot more things. The first day that I met this research tool, I said to myself: “The water is in the jug and I am looking for it around the world”! (This is a Persian idiom, which is used when you find out something you really missed was in fact near you).

As a Persian native, one thing that zotero lacked for me was the support of RTL languages in its note editor. After some goolging and reading a useful post on the Zotero forum, I managed to add the RTL and LTR buttons to its built-in editor. If you need the support of RTL languages (such as Arabic, Hebrew, and Persian) in Zotero then this blog post may help you. I hope that Zotero team will add this functionality to the main zotero release so that RTL people do not have to patch their installation for it.

The procedure is for the latest stable release at the moment which is zotero-2.0.9. I assume that you have Zotero installed and my instructions are for a Linux environment. You should patch the RTL functionality into built-in tinyMCE editor which resides in zotero.jar.

First of all, make a working directory and find and unpack zotero.jar there:

$ mkdir -p ~/work/zotero
$ cd ~/.mozilla
$ find -name zotero.jar
./firefox/z4qwdrwe.default/extensions/zotero@chnm.gmu.edu/chrome/zotero.jar
$ cp ./firefox/z4qwdrwe.default/extensions/zotero@chnm.gmu.edu/chrome/zotero.jar ~/work/
$ cd ~/work/zotero
$ jar -xf ../zotero.jar

Then you should download the same version of tinyMCE as the one in zotero.jar and add the extra tinyMCE files that are not available in the zotero.jar to it. In order to find out what version it is you can look at tiny_mce.js.

$ cat content/zotero/tinymce/tiny_mce.js | grep Version
   majorVersion : '3',
   minorVersion : '3.9.2',
$ cd ..
$ wget http://downloads.sourceforge.net/project/tinymce/TinyMCE/3.3.9.2/tinymce_3_3_9_2.zip
$ unzip tinymce_3_3_9_2.zip
$ cp -au tinymce/jscripts/tiny_mce/* zotero/content/zotero/tinymce/

The third step is to enable directionality plugin. Go this way:

$ cd zotero
$ vi content/zotero/tinymce/note.html
change:
    plugins : "paste,contextmenu",
to:
    plugins : "paste,contextmenu,directionality",

change:
    theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,sub,sup,|,forecolor,backcolor,|,blockquote,|,link,unlink",
to:
    theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,sub,sup,|,ltr,rtl,|,forecolor,backcolor,|,blockquote,|,link,unlink",

Now you can compress your new zotero.jar and move it back into where you found it in the first step:

$ jar -cf zotero.jar *
$ mv zotero.jar ~/.mozilla/firefox/z4qwdrwe.default/extensions/zotero@chnm.gmu.edu/chrome/

You should (re)start your firefox now. If everything goes OK, you will have two new buttons in your browser: RTL and LTR.

January 3, 2011

A Simple Programmer for PIC18F14K50 Microcontroller

Filed under: Microcontroller — fadishei @ 2:12 am
Tags: ,

Microchip’s PIC18F14K50 is fantastic: almost anything you need in a small footprint for a low price! Absorbed in many good features of this chip, I neglected a special requirement for its flash programming when I was designing a small USB board. Unlike many other PICs, you have to drive two programming pins of this micro with 3.3v even if you are using a 5v supply. This was not a good news for me and probably many other people who want to use low cost hand made programmers. But don’t be worry! If your programmer is a PICPgm LVISP then you can program PIC18F14K50 by a applying small modification to the programmer circuit and using the latest version of PICPgm.

Next Page »

Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.