OpenWRT

Criando um roteador Wifi com adblock

Quem me conhece, sabe que eu sou um grande entusiasta do projeto OpenWRT. Foi por isso e por querer contribuir com o grupo de OpenWRT do LHC que decidi escrever este tutorial. Neste post vou mostrar como criar um roteador WiFi usando o OpenWRT e uma Raspberry Pi 3 (ou qualquer outra que você tenha disponível). Nosso roteador terá uma funcionalidade bem interessante: ele bloqueará anúncios dos sites que visitarmos – assim como o bloqueador de anúncios do seu navegador.

Antes de começarmos, é importante ressaltar que o desempenho de rede nas versões mais antigas da Raspberry (0, 1, 2 e 3) pode ficar abaixo do que você espera, isso porque as interfaces de rede estão ligadas ao SOC (processador) por um barramento USB 2.0 – Isso não acontece com a Raspberry Pi 4. Como a idéia é experimentar e não criar um roteador comercial, essa limitação não irá nos impedir de continuarmos, certo?

Material

Bom, recado dado, é hora de listarmos o que precisaremos para criar o nosso roteador caseiro:

  • Um computador com uma distro Linux ou uma VM;
  • Uma Raspberry Pi 3 model B (as instruções para outras versões podem ser diferentes, deixe nos comentários as dúvidas nesse caso);
  • Um adaptador UART-Serial (recomendado, não obrigatório);
  • Um cabo de rede ou um patch cord;
  • Um micro SD Card de 2GB ou mais;

Preparando o ambiente

Se você não se sente confortável com compilação, git, etc. Siga para “gravando a imagem no sd-card”, mais abaixo, e siga o passo-a-passo utilizando a imagem oficial do OpenWRT para a Raspberry Pi.

Basicamente, o que vou reproduzir aqui é o que já coloquei anteriormente no artigo do Embarcados “Conhecendo o OpenWRT“, que escrevi junto com meu amigo Thiago Medicci um tempo atrás. As instruções apresentadas consideram que você está usando o Ubuntu 16.04 como ambiente de desenvolvimento.

Primeiro, instale as dependências do projeto no seu ambiente:

$ sudo apt update
$ sudo apt install make gcc binutils bzip2 flex python perl grep git unzip gawk subversion libz-dev libc-dev libncurses-dev time wget g++ xz-utils

Em seguida, clone o projeto para seu ambiente:

$ git clone https://github.com/openwrt/openwrt.git

O leitor mais atento perceberá que estamos clonando a branch da última release estável no momento da publicação deste artigo.

A última etapa de preparação envolve sincronizarmos o código dos pacotes disponíveis para o OpenWRT:

$ scripts/feeds update -a
$ scripts/feeds install -a

Pronto! Nosso ambiente está preparado. Vamos preparar a configuração da imagem.

Configuração da imagem

Quiser pular essa parte, baixe o meu arquivo de configuração.

Na raíz do projeto, digite o comando abaixo para entrar no menu de configuração:

$ make menuconfig
Screenshot_20200830_170029

Vamos configurar o target (o sistema alvo). No menu selecione “Target System”, e selecione “Broadcom BCM27xx”.

Screenshot_20200830_170029

Em “Subtarget”, selecione “BCM2710 64 bit based boards”. Em “target profile”, “Raspberry Pi 3B/3B+”.

Agora, precisamos selecionar os pacotes que queremos incluir na imagem. Por se tratar de um roteador, acho prudente instalarmos uma interface web (WUI) para facilitar a configuração básica do roteador. O projeto OpenWRT mantém um sub-projeto de um WUI bem intuitivo, chamado LuCI.  Para adicionar a LuCI a imagem, vá em LuCI → Collections → Luci.licação que boqueia os anúncios antes de eles “chegarem” ao browser.

Screenshot_20200830_170813

Recomendo ainda adicionarmos algumas extensões da LuCI:

  • LuCI → Modules → Translations → Brazilian Portuguese (pt_BR)
  • LuCI → Applications → luci-app-adblock
  • LuCI → Themes → luci-theme-material

Ao selecionarmos a opção “luci-app-adblock” o pacote adblock é selecionado automaticamente. Esse pacote contém a aplicação que bloqueia os anúncios antes de eles “chegarem” ao browser.

Vá em “Exit” e salve as configurações.

Compilando a imagem

Agora é tempo de compilar a imagem. Antes de propriamente compilar os pacotes e gerar a imagem, vamos baixar todos os códigos-fonte dos pacotes selecionados no arquivo de configuração (que editamos no passo anterior):

$ make download

Em seguida, vamos compilar:

$ make

Isso pode levar algum tempo. Se quiser acelerar o processo de build, use a opção -j seguida do número de jobs em paralelo (isso depende do seu processador instalado na sua máquina de desenvolvimento – um Core i5 de 4ª geração, por exemplo, tem dois núcleos, e com hyperthreading ele suporta até 4 jobs em paralelo).

$ make -j 4

Ao final do processo você irá encontrar o arquivo openwrt-brcm2708-bcm2710-rpi-3-squashfs-factory.img.gz em bin/targets/brcm2708/bcm2710/. Esse arquivo é a imagem que devemos gravar no SD-Card.

Gravando a imagem no SD-Card

