fev
06
2010

Usando o subversion para sincronizar a $HOME

Enfim postando no blog agora que não tenho mais dor de cabeça universidade, mas vamos ao que interessa.

A muito tempo atrás vinha procurando uma forma de sincronizar minhas configurações de usuário como chaves públicas, scripts, hosts através de várias máquinas, uma vez que tenho que manter em sincronia a minha máquina no trabalho, notebook pessoal, desktop pessoal (fora as máquinas virtuais).

A um tempo tentei algo como um script que utilizava scp, para sincronizar diretórios, mas com o problema de consumo de banda (o que no Brasil é um grande problema) e sobrescrever  alterações, resolvi adotar o rsync que já otimizava o uso da banda enviando somente as alterações e faz a checagem da data de modificação porém ele não faz nenhuma verificação quanto ao conteúdo do arquivo, e isto trazia um sério problema pois uma vez que houvessem alterações em duas máquinas, teríamos um sério problema na hora de sincronizar os arquivos.

Um dia desses no trabalho, utilizando o subversion para controle de versão em um projeto, ele fornece backup dos arquivos, histórico de alterações, otimiza o consumo de banda enviando somente alterações e ainda por cima verifica o conteúdo dos arquivos em questão.. Comecei a associar as coisas, e isto parecia ser uma possível solução para o meu problema, por que não tentar?

Criado o repositório online, ja que todas máquinas tem acesso a internet, dei um checkout na minha $HOME para criar os diretórios .svn de controle, a primeira coisa que fiz foi ignorar todos arquivos na minha pasta pessoal com o comando:

svn propset svn:ignore *

Isto deve ser feito senão todos arquivos na HOME serão tratados como desconhecidos e perguntado se não devem ser adicionados ao controle de versão e não queremos isto, queremos fazer o controle de somente alguns arquivos/diretórios que são de nosso interesse.

logo após esse procedimento podemos começar a adicionar nossos arquivos ao controle de versão, como por exemplo nossa pasta .ssh e .gnupg para ter nossa chave pública em todas as máquinas:

$ svn add .ssh
$ svn add .gnupg

Caso queira ignorar algum arquivo como o known_hosts na pasta ssh proceda da seguinte forma:

$ svn rm --keep-local known_hosts
$ svn propset svn:ignore known_hosts

Uma vez feito isto já temos os arquivos que queremos no controle de versão e só falta o commit:

$ svn status -uv # cheque se esta tudo ok ;)
$ svn commit -m "commit inicial da home"

Estou usando a algum tempo este procedimento, e tem dado muito certo, uma vez que não perco meus arquivos, mantenho um registro das alterações e tenho minhas máquinas (virtuais) sincronizadas. happy syncin’.

jan
30
2010

First prototype for Beagle Board box

After drawing a sketch for BeagleBoard this week I coud try something real. The board fit perfectly inside the box.

The whole for DVI-D would be a little bigger, the way it is the user need stick the connector well to don’t loose image quality.

The entries for USB and MMC fits together in the same whole.  I put RS232 output because it’s a prototype, if you are developing something for an end-user you don’t need that. The box in my tests don’t heated

I’m using this box to show a “general purpose” computer to others. Inside the memory card I had some GNU/Linux distributions like: Angstron, Ubuntu and Gentoo. But Symbian and Maemo are in the roadmap. Other tests include running linus-git kernel done with CodeSourcery toolchain (2009q1 and 2009q3) and playing with armv7a instructions.

Check more photos on Flickr!

jan
28
2010

Byte Order

In the book about Linux Kernel Programming the author Robert Love demonstrated a trick to check your hardware endianness.

int x = 1;
if (*(char *)&x == 1)
/* little endian */
else
/* big endian */

Using GCC you can use -mbig-endian or -mlittle-endian to generate appropriate endianess. Remember to check man pages section on your architecture (i.e: i386 and x86-64 don’t implement this option whilst IA-64 and ARM yes)

One interesting point regards on byte swapping. Suppose that you have a file that starts with 0xaabbccdd referring to little endian and 0xddccbbaa referring to big endian (note that I took these values and order arbitrarily). In order to use one kind of byte order in your code we need check what endianness your file was generated and if necessary rectify. This C++ code exemplifies.

class Endian {
 
     int _byteSwapped;
 
public:
 
     Endian(unsigned long dw) {
 
        if (0xaabbccddL == dw) _byteSwapped = 1;
        else if (0xddccbbaaL == dw)  _byteSwapped = 0; 
        else throw "error";
 
     }
 
     long rectify(long dw) const {
 
        if (!_byteSwapped) return dw;
        char result[4] = {((char*) &dw)[3],((char*) &dw)[2],((char*) &dw)[1],((char*) &dw)[0]};
        return (*((long*) result));
 
     }
};

Another way to do byte swapping is using an macro. The following example swap two bytes:

