sabato 5 luglio 2014

Bootable SD Card Cloning


Bootable SD Card Cloning

(OpenSuse 11.4)

DISCLAIMER
If you don't know what you do, you can seriously damage your system with the commands used in this post. Please DOUBLE CHECK any command you run, and be absolutely sure to understand what it does before hitting "ENTER" or copy/paste as a dumb. If you are in doubt, DON'T DO IT! You have been warned.
You want to clone on an SD card your bootable OpenSuse 11.4 Linux installation and be able to boot from the SD card itself. Or you simply want to clone a bootable SD card or USB flashpen into another one.
  • Solution 1: use clonezilla
  • Solution 2: you want to do it manually for some reason
This article is about solution 2. You should not do this on a running system, so your source SD card or hard disk can not be running while doing that. You must have another system running and use it. All commands used here need root privileges.

You must follow the steps below:
  • Partition the target SD card
  • Format the target SD card
  • Copy the system directories
  • /etc/fstab adapting
  • Install the bootloader
We suppose the target SD card being /dev/sdc and the source being dev/sdg.
My system language setting is Italian, so some of the outputs shown here are in italian.

Partitioning & Formatting

/dev/sdc must be unmounted.

Start fdisk:
  # fdisk /dev/sdc

Delete all the existing partitions (usually one):
  Comando (m per richiamare la guida): d
  Partizione selezionata 1

Create two partitions, one for the system and one for the swap:
  Comando (m per richiamare la guida): n
  Azione comando
      e   estesa
     p   partizione primaria (1-4)
  p
  Numero della partizione (1-4, predefinito 1): 
  Utilizzo del valore predefinito 1
  Primo settore (2048-62333951, predefinito 2048): 
  Utilizzo del valore predefinito 2048
  Last settore, +settori or +size{K,M,G} (2048-62333951, predefinito 62333951): 61285375
  
  Comando (m per richiamare la guida): n
  Azione comando
      e   estesa
     p   partizione primaria (1-4)
  p
  Numero della partizione (1-4, predefinito 2): 
  Utilizzo del valore predefinito 2
  Primo settore (61285376-62333951, predefinito 61285376): 
  Utilizzo del valore predefinito 61285376
  Last settore, +settori or +size{K,M,G} (61285376-62333951, predefinito 62333951): 
  Utilizzo del valore predefinito 62333951
  
  Comando (m per richiamare la guida): t
  Numero della partizione (1-4): 2
  Codice esadecimale (digitare L per elencare i codici): 82
  Modificato il tipo di sistema della partizione 2 in 82 (Linux swap / Solaris)
  
  Comando (m per richiamare la guida): a
  Numero della partizione (1-4): 1
  
  Comando (m per richiamare la guida): p
  
  Disk /dev/sdc: 31.9 GB, 31914983424 bytes
  64 testine, 32 settori/tracce, 30436 cilindri, totale 62333952 settori
  Unità = settori di 1 * 512 = 512 byte
  Sector size (logical/physical): 512 bytes / 512 bytes
  I/O size (minimum/optimal): 512 bytes / 512 bytes
  Identificativo disco: 0x00000000
  
  Dispositivo Boot      Start         End      Blocks   Id  System
  /dev/sdc1   *        2048    61285375    30641664   83  Linux
  /dev/sdc2        61285376    62333951      524288   82  Linux swap / Solaris

Save and exit:
  Comando (m per richiamare la guida): w
  La tabella delle partizioni è stata alterata!
  
  Chiamata di ioctl() per rileggere la tabella delle partizioni.
  Sincronizzazione dei dischi in corso.