Para gavar a imagem, vamos usar o Balena Etcher, que é a maneira mais fácil de gravar imagens em pendrives, SD-Cards, etc. O processo é simples, carregue o arquivo openwrt-brcm2708-bcm2710-rpi-3-squashfs-factory.img.gz (você pode usar a imagem gerada pelo processo anterior ou baixar uma imagem pronta) na primeira opção, insira o SD-Card no slot do seu PC e, por fim, clique em Flash.

Screenshot_20200902_214303

Configuração de rede

Como nosso roteador é apenas uma prova de conceito, vamos manter a topologia da rede da sua casa, e vamos conectar a Raspberry Pi ao seu roteador, assim você terá uma rede adicional na sua casa:

TOPOLOGIA

Vamos conectar a Raspberry ao roteador (gateway) através da interface cabeada (eth0) e os demais dispositivos da casa, conectar-se-ão a internet através da interface WiFi da Raspberry (wlan0). Entretanto, durante a configuração precisaremos conectar a Rasp ao computador por cabo.

Insira o SD-Card com a imagem que você gravou no passo anterior, e conecte a Rasp ao PC usando o cabo ethernet. Abra o browser e abra o endereço 192.168.1.1:

Screenshot_2020-09-06 OpenWrt - Overview - LuCI

Use a senha root (usuário root) e clique em Login.

Na página principal (overview), localize no menu superior o menu Network. Nesse menu, clique em Wireless.

Screenshot_2020-09-06 OpenWrt - Overview - wireless

Habilite a interface WiFi e aplique as configurações clicando em Save & Apply:

wifi_enable

Vá novamente para o menu Network, mas desta vez clique em Interfaces:

Screenshot_2020-09-06 OpenWrt - interfaces - menu - LuCI

Agora, clique em Add new interface:

create_new_interface

Na tela de edição da interface, coloque o nome WAN no campos name, em Protocol, selecione DHCP client, e por fim, em interface escolha eth0.

Por fim, clique em Create Interface (botão verde).

Edite a interface LAN. Na aba Physical Settings, vá até as opções de interface e desmarque Ethernet Adapter “eth0”. Salve suas configurações (botão verde).

Agora, edite a interface WAN. Na aba General Settings, em protocol, selecione DHCP client.

Na aba Physical Settings, vá até interface e selecione eth0.

Por fim, na aba Firewall Settings, selecione WAN como Firewall Zone. Logo em seguida, salve suas novas configurações.

Agora, temos que aplicar as configurações: clique em Save and Apply.

Desconecte o cabo de rede do PC e conecte ao seu roteador. Sua Rasp deve ganhar um IP e ter conexão a internet.

Instalação do adblock

Se você compilou a própria imagem usando os passos apresentados mais acima, então você pode pular esta seção.

No menu superior, vá em System > Software.

Primeiramente, precisamos sincronizar a lista de pacotes. Para isso, clique em Update Lists.

Agora, filtre os pelo nome luci-app-adblock e clique em Install.

De maneira semelhante, instale também o pacote curl.

Reinicie a Raspberry Pi, em System > Reboot.

Configuração do adblock

A última etapa é a configuração do Adblock. Para configurá-lo, no menu superior, vá a Services > Adblock.

Na aba Additional Settings,

Desça até aparecer a opção Download Utility. No menu, selecione curl.

O serviço adblock depende de listas de sites e urls a serem bloqueadas, que podem ser adicionadas na aba Black List Sources. Como exemplo, vamos adicionar a lista youtube, que permite o bloqueio de anuncios no YouTube.

Após, salve e aplique as configurações, clicando no botão azul Save & Apply. Recomendo um reboot (System > Reboot), para garantir que tudo irá funcionar.

Pronto! Agora, conecte seus dispositivos rede OpenWRT e navegue sem anúncios e trackers.

Conteúdo sob licensa CC BY-SA 4.0.

Sistemas Embarcados

Primeiros passos com a NodeMCU no Fedora

Recentemente comprei uma placa de desenvolvimento chamada NodeMCU. A NodeMCU é projeto open hardware e open software que permite começar muito rapidamente o desenvolvimento de aplicações de IoT no módulo ESP-12E (ESP8266).

img_20161203_092248

Preparando o ambiente

Eu utilizei uma máquina com Fedora 23. Primeiro, iremos instalar algumas dependências:

$ sudo dnf install git picocom

O git é um versionador de código, iremos precisar dele para baixar o código de algumas ferramentas. O picocom é um terminal serial. Se você preferir pode utilizar outro terminal serial, sem problemas.

Instalando a firmware NodeMCU

A firmware do NodeMCU permite que conectemos a um interpretador Lua com uma biblioteca de controle de hardware built-in, que é excelente para começar a programar.

Infelizmente, as versões mais recentes da firmware são distribuidas apenas por binários. Como queremos começar imediatamente, vamos baixar a versão 0.9.6 que foi a última a ser lançada em formato binário (NOTA: Em outra oportunidade irei ensinar como compilar a versão mais recente).

Abra o terminal e baixe a firmware com o wget:

$ https://github.com/nodemcu/nodemcu-firmware/releases/download/0.9.6-dev_20150704/nodemcu_integer_0.9.6-dev_20150704.bin

Agora, precisamos clonar o código do esptool, que é uma ferramenta para gravar a firmware no módulo.

$ git clone https://github.com/themadinventor/esptool.git

Após concluído o download, acesse o diretório esptool e rode o comando abaixo para instalar as dependências do esptool:

$ cd esptool
$ python setup.py build
$ sudo python setup.py install

Por fim, vamos gravar a firmware:

sudo python ./esptool.py --port /dev/ttyUSB0 write_flash -fm dio 0x00000 ../nodemcu_integer_0.9.6-dev_20150704.bin
[sudo] password for jaufranc:
Connecting...
Erasing flash...
Writing at 0x00048000... (90 %)
Wrote 450560 bytes at 0x00000000 in 44.3 seconds (81.3 kbit/s)...

Leaving...

Ligar/Desligar um led

Como já é de praxe, sugiro que o primeiro programa seja piscar um led. A placa já conta com um led, ligado ao D0, o que facilita o nosso primeiro teste.

Abra o picocom e aponte para o conversor USB-serial da NodeMCU (geralmente, em /dev/ttyUSB0):

$ picocom -b 9600 /dev/ttyUSB0

Pressione o botão RST da placa, você deve ver o seguinte no terminal:

NodeMCU 0.9.6 build 20150704  powered by Lua 5.1.4
lua: cannot open init.lua

Digite os comandos abaixo diretamente nesse terminal:

pin = 0
gpio.mode(pin,gpio.OUTPUT)

No trecho acima, criamos uma variável pin que recebeu o valor 0, que correponde ao pino ao qual o led da placa está ligado. Na segunda linha, o comando gpio.mode determina qual o modo do pino, neste caso queremos que ele seja um pino controlável, portanto de saída, logo setamos ele com gpio.OUTPUT (atente-se as letras maiúsculas, pois o Lua é uma linguagem case-sensitive). Após esses comandos o Led deve estar aceso.

Para apagar o led, use o comando gpio.set:

gpio.write(pin, gpio.HIGH)

Para voltar a acendê-lo:

gpio.write(pin, gpio.LOW)

Próximos passos

No site do NodeMCU há alguns exemplos bem legais, como o código para criar um pequeno servidor http.

Referências

  1. http://www.cnx-software.com/2015/10/29/getting-started-with-nodemcu-board-powered-by-esp8266-wisoc/
  2. http://www.nodemcu.com/index_en.html#fr_54747661d775ef1a3600009e
Linux device drivers

Boot da kernel pela rede

Neste post vou mostrar como configurar o seu host para hospedar uma versão cross-compilada da kernel, para ser “bootada” pela Raspberry Pi através de uma rede.

Let’s hack it?!

Configuração

No diagrama da figura abaixo, exemplifico uma maneira de criar uma rede entre a Rpi e o host. Como pode-se notar, configurei um IP fixo paLDD: LDD: ra a porta ethernet do meu PC e um IP fixo (mostrarei mais adiante como fazer isso) para a Rpi, ligados diretamente um ou outro através de um cabo de rede comum.

Raspberry_PC

TFTP

Vamos preparar o nosso host para hospedar a kernel compilada.

O primeir passo é instalar o tftp-server:

# dnf install tftp-server

Agora, vamos checar se o serviço tftp está liberado no firewall do Fedora, para isso digite no terminal:

$ firewall-cmd --zone=public --list-all

Na linha services procure por tftp. Se você não encontrar, então precisamos liberar esse serviço:

# firewall-cmd --zone=public --add-service=tftp

NOTA: Para não precisar adicionar essa regra ao firewall toda vez que quisermos bootar pelo tftp, adicione o parâmetro –permanent ao comando acima.

Clonando a kernel

Para testarmos nosso setup do tftp, vamos compilar uma versão da kernel.

Primeiro, vamos clonar uma versão do repositório.

NOTA: Como você deve estar seguindo o linux-kernel-labs.pdf da free-electrons (assim como eu),  sugiro que você siga as instruções de lá. Vou reproduzi-las aqui com algum atalho, mas sugiro fortemente que você dê uma olhada nos capítulos “Downloading kernel source code” e “Kernel source code” daquele pdf.

$ git clone http://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
$ cd linux
$ git remote add stable git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
$ git fetch stable

Esse processo deve demorar um pouco, dependendo da velocidade da sua conexão com a internet.

Confira as branches disponíveis:

$ git branch -a

Nós vamos utilizar a versão estável (stable) 4.1  :

$ git checkout -b 4.1.y stable/linux-4.1.y

Compilando a kernel

Vamos compilar a kernel clonada no passo anterior para podermos testar nosso setup.

Como no post anterior sobre o U-boot, precisamos setar a variável CROSS_COMPILE. Também precisamos setar a variável ARCH, que indica para qual arquitetura a kernel será cross-compilada.

 $ export ARCH=arm $ export CROSS_COMPILE=arm-linux-gnu- 

Estamos prontos para cross-compilar a kernel Linux.

$ make bcm2835_defconfig
$ make -j4 zImage dtbs

O primeiro make cria um arquivo de configuração específica para nossa Rpi (BCM2835 é o SOC da Raspberry Pi model B).
O segundo make cross-compila a kernel, gerando um arquivo compactado zImage e o arquivo do dtb (Device Tree Blob).

Por fim, copie os artefatos gerados para o diretório /var/lib/tftpboot/:

# cp ./arch/arm/boot/zImage /var/lib/tftpboot
# cp ./arch/arm/boot/dts/bcm2835-rpi-b.dtb /var/lib/tftpboot/

Bootando pela rede com U-boot

Abra seu terminal serial e ligue a Rpi a energia. Pressione Enter para interromper o U-boot.

Você deverá ver o terminal d U-boot (U-Boot>_).

Primeiro vamos configurar a rede, inicializando os dispositivos USB (a porta ethernet está conectada pelo barramento USB da Rpi), e indicando o IP da Rpi e do servidor tftp:

U-Boot> usb start
U-Boot> setenv ipaddr 192.168.0.2
U-Boot> setenv serverip 192.168.0.1

Em seguida, vamos fazer o download dos artefatos hospedados no nosso host (servidor tftp):

U-Boot> tftpboot ${scriptaddr} bcm2835-rpi-b.dtb
...
U-Boot> tftpboot ${kernel_addr_r} zImage
...

Se tudo ocorreu certo você deve ter recebido mensangens como “Bytes transferred = 3967 (f7f hex)”, sendo que o número pode variar, dependendo se você mexeu nas configurações da kernel, dentre outros fatores.

E finalmente, vamos “bootar” a kernel. Primeiro setamos a variável bootargs, que contém os parâmetros da kernel, como o qual porta serial (UART) a kernel deve direcionar suas mensagens, e, ainda, indicar a localização do rootfs. Neste exemplo, eu estou utilizando o rootfs do SDCard que criei com o ArchLinux.

U-Boot> setenv bootargs console=ttyAMA0 console=tty1 root=/dev/mmcblk0p2 rootwait
U-Boot> bootz ${kernel_addr_r} - ${scriptaddr}

O comando setenv configura variáveis no U-boot, e o comando bootz carrega a kernel que está armezanada na memória (o armazenamanto ocorreu no passo do tftpboot, mais acima no post).

Se tudo ocorreu corretamente, você deve ver as mensagens de boot da kernel:

Kernel image @ 0x1000000 [ 0x000000 - 0x371b28 ]
## Flattened Device Tree blob at 02000000
   Booting using the fdt blob at 0x2000000
   Using Device Tree in place at 02000000, end 02003f7e

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Initializing cgroup subsys cpuacct
[    0.000000] Linux version 4.1.20 (rnunez@localhost.localdomain) (gcc version 5.3.1 20160212 (Red Hat Cross 5.3.1-2) (GCC) ) #2 Sun Apr 3 16:34:18 BRT 2016
[    0.000000] CPU: ARMv6-compatible processor [410fb767] revision 7 (ARMv7), cr=00c5387d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
[    0.000000] Machine model: Raspberry Pi Model B
[    0.000000] Memory policy: Data cache writeback
...

No próximo post iremos criar um módulo para kernel. Até lá! 😉

Referências:

[1] http://wiki.beyondlogic.org/index.php?title=Raspberry_Pi_Building_Mainline_Kernel
[2] http://blog.christophersmart.com/2014/01/15/add-permanent-rules-to-firewalld/
[3] http://www.informit.com/articles/article.aspx?p=1647051&seqNum=5

Linux device drivers

U-boot na Raspberry Pi

Neste estudo estou usando como base o material gratuito da Free-electrons, que é uma empresa francesa que disponibiliza, dentre outros serviços, treinamento na área de Linux Embarcado. Se você der uma olhada no material, perceberá que o curso usa uma BeagleBone Black como target, como eu não tenho uma BBB e sou fã da Raspberry Pi, decidi “traduzir” as instruções do labs da Free-electrons para a Raspberry Pi. Essa “tradução” não será literal, e irá sendo postada aos poucos, a medida que eu for avançando no assunto.

O que é U-boot? Por que precisamos dele nessa série?

O Das U-boot (a.k.a U-boot) é um bootloader muito utilizado em sistemas embarcados. Em nossa jornada de desenvolvimento de drivers para Linux, ele será útil para bootarmos as diferentes versões da kernel que geraremos ao longo do caminho. Com ele, por exemplo, é possível bootarmos a kernel pela rede, o que evita de ficarmos tirando o SDCard toda a hora da Rpi.

Material Utilizado

Nosso target será uma Raspberry Pi model B rev. 2, a mais comum das Rpi. O nosso host é um Notebook x86_64 com Fedora 23.

Além do host e da target precisaremos ter acesso ao terminal serial da Rpi, para isso usamos um conversor TTL-Serial (UART-RS232) ou TTL-USB (geralmente baseado no C.I. FTDI FT232), facilmente encontrado em lojas especializadas em eletrônica.

Preparando o ambiente

Primeiro vamos instalar as ferramentas necessárias para cross-compuilar o U-boot. Abra uma janela do terminal e digite:

# dnf install gcc-arm-linux-gnu gcc-c++-arm-linux-gnu binutils-arm-linux-gnu

Com as ferramentas em mãos, vamos, agora, clonar o repositório do U-boot:

 $ git clone git://git.denx.de/u-boot.git 

Compilando…

Compilar o U-boot é muito simples. Antes de mais nada, precisamos setar a variável CROSS_COMPILE com o valor do prefixo das ferramentas de desenvolvimento que instalamos no primeiro passo apresentado:

$ export CROSS_COMPILE=arm-linux-gnu-

Em seguida, acesse a pasta u-boot, que foi criada com o comando clone do git. Dentro da pasta utilize o comando make para criar a configuração para a Raspberry Pi (v1 model B):

$ make rpi_defconfig

O comando acima cria um arquivo de configuração (.conf) no diretório do u-boot, com um preset para compilar o u-boot corretamente para a Raspberry Pi.

Agora, para compilar, digite make no terminal:

$ make

Após o processo, perceba que alguns arquivos foram criados, dentre eles o u-boot.bin, que o arquivo que usaremos para rodar o u-boot na Rpi.

No seu PC, monte a partição BOOT (a de menor tamanho, em torno de 105MB) do SDCard com o sistema operacional para a Rpi, como por exemplo, o Arch Linux ou o Raspbian. Mude o nome dos arquivos kernel.img e config.txt:

$ mv kernel.img kernel.img.old
$ mv config.txt config.txt.old

Agora, copie o arquivo u-boot.bin para a partição BOOT do SDCard:

$ cp u-boot.bin /mnt/boot/

Desmonte as partições do SDCard e insira-á na Rpi. Ligue o cabo de rede a um roteador ou a uma rede com DHCP, e ligue também os pinos UART a um conversor TTL-Serial ou TTL-USB. Abra um terminal serial e observe que o output:

U-Boot 2016.03-00394-gd085ecd (Mar 25 2016 - 17:11:41 -0300)

DRAM: 448 MiB
RPI Model B rev2 (0xe)
MMC: bcm2835_sdhci: 0
reading uboot.env

** Unable to read "uboot.env" from mmc0:1 **
Using default environment

In: serial
Out: lcd
Err: lcd
Net: Net Initialization Skipped
No ethernet found.
starting USB...
USB0: Core Release: 2.80a
scanning bus 0 for devices... 4 USB Device(s) found
 scanning usb for storage devices... 0 Storage Device(s) found
 scanning usb for ethernet devices... 1 Ethernet Device(s) found
Hit any key to stop autoboot: 0
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...

USB device 0: unknown device
Waiting for Ethernet connection... done.
BOOTP broadcast 1
DHCP client bound to address 10.42.0.159 (55 ms)
*** Warning: no boot file name; using '0A2A009F.img'
Using sms0 device
TFTP from server 10.42.0.1; our IP address is 10.42.0.159
Filename '0A2A009F.img'.
Load address: 0x200000
Loading: T T

Percebe-se que o processo de boot agora passa pelo U-boot, e não vai mais diretamente a kernel do Linux como anteriormente. Com esse recurso novo podemos carregar a kernel do Linux através da rede, via tftp, que é mais conveniente para o propósito de desenvolvimento de drivers para Linux. A montagem do servidor tftp será o assunto do próximo post.

Linux, Sistemas Embarcados

Arch Linux na Raspberry Pi

Sexta a noite, chovendo, a sky não estava funcionando, parei e pensei: Por que não testar uma nova distro na minha raspberry? Há tempos vinha flertando com o Arch Linux, que é uma distribuição levinha e voltada para os ‘shiitas’ Linux. Pois bem, a oportunidade de testá-la chegou! A seguir, vou mostrar como gravar uma imagem no sdcard e em seguida como conectá-la ao wifi.

Se você não conhece o Arch Linux, recomendo primeiro acessar o site do Arch Linux para ARM, archlinuxarm.org . Nesse site encontraremos diversas imagens para os mais diversas Single Board Computers dentre elas as queridas Raspberry Pi.

Ambiente

Estou utilizando o Fedora 22 em PC x86_64, uma Raspberry Pi model B e um dongle wifi com chipset Realtek RTL8188CUS.

A imagem do Arch

A melhor forma de conhecer é mexendo, essa é a filosofia ‘hacker’, portanto mãos à massa!

Abra o terminal, e baixe a imagem usando o wget:

$ wget http://archlinuxarm.org/os/ArchLinuxARM-rpi-latest.tar.gz

Enquanto a imagem baixa, vamos instalar o bsdtar (se você já o tiver, pule esta parte):

$ sudo dnf install bsdtar

O BSDTar é uma implementação do Tar, para esse tutorial utilizaremos o BSDTar seguindo a recomendação do pessoal do Arch.

Vamos, também, criar duas pastinhas

$ sudo mkdir /mnt/{rootfs,boot}

Agora, insira o cartão sdcard(no meu pc /dev/sdb, cuidado pois no seu provavelmente será diferente, confira antes com o dmesg) no seu PC para criarmos duas partições nele usando o cfdisk:

$ sudo cfdisk /dev/sdb

Dentro do cfdisk, delete todas as partições do seu sdcard, em seguida crie duas novas partições primárias, a primeira com 100MB, tipo W95 FAT32 (opção c) e a segunda com o restante de  espaço e tipo Linux(opção 83). O resultado deve ser uma tabela como a mostrada abaixo:

    Device          Boot     Start      End  Sectors   Size  Id Type
>>  ./dev/sdb1      	      2048    206847   204800   100M   c W95 FAT32 (LBA)
    ./dev/sdb2              206848  4194303  3987456   1.9G  83 Linux

Com as partições criadas, vamos formataá-las, a menor com um sistema de arquivos FAT32 e a maior com um sistema de arquivos EXT4:

$ sudo mkfs.vfat /dev/sdb1
$ sudo mkfs.ext4 /dev/sdb2

A essa altura, o download da imagem do Arch já deve estar pronto. Descompacte-o na pasta /mnt/rootfs como root (não use o sudo) montada na partição Linux:

# mount /dev/sdb2 /mnt/rootfs
# bsdtar xpf ArchLinuxARM-rpi-latest.tar.gz -C /mnt/rootfs

A descompactação não deve demorar muito. Assim que acabar, monte a partição FAT32 em /mnt/boot e copie todos os arquivos de /mnt/rootfs/boot para dentro dela:

# cp -r /mnt/rootfs/boot/* /mnt/boot

Desmonte as partições e estamos prontos para decolar.