#define SwapTwoBytes(data) ( (((data) >> 8) & 0x00FF) | (((data) << 8) & 0xFF00) )

One of the best practices is provide one software that will work correctly no matter which processor Endian-architecture the code is executed on, eliminating the need to rewrite the code. Intel has a interesting paper on Converting Endian-specific to Endian-neutral Code (pg. 15-16).

jan
16
2010

Convertendo videos do Youtube para audio (MP3)

Programas necessários:

  • Alguma distribuição GNU/Linux
  • mplayer
  • lame (caso queria converter para mp3)
  • vorbis-tools (caso queira converter para ogg)

Os videos do YouTube, normalmente qualquer conteúdo Flash, fica armazenados na pasta /tmp do sistema operacional na forma FlashXXXX (exemplo: FlashaOiW6k). Para cada arquivo flash existirá um arquivo correspondente, para descobrir de qual se trata utilize o mplayer, no console (cd /tmp):

mplayer FlashaOiW6k

Após descobrir o arquivo, vamos primeiro converter o arquivo para wav e depois para algum formato mais compacto.

mplayer FlashaOiW6k -novideo -ao pcm:file=musica.wav

Convertendo para mp3:

lame -V2 input.wav output.mp3
lame -V2 musica.wav musica.mp3

Ou ogg:

oggenc musica.wav

No final temos os seguintes tamanhos para cada arquivo, considerando uma música de 4 minutos.

  • 8.9M    FlashaOiW6k
  • 21.0M    saida.wav
  • 2.4M   saida.mp3
  • 1.5M   saida.ogg

Este procedimento provavelmente irá funcionar para qualquer conteúdo Flash (ex. outros sites de video) que fique armazenado na tmp.

jan
14
2010

First sketch for Beagle Board box

This is my first approach to make a case for Beagle Board. I used a plastic one that fits almost perfect, needed basically a 12 mm. spacer to height adjust. The box would be like this picture:

And the BB would fit, inside the box, more or less like that:

I still need consider some points:

  • Even with an “natural” exhaust ventilation (no fan, not visible in picture) the heat influence on “heavy” use.
  • Check all connectors and see if they fit properly.

I hope for the next weeks post more about this box and great ideas with Beagle Board.

Stay tuned!

nov
29
2009

Assembly inline

I’ve made some code snippets about assembly inline with GCC. A quick search points to a lot of good documentation.

The syntax may be confusing, if you don’t understand read the documentation available. Each example are an C function with the special construct “asm” for inline assembly code. Examples:

Increment an value:

void inc(int *value) {
 
    asm ( "incl %0"
         :"=a"(*value)
         :"0"(*value)
        );
 
}

Exchange to numbers:

void swap(int *x, int *y) {
 
    asm(""
        : "=a"(*y),"=b"(*x)
        : "a"(*x),"b"(*y)
       );
 
}

Copy an vector:

void vector_copy(int *v_src, int *v_dst, int *count) {
 
    asm("up: lodsl;"
	"    stosl;"
	"loop up;  "
	:
	: "S"(v_src), "D"(v_dst), "c"(*count)
	: "%eax"
	);
 
}

A simple copy:

void copy(int *from, int *to) {
 
     asm ("movl %1, %%eax;"
          "movl %%eax, %0;"
          :"=&amp;r"(*to)
          :"r"(*from));
 
}

A very simple implementation for strncpy:

void _strncpy(char *src, char *dst, int *count) {
 
    asm("cld;"
        "rep movsb;"
        :
        : "S"(src), // 'S' == %esi
	  "D"(dst), // 'D' == %edi
	  "c"(*count)); // 'c' == %ecx
}

If you like to try check this example:

wget http://github.com/maluta/junk/raw/master/asm-inline.c
gcc -Wall -ggdb asm-inline.c -o asm-inline
./asm-inline
nov
25
2009

Google Translate na linha de comando

Isto pode ser feito de mil maneiras diferentes (e até mais simples) : usando shell script, python, php, etc. Resolvi fazer uma prova do conceito em Qt/C++ para treinar. Para executar baixe o script de instalação install-translate.sh que ira fazer o downlad dos arquivos e compilar.

nov
15
2009

Acionando os mantenedores

Se você precisar entrar em contato com o mantendor de algum sub-sistema do kernel Linux mas não sabe onde procurar, utilize um script (get_maintainer.pl) incluído no próprio código. Um exemplo,  suponha que você utilize o sistema de arquivos ext4 e deseje sugerir alguma idéia. Se for um bug é recomendado utilizar a plataforma de submissão de bugs (bugzilla) que além de seguir uma metodologia para descrever o erro é uma forma de catalogar o problema. Estou considerando neste post que você ainda não é um desenvolvedor e quer achar o mantenedor pois gostaria de fazer uma sugestão ou comentário acerca da área do código-fonte que ele mantém. Este tipo de busca talvez seja mais intessante nos devices drivers…