Now format the partitions:
  # mkswap /dev/sdc2
  Setting up swapspace version 1, size = 524284 KiB
  nessuna etichetta, UUID=94e66236-e300-4b7d-83aa-c8baaf48c088
  #
  # mkfs.ext3 /dev/sdc1
  mke2fs 1.41.14 (22-Dec-2010)
  Etichetta del filesystem=
  Tipo SO: Linux
  Dimensione blocco=4096 (log=2)
  Dimensione frammento=4096 (log=2)
  Stride=0 blocks, Stripe width=0 blocks
  1916928 inode, 7660416 blocchi
  383020 blocchi (5.00%) riservati per l'utente root
  Primo blocco dati=0
  Maximum filesystem blocks=0
  234 gruppi di blocchi
  32768 blocchi per gruppo, 32768 frammenti per gruppo
  8192 inode per gruppo
  Backup del superblocco salvati nei blocchi: 
          32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
          4096000
  
  Scrittura delle tavole degli inode: fatto                           
  Creating journal (32768 blocks): fatto
  Scrittura delle informazioni dei superblocchi e dell'accounting del filesystem: fatto
  
  Questo filesystem verrà automaticamente controllato ogni 20 mount, o
  180 giorni, a seconda di quale venga prima. Usare tune2fs -c o -i per cambiare.
  #

System Copy

Let's mount the target SD card (being /dev/sdc) and the source (being dev/sdg):
  # mount /dev/sdc1 /mnt
  # mount /dev/sdg1 /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3
  # df
  File system        blocchi di 1K   Usati   Dispon. Uso% Montato su
  rootfs                15907324  12375740   2723520  82% /
  devtmpfs               1653368       308   1653060   1% /dev
  tmpfs                  1658796         4   1658792   1% /dev/shm
  /dev/sda10            15907324  12375740   2723520  82% /
  /dev/sda3              5162828   3684960   1215608  76% /documents
  /dev/sda11            23867088  19794348   2860236  88% /home
  /dev/sda7             15488716   8913140   5788796  61% /local
  /dev/sda8             10429552   3473932   6531828  35% /download
  /dev/sda9              1050152    653468    396684  63% /windoc
  /dev/sda2             25806300  17392260   7103136  72% /virtual
  /dev/sda11            23867088  19794348   2860236  88% /home/faumarz
  /dev/sdc1             30160428    176196  28452152   1% /mnt
  /dev/sdg1             30265344  23713308   5016656  83% /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3
  #

I showed the source dev/sdg mounted into a /media directory because I let it be mounted by the system.

Now we can do the long copy of the system:
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/bin /mnt
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/boot /mnt
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/dev /mnt
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/etc /mnt
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/home /mnt
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/lib /mnt
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/lib64 /mnt
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/opt /mnt
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/root /mnt
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/sbin /mnt
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/srv /mnt
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/studio /mnt
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/tmp /mnt
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/usr /mnt
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/var /mnt
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/bootincluded_archives.filelist /mnt
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/success /mnt
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/.Trash-0 /mnt
  cp -av /media/ca11ec65-e12b-4e89-a39a-7cda9482e2d3/.gnupg /mnt
  
  mkdir /mnt/flash
  mkdir /mnt/media
  mkdir /mnt/mnt
  mkdir /mnt/proc
  mkdir /mnt/selinux
  mkdir /mnt/sys

(Your system can be different: check it)
This will take a long time. Let's take a coffee. (you can also use dd to do the copy, if you want to wait longer).

Bootloader & Friends

I assume you have grub bootloader. OpenSuse is very scared about the damages you can cause to your system using the grub-install script, and you should be scared, too. OpenSuse is so scared that renamed the script into grub-install.unsupported in order to be really sure that you know what you do when you call it.

Old grub versions (OpenSuse 11.4):
  grub-install.unsupported --recheck --root-directory=/mnt /dev/sdc

Newer grub versions:
  grub-install.unsupported --recheck --boot-directory=/mnt/boot /dev/sdc

The --recheck options is needed to avoid the following error:
  /dev/hdc does not have any corresponding BIOS drive

Another way to solve this error is to add the following line to the /mnt/boot/grub/device.map:
  (hd2) /dev/hdc

The important thing is that you have to edit the device.map which is in <root-directory>/boot/grub, and NOT the file on the drive you booted from. If you modify the/mnt/boot/grub/device.map you can also use interactive grub shell instead of grub-install script:
  # grub --device-map=/mnt/boot/grub/device.map
  grub> root (hd2,0)
  root (hd2,0)
  grub> setup (hd2)
  setup (hd2)
   Checking if "/boot/grub/stage1" exists... yes
   Checking if "/boot/grub/stage2" exists... yes
   Checking if "/boot/grub/fat_stage1_5" exists... no
   Running "install /boot/grub/stage1 (hd2) /boot/grub/stage2 p /boot/grub/menu.lst "... succeeded
  Done.
  grub> quit