NOTA: Perceba que a desmontagem pode demorar um pouco devido a sincronização da memória com o sdcard, você pode acompanhar o andamento através seguinte comando:

$ watch grep -e Dirty: -e Writeback: /proc/meminfo

A sincronização se encerra quando o campo Dirty chega a zero.

Rodando a imagem

Insira o sdcard na Raspberry e conecte-a ao seu roteador via cabo. Conecte também o dongle wifi(caso você tenha um). Decubra o ip dela (no meu caso 10.0.0.102) e estabeleça conexão via ssh(user: alarm, pass: alarm):

$ ssh alarm@10.0.0.102

Se você tem o dongle wifi, precisaremos instalar alguns apps:

$ su
Password: root
# pacman -S wpa_supplicant dialog

Com as ferramentas instaladas, a habilitaremos o dongle,

# ip link set wlan0 up

E configuraremos a conexão:

# wifi-menu

Selecione sua rede e digite a senha. Simples, né?!

Se fosse foi desastrado como eu e errou a senha, basta apagar o arquivo de profile criado pelo wifi-menu:

# rm /etc/netctl/wlan-Rede

Se você conseguiu conectar a rede, e quiser que seu wifi sempre fique habilitado, rode o comando abaixo:

# netctl list
# netctl enable <resultado do comando anterior>

E agora?

Chegamos ao final do tutorial. Agora temos rede (sem fio! Uhul!) e um vasto caminho de conhecimento a percorrer. Um dos pontos fortes do Arch é a sua documentação e sua comunidade. Não deixe de visitar o forum e a wiki do projeto.

Divirta-se!

Linux

Listando as redes wi-fi usando Python

No post de hoje, vou ensinar a listar as redes wi-fi usando python ao invés de comandos do shell. Você deve estar se perguntando: “Mas pra quê?” Bueno, você poderia criar uma pequena aplicação que gerencia duas redes wi-fi, escolhendo a com sinal mais forte e se conectando a ela. Ou, listar as redes wifi de um computador remotamente, e por ai vai.

Para isso vamos utilizar a biblioteca wifi, que nada mais é que um wrapper para o iwlist e o arquivo /etc/network/interfaces.

Instalando a biblioteca

A instalação é muito simples, basta o usar o pip:

$ sudo pip install wifi

Se você ainda não conhece o pip, tem uma apresentação no slideshare que apresenta muito bem a ferramenta. (http://www.slideshare.net/pugpe/pip-5939243)

Utilizando para listar as redes ao alcance

Bora programar! Abra o shell do python como root (ou com previlégios usando o sudo, se não o fizer assim não vai funcionar) e digite o seguinte:

from wifi import Cell
cells = Cell.all('wlan0')
for cell in cells:
    print cell.ssid

Inicialmente importamos a classe Cell, que é  o wrapper, de fato, do iwlist. Em seguida, solicitamos os output do iwlist através do método all. Esse método retorna uma lista de objetos, cada um representando uma rede que o iwlist encontrou. O parâmetro que passamos ao all é uma string com o nome da sua interface wifi – Para descobrir qual o nome da sua, use o iwconfig no terminal.

Esses objetos tem diversos atributos, cada qual representa uma informação sobre cada rede. No nosso exemplo, o atributo ssid é o “nome” da rede. Há vários outros que nos revelam informações interessantes sobre as redes ao nosso arredor, para os conhecer, dê uma olhada na documentação da biblioteca.

Listando a rede e a sua potência

No próximo programinha, vamos atribuir a cada rede, a potência que o nosso adaptador de rede mediu. Em seguida, vamos classificar em ordem do sinal mais forte para o mais fraco, indicando a “melhor” rede.

from wifi import Cell

cells = Cell.all('wlp2s0')
cell_power = []

for cell in cells:
    cell_power.append((cell.ssid, cell.signal))

cell_power.sort(key=lambda cell_signal:cell_signal[1], reverse=True)

print cell_power

A iteração do laço, adicionamos um tuple a lista cell_power. Em seguida, utilizamos o método sort para ordenar essa lista, usando como critério o segundo elemento do tuple que criamos no laço.

NOTA: Se estiver com alguma dúvida em relação ao lambda, 
dê uma olhadinha nesse link que você vai entender. :D

Muito bem, apresentamos a pequena biblioteca wifi e colocamos dois exemplinhos para ajudar. Espero que isso ajude você algum dia! Até a próxima!

IoT

Bottle: IoT fácil na Raspberry Pi com Python

A Internet das Coisas (IoT, na sigla em inglês) é onda do momento no mundo Maker. E colocar nossas “coisas” na rede está ficando cada vez mais fácil. Neste artigo, vou ensinar como utilizar o Bottle para colocar a Raspbery Pi como um servidorzinho web e servir dados a outros dispositivos através da rede, ou mesmo, controlá-la via web.

O pacote Bottle
O Bottle[1] é uma micro framework web para Python. O projeto é open-source, e seu código-fonte, sob licensa MIT, está disponível no Github[2].

Uma das coisas mais legais que eu achei do Bottle, é que ele é distribuído em um único arquivo .py, e a única dependência é a Python Standard Library.

HelloBottle
Para nos familizarmos com a framework, nada melhor que o bom e velho HelloWorld (a.k.a HelloBottle). Mas antes de mais nada, vamos criar um diretório de trabalho e baixar o bottle:

$ mkdir hello_bottle
$ cd hello_bottle
$ wget https://github.com/bottlepy/bottle/raw/master/bottle.py

Através do download direto, baixamos a versão mais recente do bottle, com o ônus de ela poder ser um pouco instável. Se você se preocupa com isso, instale-o através do pip ou do easy_install.

Ótimo, com o pacote em mão podemos podemos prosseguimos para o código:

from bottle import run, route

@route('/hello')
def test_bottle():
return 'Olá mundo!'

run(host='0.0.0.0', port=8080)

Na primeira linha,

from bottle import run, route

do pacote bottle, importamos as funções run e route.

No trecho,

@route('/hello')
def test_bottle():
return 'Olá mundo!'

Definimos que ao chamarmos o http://<endereço_da_rpi>/hello executaremos a função test_bottle. O client receberá a string retornada da função, que nada mais é que uma página html.

A função run(),

run(host='0.0.0.0', port=8080)

é responsável por rodar o nosso servidorzinho. O parâmetro “host” indica qual o endereço que o servidor escutar. Passando 0.0.0.0 indicamos que qualquer endereço pode acessar nosso servidor. Se você pusesse 127.0.0.1, você só conseguiria acessar o servidor a partir da própria Raspberry, o que é interessante somente para testes. Já o parâmetro “port”, define qual porta o servidor escuta, no caso, a porta 8080.

Para rodar o nosso teste, salve o arquivo hello_bottle.py com o código acima, e digite no terminal:

$ python hello_bottle.py

em outra instância do terminal, descubra o endereço ip da sua Raspberry, digitando:

ifconfig eth0

Abra um browser em outro computador na mesma rede e digite na barra de endereços, substituindo 10.0.0.110 pelo endereço da sua Raspberry:

http://10.0.0.110:8080/hello

No browser , você deve ler Olá Mundo!.

Conversando com o servidor: Pegando a temperatura da CPU
A idéia não é ficar retornando páginas html, mas sim dados que possam ser manipulados por outros servidores, páginas dinâmicas ou por um app em um celular. Para isso, quando requisitado, ao invés de retornar uma string com um código html, vamos retornar dados no formato JSON[3]. Nesse formato, os dados são melhor manipuláveis e podem ser integrados a páginas dinâmicas(AJAX) e tudo mais.

No próximo exemplo, vamos ler a temperatura da CPU da Raspberry, e retornar em formato JSON para que possa ser lida por outras aplicações.

from bottle import route, run, response
import json

@route('/temperature')
def getTemperature():
file = open('/sys/class/thermal/thermal_zone0/temp')
cpu_temp = int(file.read())/1000.0
file.close()

response.content_type = 'application/json'
cpu_temp_json = json.dumps({"temperature":str(cpu_temp)})

return cpu_temp_json

if __name__ == '__main__':
run(host='0.0.0.0', port=8080)

No código acima, percebemos uma mudança, em relação ao “hello world” do código anterior, já nas duas primeiras linhas:

from bottle import route, run, response
import json

veja que importamos mais dois objetos: response do pacote bottle e o json, que é nativo.

Em seguida, definimos a função getTemperature():

@route('/temperature')
def getTemperature():
file = open('/sys/class/thermal/thermal_zone0/temp')
cpu_temp = int(file.read())/1000.0
file.close()

response.content_type = 'application/json';
cpu_temp_json = json.dumps({"temperature":str(cpu_temp)})

return cpu_temp_json

Primeiro, abrimos o arquivo temp, localizado em /sys/class/thermal/thermal_zone0/, para leitura. Na linha seguinte, dividimos o valor lido por 1000, e o resultado será o valor da temperatura da cpu em grau Celsius.

As três linhas seguintes determinam o tipo de resposta que o servidor entregará ao cliente:

response.content_type = 'application/json'
cpu_temp_json = json.dumps({"temperature":str(cpu_temp)})

return cpu_temp_json

Primeiro, setamos o tipo de resposta para “application/json” através do response.content_type. Segundo, gravamos na variável cpu_temp_json, o resultado da serialização da temperatura com uma chave(json key) chamada “temperature”. Em seguida, retornamos cpu_temp_json. Assim, quando fizermos a requisição através do endereço http://10.0.0.110:8080/temperature, a resposta será do tipo JSON.

json

E agora?

Bueno, a partir daqui você já pode sair controlando a sua Raspberry Pi através de sua rede local. Com um pouco de configuração em seu roteador será possível controla-lá não só na rede local, mas através da internet também. Vale a pena dar uma pesquisada.

Que tal controlar o I/O, ler um sensor, ou mesmo rebootar sua Rasp pela rede? Legal, né?Mas isso é assunto para outros posts… Até lá! 🙂

Referências:
[1] http://bottlepy.org/docs/dev/index.html
[2] https://github.com/bottlepy/bottle
[3] http://json.org/

Linux

Configurar a identação do Vim

Para configurar a identação do Vim para quatro espaços ao invés do “default” de 8 espaços, basta digitar o seguinte:

:set tabstop=4

Se tu reiniciares o Vim, perceberás que a identação volta ao padrão. Para tornar a mudança permanente, :basta editar (ou criar) o arquivo .vimrc na sua “home” e inserir o texto:

set tabstop=4

fonte: http://stackoverflow.com/questions/1878974/redefine-tab-as-4-spaces

Sistemas Embarcados

Configuração headless da Raspberry Pi

O post de hoje é uma dica pra quem quer usar a Raspberry pi e não tem um monitor ou uma TV com hdmi sempre disponível. Aqui em casa, por exemplo, eu preciso liberar a TV pra minha esposa poder assistir a novela! :p

Configuração da Raspberry Pi

Primeiro, vamos instalar o x11vnc na rpi (eu uso a distro raspbian) que é um servidor VNC:


sudo apt-get install x11vnc

Após instalar o servidor de vnc, vamos configurar a resolução da rpi:


sudo nano /boot/config.txt

Descomente as linhas (removendo o ‘#’ do incio da linha):


disable_overscan=1

hdmi_force_hotplug=1

hdmi_group=1

hdmi_mode=1

Substitua o valor dos campos hdmi_group e hdmi_mode para os seguintes:


hdmi_group=2

hdmi_mode=28

Com essa configuração habilitamos a rpi a usar a resolução 1280×800@60Hz, que é a resolução do meu PC. Você pode escolher outra mais apropriada a resolução do seu PC, para tal sugiro que consulte a tabela do elinux.

Se tu ainda não fizeste, habilite a rpi para chamar a interface gráfica já no boot:


sudo raspi-config

Selecione a opção 3: “Enable Boot to desktop” e na próxima tela selecione “yes”.

Finalmente, configure o LXDE (o window manager) para subir o x11vnc junto com ele. Para tal, siga os passos a seguir:


mkdir -p ~/.config/lxsession/LXDE/

echo "@x11vnc -forever" > ~/.config/lxsession/LXDE/autostart

A opção “-forever” indica que o após desconectar, o servidor deve continuar rodando.

Configuração do PC

No teu pc, tu vais precisar apenas de um cliente VNC. No Fedora 18, eu instalei o Remmina e o plugin dele para conectar a servidores VNC:


sudo yum install remmina remmina-plugins-vnc -y

A interface do remmina é bastante intuitiva, para configurar uma nova conexão basta clicar no icone do folha de papel com um “+”.

remmina

Na tela que surge, complete o campo server é o mais importante, insira ai o endereço IP da Rpi (para descobrir digita no terminal da rpi: ifconfig eth0 e copia o valor do campo ipaddr).

remmina_editor

Clique em Connect e pronto! A tela da tua Raspberry Pi deve surgir em uma janela!

Agora é só hackear e programar ( e deixar tua TV livre!) ^^

FONTES:

http://www.raspberrypi.org/phpBB3/viewtopic.php?f=26&t=19600

http://elinux.org/RPiconfig

https://wiki.archlinux.org/index.php/LXDE#autostart_file

Sem categoria

Aprendendo gratuitamente a programar na web, é possível?

Buenas indiada!

Sabia que é possível aprender e se profissionalizar na internet? Melhor ainda: gratuitamente?! Eu reuni alguns links que eu já utilizei para estudar( ou não) com aulas de linguagens de programação, sistemas embarcados, eletrônica e por ai vai. Por que nem só de Facebook vive o nerd!

Linguagens de programação

Ultimamente, eu tenho descoberto muita coisa com ajuda do Google e do meu professor de Java (Eduardo “Bisso” @ervcarval) . O próprio Bisso tem um canal super bacana de vídeo-aulas de Java no Youtube, onde ele ensina o os fundamentos da linguagem e o uso de algumas ferramentas através do desenvolvimento de um projeto.

Se Java não é o que tu procuras, que tal Python? Eu utilizei muito um livro brasileiro e grátis, o “Python para desenvolvedores, 2a edição” O foco dele não são os noobs em programação, mas quem já sabe programar e quer aprender Python (que por sinal, é uma ótima linguagem!).

Pra galera mais hardcore, baixo nível mesmo, eu recomendo o site do Alex Allain o http://www.cprogramming.com que tem tutoriais e posts sobre C/C++ do mais básico e fundamental ao recursos mais avançados. Ele publicou um livro recentemente, mas infelizmente não é grátis… 😦

Academia de programação

Durante as pesquisas para escrever este post, eu achei uma ferramenta muito tri.. Não, muito mais que isso: Realmente Punk! O Code Academy! O CA surgiu no final de 2011 e na primeira semana de vida já tinha 200.000 alunos! Na minha singela opinião, o sucesso se deve ao formato de EAD de programação apresentado por eles, que eu acredito ser o futuro desse tipo de plataforma. Funciona assim: Tu te cadastra, ou usa tua conta das redes sociais, e já sai programando, no browser mesmo… Simples assim! A página apresenta um fundamento da linguagem no lado esquerdo, por exemplo declaração de variáveis, e a direita um emulador de terminal para realizar um exercício prático. O resultado sai na hora. A medida que se evolui no curso se ganha medalhas e se pode compartilhar com os amigos nas redes sociais. Há cursos de Javascript, Python, Ruby, JQuery e PHP.

Finalmentes, só que não…

O assunto é muito vasto e há outros cursos e tutoriais sobre esses e outros assuntos relacionados a programação espalhados pela rede. Por exemplo, eu não falei da Softblue oferece um curso de banco de dados gratuitamente, com partes práticas e teóricas, com direito a certificado e tudo mais. Tu podes, ainda, procurar no Youtube por video-aulas e screencast, há vários canais de pessoas e/ou organizações que postam videos realmente legais. Há, ainda, verdadeiras universidades virtuais com o Udacity, o EdX e o Coursera. Enfim, há diversas opções…

Tem sugestões? Acha que eu esqueci de citar algum serviço ou canal? Posta ai nos comentários, vivente!

Nos próximos post vou mostrar que não é só programação que se pode aprender na web.

Até mais!