Um exemplo com o ext4:

./scripts/get_maintainer.pl -f  fs/ext4/

“Theodore Ts’o” <tytso@…>

Aneesh Kumar K.V <aneesh.kumar@…>

Eric Sandeen <sandeen@…>

linux-kernel@vger.kernel.org (lembre-se de se cadastrar e sempre de copiar a lista de email junto)

Um exemplo com o driver de video da Intel:

./scripts/get_maintainer.pl -f drivers/video/intelfb/

Sylvain Meyer <sylvain.meyer@worldonline.fr>
Andrew Morton <akpm@linux-foundation.org>
Thomas Hilber <sparkie@lowbyte.de>
Stefan Husemann <shusemann@googlemail.com>
Hannes Eder <hannes@hanneseder.net>
Paul Menzel <paulepanter@users.sourceforge.net>
linux-fbdev-devel@lists.sourceforge.net
linux-kernel@vger.kernel.org

Sylvain Meyer <sylvain.meyer@…>

Andrew Morton <akpm@…>

Thomas Hilber <sparkie@…>

Stefan Husemann <shusemann@…>

Hannes Eder <hannes@…>

Paul Menzel <paulepanter@…>

linux-fbdev-devel@lists.sourceforge.net

linux-kernel@vger.kernel.org

Dar o retorno do uso de algum programa é ótimo para o desenvolvedor e garante a qualidade do sotfware.

nov
12
2009

Otimização

Dentre as diversas apresentações no Linux Kongress 2009 a palestra do Felix von Leitner’s me chamou atenção. Com título “Compiler Optimization Survey” ele discutiu os aspectos relacionados a programação nos compiladores modermos e as possibilidades de otimização (slides).  A idéia básica é que:

  • Otimização é importante
  • Mas frequentemente: Código legível é mais importante
  • Aprenda o que seu compilador faz
    E então deixe-o fazê-lo.

Exemplo. As quatro instruções abaixo fazem a mesma coisa, zeram um registrador da CPU x86, qual é a melhor forma?

Zerando registros

Analisando no GDB (x/FMT ADDRESS) temos:

movl  0xb8    0x00    0x00    0x00    0x00
andl  0x83    0xe0    0x00
subl  0x29    0xc0  
xorl  0x31    0xc0
 

E agora? sub ou xor, veja que ambos produzem uma falsa dependência em %eax, mas a CPU sabe como ignorar no caso do xor.

Você sabia?

O compilador sim.

Se você usar o sub na prova seu professor provavelmente irá descontar alguns pontos ou te dar zero…

  • Se você fizer uma otimizacão, teste em dados reais.
  • Se tornar o código ilegível não tornar o programa drasticamente rápido, não faça.
movl  0xb8    0×00    0×00    0×00    0×00
andl  0×83    0xe0    0×00
subl  0×29    0xc0
xorl  0×31    0xc0
nov
11
2009

Acessando o Gmail pelo Mutt

Para acessar seus emails da conta do GMAIL no modo texto, utilizando o mutt,  adicione ao arquivo ~/.muttrc

set imap_user = "USERNAME@gmail.com"
set imap_pass = "PASSWORD"
set spoolfile = imaps://imap.gmail.com:993/INBOX
set folder = imaps://imap.gmail.com:993
set record="imaps://imap.gmail.com/[Gmail]/Sent Mail"
set postponed="imaps://imap.gmail.com/[Gmail]/Drafts"
set header_cache="~/.mutt/cache/headers"
set message_cachedir="~/.mutt/cache/bodies"
set certificate_file=~/.mutt/certificates

set move = no

set sort = 'threads'
set sort_aux = 'last-date-received'
set imap_check_subscribed

ignore "Authentication-Results:"
ignore "DomainKey-Signature:"
ignore "DKIM-Signature:"
ignore "Received:"
ignore "Return-Path"
ignore "MIME-Version"
ignore "X-Spam-Details"
ignore "Received-SPF"
ignore "List-Id"
ignore "List-Unsubscribe"
ignore "List-Post"
ignore "List-Help"
ignore "List-Subscribe"
ignore "Content-Type"
ignore "Content-Transfer-Encoding"
ignore "Sender"
ignore "Errors-To"
ignore "X-BeenThere"
ignore "X-Mailman-Version"
ignore "Precedence"
ignore "List-Archive"
ignore "X-MIME-Autoconverted"
ignore "Message-ID"
ignore "Delivered-To"
ignore "User-Agent"
ignore "X-Spam-Score"
ignore "X-Spam-OrigSender"
ignore "X-Spam-Bar"
ignore "In-Reply-To"
ignore "References"
ignore "X-System-Of-Record"

hdr_order Date From To Cc