Now check the /mnt/etc/fstab file and be sure that its content are the desired mountings for the target system, in particular the swap partition should be /dev/sda2 (supposing that your system boots the SD card considering it as /dev/sda).

I suggest also to check the /mnt/boot/grub/menu.lst in order to be sure that the booting references to the hard disk partitions are correctly referred to /dev/sda (or whatever your system will consider as boot device).

mercoledì 2 luglio 2014

Creare USB-serial alias in Linux


Creare USB-serial alias in Linux

(OpenSuse 11.4)


Per avere sempre gli stessi dispositivi USB-seriali ho fatto quanto suggerito qui: [http://hintshop.ludvig.co.nz/show/persistent-names-usb-serial-devices/]
e cioe' creato il file /etc/udev/rules.d/99-usb-serial.rules contenente:

  # Assegna dei symlink con nomi fissi ai dispositivi USB-Serial
  
  ACTION!="add|change", GOTO="usb_serial_rules_end"
  SUBSYSTEM!="tty", GOTO="usb_serial_rules_end"
  
  SUBSYSTEMS=="usb", GOTO="usb_serial_rules_vendorcheck"
  GOTO="usb_serial_rules_end"
  
  LABEL="usb_serial_rules_vendorcheck"
  
  SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="FTDOCOXM", SYMLINK+="ttyLPC2000"
  
  
  LABEL="usb_serial_rules_end"

Il file di esempio qui sopra assegna all'adattatore USB con serial nr. "FTDOCOXM" l'alias /dev/ttyLPC2000.

Per rilevare ATTRS{idVendor}, ATTRS{idProduct} e ATTRS{serial} dei dispositivi USB:
  # tail -f /var/log/messages

Nota: gli adattatori USB Serial con chipset Prolific NON sembrano avere serial nr, quindi non e' possibile utilizzare questo metodo. I chipset FTDI invece sono OK.

Linux ModemManager Blacklist


Linux ModemManager Blacklist

(OpenSuse 11.4)


Networkmanager ha un modulo che si chiama modem-manager che prova a configurare modem su qualsiasi USB-Serial compaia: [http://comments.gmane.org/gmane.linux.network.networkmanager.devel/17250]

Per escludere alcune porte ho creato /etc/udev/rules.d/77-mm-usb-device-blacklist.rules:

  # Disabilita alcuni dispositivi dall'essere rilevati e interrogati da modem-manager
  
  ACTION!="add|change", GOTO="mm_usb_device_blacklist_end"
  SUBSYSTEM!="tty", GOTO="mm_usb_device_blacklist_end"
  
  SUBSYSTEMS=="usb", GOTO="mm_usb_device_blacklist_vendorcheck"
  GOTO="mm_usb_device_blacklist_end"
  
  LABEL="mm_usb_device_blacklist_vendorcheck"
  
  SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="FTDOCOXM", ENV{ID_MM_DEVICE_IGNORE}="1"
  SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="FTDOCOXM", ENV{ID_MM_PORT_BLACKLISTED}="1"
  
  LABEL="mm_usb_device_blacklist_end"

Il file di esempio qui sopra aggiunge alla black list di dispositivi da non configurare l'adattatore USB con serial nr. "FTDOCOXM".
Per evitare che modemmanager faccia anche solo il probe iniziale delle porte, e' stato necessario compilare la patch che ho trovato qui: [http://bugzilla-attachments.gnome.org/attachment.cgi?id=154215]

copiare il plugin generic
  # cp ./plugins/.libs/libmm-plugin-generic.so /usr/lib/ModemManager

e aggiungere le regole come:
  SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="FTDOCOXM", ENV{ID_MM_PORT_BLACKLISTED}="1"

Per esempio, il probe di modemmanager mi attivava l'alimentazione dispositivo su di un programmatore LPC900icp

Per rilevare ATTRS{idVendor}, ATTRS{idProduct} e ATTRS{serial} dei dispositivi USB:
  # tail -f /var/log/messages

Nota: gli adattatori USB Serial con chipset Prolific NON sembrano avere serial nr, quindi non e' possibile utilizzare questo metodo. I chipset FTDI invece sono OK.

lunedì 30 giugno 2014

Change FTDI USB-Serial latency in Linux


Change FTDI USB-Serial latency in Linux

If you try to change the settings like this, it won't work:

  # cat /sys/bus/usb-serial/devices/ttyUSB0/latency_timer
    1
  # echo 16 > /sys/bus/usb-serial/devices/ttyUSB0/latency_timer
  # cat /sys/bus/usb-serial/devices/ttyUSB0/latency_timer
    1

The low_latency flag is set by default, which forces it to 1, always. You have to run the follwing command to disable it:

  # setserial /dev/ttyUSB0 ^low_latency

Then you can modify the latency_timer entry:

  # cat /sys/bus/usb-serial/devices/ttyUSB0/latency_timer
    16
  # echo 8 > /sys/bus/usb-serial/devices/ttyUSB0/latency_timer
  # cat /sys/bus/usb-serial/devices/ttyUSB0/latency_timer
    8

venerdì 21 marzo 2014

GDB and Geany IDE: Remote Cross Debugging

Embedded Linux System Debugging with Geany


Remote debugging is when GDB runs on one machine and the program being debugged runs on another. This is useful in embedded systems, and often in this case it's called remote cross-debugging because the target CPU is differerent from the host used for developing code.
gdbserver can be used to remotely debug the program without needing to change it in any way.

The Geany IDE debugger plugin does not support remote debugging natively. Some graphical debugger such as Insight or the Eclipse IDE support it, but not Geany. And I like Geany very much, while I don't like Eclipse: so I arranged a patch/workaround to do it (based on plugin version 0.21).


Compiling the patch

Download geany plugins sources [http://plugins.geany.org/downloads.html] and install geany and gtk devel packages for your distribution. You'll need also Geany devel package installed. Compiling debugger plugin needs also vte-devel package installed.
  # cd geany-plugins-0.21.1
  # ./configure --prefix=/usr --mandir=/usr/share/man/
  # cd debugger/src
  # make

Compiled plugin is in the debugger/src/.libs/ directory (debugger.so). You will need to copy it in /usr/lib/geany (or where your distribution places the geany plugins), or install it with:
  make install

Geany can use an addictional path for plugins search (see Geany options), and if you want to use it you will have to configure the sources with:
  # ./configure --prefix=/your/path/to/plugins --mandir=/usr/share/man/

Here below the patch for dbm_gdb.c file:

  --- geany-plugins-0.21.1/debugger/src/dbm_gdb.c.original
  +++ geany-plugins-0.21.1/debugger/src/dbm_gdb.c
  @@ -96,6 +96,9 @@
   
   /* flag, showing that on debugger stop we have to call a callback */
   gboolean requested_interrupt = FALSE;
  +
  +/* flag: remote debugging session*/
  +gboolean remote_session = FALSE;
   
   /* autos list */
   static GList *autos = NULL;
  @@ -598,6 +601,9 @@
    */
   gboolean load(char* file, char* commandline, GList* env, GList *witer)
   {
  +char *ip;
  +char *port;
  +
    /* loading file */
    GString *command = g_string_new("");
    g_string_printf(command, "-file-exec-and-symbols %s", file);
  @@ -610,11 +616,38 @@
     return FALSE;
    }
   
  - /* set arguments */
  - command = g_string_new("");
  - g_string_printf(command, "-exec-arguments %s", commandline);
  - exec_sync_command(command->str, TRUE, NULL);
  - g_string_free(command, TRUE);
  + /* is it a remote target? */
  + /* (remote sessions handle commandline on debugserver side) */
  + if (commandline[0] == '@') {
  +  ip = commandline + 1;
  +  port = strchr(ip, ':');
  +  if (port != NULL) {
  +   *port = '\0';
  +   port++;
  +  }
  +  else {
  +   port = (char *)"3278";
  +  }
  +  if (ip == '\0') {
  +   ip = (char *)"127.0.0.1";
  +  }
  +  if (port == '\0') {
  +   port = (char *)"3278";
  +  }
  +  command = g_string_new("");
  +  g_string_printf(command, "target remote %s:%s", ip, port);
  +  exec_sync_command(command->str, TRUE, NULL);
  +  g_string_free(command, TRUE);
  +  remote_session = TRUE;
  + }
  + /* set arguments in non-remote sessions */
  + else {
  +  remote_session = FALSE;
  +  command = g_string_new("");
  +  g_string_printf(command, "-exec-arguments %s", commandline);
  +  exec_sync_command(command->str, TRUE, NULL);
  +  g_string_free(command, TRUE);
  + }
    
    /* set locale */
    command = g_string_new("");
  @@ -678,7 +711,14 @@
    }
    free_start_messages();
   
  - exec_async_command("-exec-run &");
  + if (remote_session) {
  +  exec_async_command("break main");
  +  sleep(2);
  +  exec_async_command("continue");
  + }
  + else {
  +  exec_async_command("-exec-run &");
  + }
   }
   
   /*
  @@ -686,6 +726,9 @@
    */
   void restart(char* terminal_device)
   {
  + if (remote_session) {
  +  dbg_cbs->report_error(_("Restart command not available in remote sessions"));
  + }
    dbg_cbs->clear_messages();
    exec_async_command("-exec-run &");
   }


Remote debugging

After compiling and installing this patched plugin, enable Debugger plugin in Geany. Remote debugging can be used inserting in the debugger plugin tab "Command Line" field the following format string:
  @remoteipaddr:port

for example:
  @192.168.2.51:4567

If you don't specify remoteipaddr, the default used is 127.0.0.1; if you don't specify port, the default used is 3278.

On the remote side, you'll have to start gdbserver:
  # gdbserver localhost:4567 yourprogram [yourprogram options]

Command options must be specified on the gdbserver side, when debugging remotely.


Cross debugging

The remote device can be a target CPU different from the host. For example it could be an embedded ARM Linux board. In this case you have to use a shell script to start geany with the correct path for the right gdb executable (x86 gdb executable can not debug other target CPUs than x86); let's suppose your ARM gdb executable is gdb-arm-linux (you can download it from emdebian: gdb-arm-linux-gnueabi_7.2-1_i386.deb) and you installed it in your ~/bin/arm-linux-emdebian/usr/bin/ directory:
  • create a symlink gdb to gdb-arm-linux:
      # cd ~/bin/arm-linux-emdebian/usr/bin/
    
      # ln -s gdb-arm-linux gdb
    
  • then create a shell script like this and use it for starting Geany:
      #!/bin/sh
      PATH=/home/yourhome/bin/arm-linux-emdebian/usr/bin/:$PATH
      geany $1
    
    
    

Notes

A few notes on remote debugging use:
  • don't use "Restart" command in remote debugging session: it can't be used
  • a breakpoint is automatically placed at main start (break main) so program stops there after first run, but it's not shown in Geany
  • place manually yourself a breakpoint in the place where program stops initially: it will prevents other breakpoints garbage later
This does not want to be a definitive solution: it's a dirty patch/workaround for my needs.

venerdì 14 febbraio 2014

Eizo EV2316W: xrandr settings

Setting up Eizo Flexscan EV2316W LCD Monitor under Linux with xrandr


Using OpenSuse 11.4 and a DELL d820 laptop.

The monitor supports a max pixel clock of 148.50:

# xrandr --newmode "1920x1080"  148.50  1920 2008 2052 2200  1080 1084 1089 1125 +hsync +vsync
# xrandr --addmode VGA 1920x1080

# xrandr --output LVDS --off
# xrandr --output VGA --mode 1920x1080


If you are using KDE4 you may experiment a "mouse disappear" problem after changing screen resolution as shown; the only workaroud I found is the following (needs sudo):

# sudo /bin/chvt 1; sudo /bin/chvt 7

Here below a script for automating this:

Philips 226V4LAB: xrandr settings

Setting up Philips 226V4LAB LCD Monitor under Linux with xrandr



Using OpenSuse 11.4 and an old eeePC 701.

The monitor seems to support a max pixel clock of 138.50:

# xrandr --newmode "1920x1080R"  138.50  1920 1968 2000 2080  1080 1083 1088 1111 +hsync -vsync
# xrandr --addmode VGA1 1920x1080R

# xrandr --output VGA1 --rate 59.9* --mode 1920x1080R
# xrandr --output VGA1 --rate 59.9* --mode 1920x1080R --output LVDS1 --off



Here below a script for automating this: