Author: xathrya

Home / Author: xathrya

Being Member of DracOS Developer Team

July 24, 2016 | News | No Comments

Hi everyone.

Have you ever heard DracOS Linux. Let me tell you, it is a cool stuff. You better check this out. It is a Linux distribution focusing on penetration testing. The coolest part of it is, it is built from scratch (see Linux From Scratch (LFS) for reference), unlike other similar theme distribution. The hardest and the most challenging part is of course master the beast.

Yeah, apparently the Devs are crazy and brilliant enough to run this project.

And not so long ago  I join the bandwagon project. My team is focusing on Operating System development. Yeah, we have some team, such as Tools Creation team, Maintainer team, etc. So as part of insider, I will also post some stuffs about our project here. Maybe some sneak peek of upcoming version? No, just wait 😉

The next DracOS is DracOS codename Leak (pronounce Le-yak).

Just you know, Leak is a demon. We use demon as weapon. Dare to ride? Release the Leak!


Sunday, June 26th 2016 I have delivered a presentation about Docker. It is an introduction to two things: Docker and DevOps activity. I believe that Docker and DevOps is complementing each other.

You can see and download the slides freely. You are free to use the slides and spread it as you like. If you have a question you can direct your question to me.

Best regards,

Satria Ady Pradana.

I Passed MTCNA Certification

April 24, 2016 | News | No Comments

Yesterday I got my first certification. It was MikroTik Certified Network Associate (MTCNA) with certificate #1604NA936.

I was so glad I pass this with score 85%. It is said that if your score is above 75% you can take a license to be a trainer. Though I will consider it later.

Next, I plan to get other certification. Wish me luck.

Debugging Linux Kernel on QEMU Using GDB

March 21, 2016 | Article | No Comments

Kernel is magic. Well, not really. All my experiences involving programming in userland. Could I step up to enter the land of kernel? Sure, but before that I need to arm myself with knowledge. Especially when dealing with kernel debugging.

This article will discuss about kernel debugging. When writing this, I use:

  • Linux Kernel 4.5
  • GDB 7.7.1
  • Qemu 2.5.0
  • Busybox 1.24.2
  • ParrotSec Linux for host

Although in the end we can run minimalistic kernel, this approach is not close to “real world” yet.


Download the kernel source code from and extract it to /usr/src

mv linux-4.5.tar.xz /usr/src
cd /usr/src
tar -xf linux-4.5.tar.xz -C linux

Download busybox and extract it to /usr/src. We will use this for creating initramfs.

mv busybox-1.24.2.tar.bz2
cd /usr/src
tar -xf busybox-1.24.2.tar.bz2 -C busybox

ParrotSec is debian derivative.

I use latest Qemu, you can read it from here.

Compile Linux Kernel

It’s a bit different to usual routine, we need to enable debug info.

cd /usr/src/linux
mkdir build
make menuconfig O=build

Select “Kernel hacking” menu.

Go to “Compile-time checks and compiler options”.

  • Enable the “Compile the kernel with debug info”
  • Enable the “Compile the kernel with frame pointers”
  • Enable the “Provide GDB scripts for kernel debugging”.

Search for “KGDB: kernel debugger” and make sure it is checked.

Go to the build directory and build from there

cd build
make bzImage -j $(grep ^Processor | wc -l)

Creating Initramfs

We need some kind of environment with basic command line tools. Something that provided by binutils, like: ls, cat, mkdir, etc. It is called initramfs (Initial RAM file system). The idea is to provide a minimal “root file system” as a temporary file system so Kernel can prepare all works before mounting the real file system. We will use Busybox.

cd /usr/src/busybox
mkdir build
make menuconfig O=build

Select “Busybox Settings” > “General Configuration” and uncheck the “Enable options for full-blown desktop systems” and check”. Go back and select “Build Options” and check “Build BusyBox as a static binary (no shared libs).

make && make install

This will create a new directory “_install” and install our busybox there. This _install will be base for initramfs.

Next we create a new “initramfs” directory and create some configuration files inside.

mkdir /usr/src/initramfs
cd /usr/src/initramfs
cp -R /usr/src/busybox/build/_install rootfs
cd rootfs
rm linuxrc
mkdir -p dev etc newroot proc src sys tmp

We don’t need “linuxrc” sine we are going to use initramfs boot scheme.

Create a file etc/wall.txt and fill it:

#                                    #
#      Kernel Debug Environment      #
#                                    #

Remember init? Once our kernel is up, we need init to spawn everything necessary. However in our minimalistic system, our init only needed to spawn tty. Now create and populate init file with following content.

dmesg -n 1

mount -t devtmpfs none /dev
mount -t proc none /proc
mount -t sysfs none /sys

cat /etc/wall.txt

while true; do
   setsid cttyhack /bin/sh

The cttyhack is a small utility for spawning tty device. This way, we can rest assure that when we execute the “exit” command new shell will be started automatically.

We need to make the init file is executable.

chmod +x init

Next we need to pack initramfs.

cd /usr/src/initramfs/rootfs
find . | cpio -H newc -o | gzip > ../rootfs.igz

Running Kernel on Qemu

Next thing to do is to launch the kernel inside Qemu.

qemu-system-x86_64 -no-kvm -s -S \
-kernel /usr/src/linux/build/arch/x86/boot/bzImage \
-hda /mnt/jessie.ext3 -append "root=/dev/sda"

At this point, we will see a blank QEMU terminal windows.

The -s option is a shorthand for -gdb tcp::1234, i.e. open a gdbserver on TCP port 1234.

The -S option stops the CPU to start at startup. Now QEMU is waiting for kernel to start in debug mode.

Running GDB

The QEMU had launched the kernel and waiting for debugging. The next thing is to launch GDB and do the debugging.


In our host, we need to load the the same kernel load in QEMU and point our target to QEMU.

file /usr/src/linux/build/arch/x86/boot/bzImage
set architecture i386:x86-64:intel
set remote interrupt-sequence Ctrl-C
target remote :1234

Let’s try it, using GDB:


As for now, GDB still not appreciate the size of registers changing. As for our kernel, there is a time when our kernel change from 16 bit to 32 bit (or 64 bit). You might notice that when we run QEMU we specify -S so QEMU will stop at startup. At that time, Linux will change to full 64 bit (or 32 bit) kernel. If you don’t do something, GDB will keep complaining about “remote packet reply is too long”.

To circumvent it, we can just disconnect and then reconnect.

set architecture i386:x86-64:intel
target remote :1234

QEMU [Paused]_021  LXTerminal_022

Linux is dominating embedded system. It is mainly because of broad support of processor, such as: ARM, MIPS, PowerPC, etc. For some gadget, touch screen is an extra feature, other must have it. Whatever the reason, Linux support it. The fundamental thing in programming a system with touch screen is how to get coordinate of point touched by user.

This article will discuss about how to capture coordinate of point in touch screen. When I write this article I use Castles Technology’s EDC. I won’t disclose internal of the system used, but I should tell you that our discussion could be applied to Linux in general.

Some Knowledge

As usual, before we start we need to know some basic knowledge.

Linux is unix-like operating system. Everything in Linux is a file, including device. They are all stored inside /dev. Your first SCSI disk should be recognized as /dev/sda. Your DVD ROM might be recognized as /dev/sr0 (or /dev/dvd, a symlink to it).

You might also learn that device is categorized mainly as character device and block device. A character device is a class of device which send data by amount of character at a time, while block device will give you a block of data (typically some bytes).

Now direct our focus toward /dev/input. This is the location where device files for our input devices located. By input devices we means mouse, keyboard, or perhaps touch screen. Good, now spot eventX file where X is a number. Well, the number of files is depends on how much input device you have.

So how can we pinpoint the device?

In desktop I can see the /dev/input/by-id or /dev/input/by-path and see to which device they are pointing at. However, we don’t always have this luxury.

ls -la /dev/input/by-id/
ls -la /dev/input/by-path/

Another quick way to figure it out is by inspecting /proc/bus/input/devices. Yet, this might be not the case for most device. Also we need to parse some unneeded information.

cat /proc/bus/input/devices

Next option is dumping the raw data from file. Again this is not always the case.

cat /dev/input/event0 | hexdump -c

Last option is writing a small program, open the device, and read it. This works for me and we will discuss it deeper later.


I will leave the idea of “how you can connect to device” to you. I assume you have some way to write a program. We also need a way to direct I/O to device.

I also assume you can produce code for the device. Whether you have compiler inside, or just do cross compilation doesn’t matter.

Last, I assume you know our great programming language, C.


This is the sample working code I use to enumerate the device, open it, and capture the coordinate.

#include <stdio.h>
#include <stdlib.h>

/* For open and read data */
#include <unistd.h>
#include <fcntl.h>
#include <linux/input.h>

/* For directory listing */
#include <sys/stat.h>
#include <dirent.h>

/* Miscs */
#include <limits.h>
#include <string.h>

// We don't care it for now, let it be global.
DIR *dir = NULL;

/* Find first valid device which we can open */
int enum_and_open_dev()
    struct dirent *dirent;
    int fd;
    // Is it first time? Open it if yes.
    if (!dir)
        dir = opendir("/dev/input");

    if (dir)
        while ((dirent = readdir(dir) != NULL)) {
            if (!memcmp(dirent->d_name, "event", 5)) {
                fd = open(dirent->d_name, O_RDONLY);
                if (fd == -1)
                    continue;   // Not a valid file

                return fd;   // file is opened
        dir = NULL;
        return 0;

int get_dev_name(int fd)
    char buf[256] = "Unknown";

    /* Print Device Name */
    ioctl(fd, EVIOCGNAME(sizeof(buf)), buf);
    write(ofd, buf, strlen(buf));

int touch_screen_getxy(int fd)
    struct input_event ev;
    size_t ev_size = sizeof(struct input_event);
    size_t size;
    while (1) {
        size = read(fd, &ev, ev_size);
        if (size < ev_size) {
            write(ofd, "Error size when reading", 23);
            return -1;
        if (ev.type == EV_ABS && 
            (ev.code == ABS_X || ev.code == ABS_Y))
            sprintf(buf, "%s = %d\n", ev.code == ABS_X ? "X" : "Y", ev.value);
            write(ofd, buf, strlen(buf));
    return 0;

int test_()
   int fd;

   fd = enum_and_open_dev();
   if (fd == 0) {
      write(ofd, "No readable device found", 24);
      return -1;


Just a note, ofd is a file descriptor where will pipe to my host, in other words a debug means for me.

enum_and_open_dev() is a function to enumerate available file in /dev/input/ and trying to open it. In my sample code, I only use the first valid file descriptor. After I got it, I want to know it’s name and then the main dish: the coordinates.


Just a single point is not enough. What about two or three simultaneous touch (multitouch) ? Well, save it for later.

GMP (GNU Multi Precision) Library is one of vital library in GNU infrastructure. It is a popular library which gives flexibility to operate abritrary precision integers, rationals, and floating point numbers. There are also MPFR (Multi Precision Floating-point Reliably) and MPC (Multi Precision Complex) which are extension to to GMP capability for precision in computation.

In this article we will try to code using GMP, with C, on Linux 64-bit.


Check whether our box has GMP library.

locate libgmp.a

If GMP is installed already, we will get entry. If not, proceed to GMP site to download and install the library. Just do usual Linux installation procedure.

Getting Start

Before we start, let’s talking about the arbritrary precision. Do we need it? or why do we need it?

Program constitute of two element: algorithm and data. Data is represented by variable, which has size on memory. The size is fix, according to the word size of processor register. To simplify it, computer process numbers in multiple of 2: 8, 16, 32, or 64 bits at a time. For example, if we declare an int variable x, it will have 32 bit size.

Let’s discover by writing little code.

#include <stdio.h>
#include <limits.h>

void printbin(int x)
    if (x==0)
        if (x&1)

int main() {
    int k, x, i;
    char c;

    /* 1. Print machine native size and the max/min integer */
    printf("sizeof(int) = %d bits\n", sizeof(int) * 8);
    printf("max(int)    = %d\n", INT_MAX);
    printf("min(int)    = %d\n", INT_MIN);

    /* 2. Try to overflow */
    k = INT_MAX;
    printf("%d + 1 = %d\n", k, k+1);

    /* 3. See the representation of variable */
    printf("Enter x: ");
    scanf("%d", &x);
    printf("x in binary = ");

    return 0;

sizeof(int) gives the number of bytes for integer and INT_MAX is a macro defined in limits.h which inform the largest possible integer. INT_MIN is just the opposite of it.

This is the result in my box.


See the range, -2147483648 (min) to 2147483647 is the valid value of 32-bits integer. If we increment x which hold maximum value it will overflow to negative.

Enter GMP!

Now let’s dive to the GMP. GMP allows us to use integers whose sizes can grow dynamically to the required precision. Imagine it as BigNum, close to. It can support 128, 256, or 1024 bits. There is no need for us to specify this, the library does to dirt. GMP will dynamically allocate memory to accommodate extra bits of precision as we need.

Let’s try it with simple code.

#include <gmp.h>
#include <stdio.h>
int main()
    char inputStr[1025];
    /* type for GMP integers. 
        We don't care about the internal representation 
    mpz_t n;
    int flag;
    printf ("Enter your number: ");
    scanf("%1024s" , inputStr);
      /* 1. Initialize the number */

    /* 2. Parse the input string as a base 10 number */
    flag = mpz_set_str(n,inputStr, 10);
    if (flag == 0)
        return -1;
    printf ("n = ");
    printf ("\n");

    /* 3. Add one to the number */
    mpz_add_ui(n,n,1); /* n = n + 1 */

    /* 4. Print the result */
    printf (" n +1 = ");
    printf ("\n");

    /* 5. Square n+1 */
    mpz_mul(n,n,n); /* n = n * n */
    printf (" (n +1)^2 = ");
    printf ("\n");

    /* 6. Clean up the mpz_t handles or else we will leak memory */

    return 0; 

Remember to include library libgmp.a so GCC won’t complaint. Here is the result:


The complete information is always on GMP manual. But we love simplicity. So here we go.

At minimum we need this skeleton to use GMP.

#include <gmp.h>

/* ... */

  mpz_t n;

      /* ... */


      /* ... */


Now let’s make something out of it. Say, factorial program?

#include <gmp.h>
#include <stdio.h>
#include <stdlib.h>

/* Use iterative solution here. */
void factorial(int n)
    int i;
    mpz_t p;
    mpz_init_set_ui(p, 1);      /* p = 1 */
    for (i=1; i<= n; i++)
        mpz_mul_ui(p, p, i);    /* p = p * 1 */
    printf("%d! = ", n);
    mpz_out_str(stdout, 10, p);

int main()
    int n;
    do {
        printf("N = ");
        scanf("%d", &n);
        if (n <= 1)
            printf("N should be > 1\n");
    } while (1);
    return 0;

Try it!

Capturing USB Data with Wireshark

February 6, 2016 | Article | 1 Comment

Everyone loves USB devices. Many devices use USB as communication port. It is popular and steadily improve the standard. So, did you ever feel curious of what, how, and why the devices works? Whether you are a hardware hacker, hobbyist, or anyone interest in peripheral and low level, USB is very challenging. With wireshark, we have power to sniff or capture data stream sent by our USB devices to our host. The host is PC with Windows or Linux installed.

In this article we will discussing how can we capture data with wireshark. While writing this article I use following material:

  • Wireshark 2.0.1 (SVN)
  • Linux kernel 4.1.6

You can use any wireshark above 1.2.0 to get it works. I didn’t add Windows section yet because I didn’t confirm it yet.

Some Knowledge

Before we start, I think it is good to know some basic knowledge in USB. USB has specification. There are three way to use USB:

  • USB Memory

UART or Universal Asynchronous Receiver/Transmitter. This device use USB simply as receiving or transmitting way. They use USB nothing more than that, like other communication work.

HID is Human Interface Device. It is a class of USB which is for interface. Devices in this class are keyboards, mice, game controllers, and alphanumeric display devices.

Last is USB Memory, or we can say storage. External HDD, thumb drive / flash drive, they are part of this class.

As you might expect, the most common devices are either USB HID or USB Memory.

Now every USB device, especially HID or Memory, has magic number called Vendor Id and Product Id. They come in pair. The vendor Id is identifier to which vendor make this device. Product Id is identifying the product and not a serial number. See following picture.


That is a list of USB device connected to my box. To get this list we can invoke lsusb.

Let’s choose an entry. I have wireless mouse, Logitech. This is an HID device. This mouse comes with a receiver. It is detected and run as expected. Can you spot which is the device? Yes, the 4th entry. Here we have following:

Bus 003 Device 010: ID 046d:c52f Logitech, Inc. Unifying Receiver

The part ID 046d:c52f is Vendor-Product Id pair. The vendor id is 046d and the product id is c52f.

See Bus 003 Device 010. This inform us the Bus in which our device is connected. Note this.


We can run Wireshark as root to sniff USB stream. But as always, it is not recommended. We need to give enough privilege for our user to dump the stream from Linux usbmon. We can use udev for this purpose. What we will do is creating a group usbmon, make our account as usbmon member, create udev rules.

addgroup usbmon
gpasswd -a $USER usbmon
echo 'SUBSYSTEM=="usbmon", GROUP="usbmon", MODE="640"' > /etc/udev/rules.d/99-usbmon.rules

Next we need usbmon kernel module. If it is not loaded yet, invoke following command as root

modprobe usbmon


Open wireshark. See the interface list. You should see usbmonX where X is number. Here is mine (yeah, I use root):

The Wireshark Network Analyzer (as superuser)_048

If there is activity or stream in interface wireshark will show it as a wave graph. So which one should we choose? Did I ask you to note? Yes, the X or the number is corresponding to the USB Bus. In my case the target is usbmon3. Just open it and see the packet flow. Click on usbmon interface and click the blue shark fin icon.

-usbmon3 (as superuser)_049


What can we do after capturing? Well it depends. In general we can understand how devices and host communicate and maybe by this knowledge we can use our skill to reverse engineering it. Well, another article.

Mounting Remote Directory Using SSHFS

December 19, 2015 | Article | No Comments

Ever heard network file system (NFS)? Yeah, that’s good.

But in this article we won’t discuss NFS, just something similar in term of access remote directory locally. SSHFS is file system over SSH. It is a mean to mount directory / partition on remote server on our local box. The cool thing is it use SSH, a Secure Shell connection, as media to transfer data. The SSH itself is secure protocol, all data transmitted / received is through encrypted channel thus the secrecy is guaranteed.

In this article, I use following to demonstrate:

Generally speaking, the Arch Linux would be installed as guest using VirtualBox. We will make sure ArchLinux has SSH server and we can login to it. Then we install SSHFS on our local / host box. All the steps then be used to mount our local box to remote box.

Our goal in this article is we can install and mount linux partition on our box.

I assume Arc linux is up and running. You can also use other Linux, as long as it can be installed SSH server.



We need to install SSHFS on local. As I use ParrotSec which is Debian derivative, I invoke following command:

apt-get install sshfs

If you are using other Linux, you would achieve the same by invoking:

# ArchLinux
pacman -S sshfs fuse

# CentOS
### SSHFS is on EPEL repository so we should add EPEL first
yum update
### installing SSHFS
yum install fuse-sshfs


All we need is SSH server. SSH server is used to receive ssh connection. We use OpenSSH-server here.

# Arch Linux
pacman -S openssh
systemctl start sshd

# Debian
apt-get install openssh-server
service sshd start

# CentOS
yum -y install openssh-server
chkconfig sshd on
service sshd start

Or you can install Dropbear, alternative SSH server

# Arch Linux
pacman -S dropbear
systemctl start dropbear

# Debian
apt-get install dropbear
service dropbear start

# CentOS
### dropbear is on EPEL repository so we should add EPEL first
yum update
### installing dropbear
yum install dropbear
service dropbear start



Make sure both end can ping each other. For the sake of simplicity, I will use following network situation:



Create user remote on remote server try to login from our local machine:

ssh [email protected]

Create a directory (or using existing partition) and create two files on it.

mkdir /home/remote/mydir
echo "Please read this file for me" > /home/remote/mydir/file1
touch /home/remote/mydir/file2

Next we create a directory in our local machine as a mount point.

mkdir -p /mnt/sshfs/1


Next we try to mount freshly created directory

sshfs [email protected]:/home/remote/mydir /mnt/sshfs/1 -o workaround=all,allow_other

Create/Read/Write File

As we mount it with allow_other, any user on our local box can access the file and directory mounted. Any I/O operation to them will be redirected to remote server and performed as the referred user (remote).

To prove it, read the /mnt/sshfs/1/file1 on our local box. And then write something to /mnt/sshfs/1/file2 and read /home/remote/mydir/file2 on remote server.

# Local
cat /mnt/sshfs/1/file1
echo "Xathrya has came" > /mnt/sshfs/1/file2

# Remote
cat /home/remote/mydir/file2
ls -la

See the result for yourself.

Before Wt: Installing Prerequisite for Wt

December 12, 2015 | Article | No Comments

In this article we will discuss about installation of various packages and software as requirement for Wt. The goal of this article is for everyone to successfully install prerequisites for building Wt.

For this purpose, I use Slackware64 14.0 as development machine. However, you can also use other machine.

This article can be broken down to two sections:

  • System requirements
  • Optional packages

System Requirements

Applications on this sections is the primary requirements for building Wt. At least there are two packages:

  • CMake: cross platform make configure utility.
  • Boost C++ Library: A general purpose library for C++. Latest version is recommended.

Another requirements are the connector support which depend on what would you like.

For FastCGI (Unix only)

  • Apache2 or other web server which supports the FastCGI protocol. You can go to this page for more information about Web Server (Apache, Lighttpd, Nginx, etc). When using Apache use mod_fastcgi-2.4.x or mod_fcgid-2.3.5 alternatively.
  • FastCGI development kit

For built in http daemon

For ISAPI (Windows only)

  • ISAPI, which only works for deploying Wt applications within Microsoft IIS server.

Optional Packages

The following packages are optional, but highly recommended for Wt. They enables additional features in Wt. The packages are:

  • OpenSSL: Enabling HTTPS protocol support for Client (Http::Client) and Server (Http::Server)
  • libharu: Enabling rendering support for PDF documents.
  • GraphicsMagick: Enabling rendering support for raster images like PNG or GIF
  • pango: Text rendering for TrueType font selection
  • PostgreSQL, MySQL/MariaDB, and Firebird: Enabling connectors database for ORM library (alongside the Sqlite3 connector). You can choose any (all whole).


Cross platform, open-source build system consists of tools designed to build, test, and packaging software. It used to control the software compilation process using simple platform and compiler independent configuration files.

For information on how to install CMake, follow this article.

Boost C++ Library

Portable C++ source libraries and work well with the C++ Standard Library. It is intended to be widely useful and usable across a broad spectrum of applications.

For information on how to install Boost Library, follow this article.



Free, cross platform, open source library for generating PDF files.

For information on how to install libHaru, follow this article.


The swiss army knife of image processing. It provides a robust and efficient collection of tools and libraries which support reading, writing, and manipulating an image in over 88 major formats including DPX, GIF, JPEG, JPEG-2000, PNG, PDF, PNM, and TIFF.

For information on how to install GraphicsMagick, follow this article.






A relational database offering many ANSI SQL standard features that runs on various operating system. It offers excellent concurrency, high performance, and powerful language support for stored procedures and triggers.

For information on how to install FirebirdSQL, follow this article.

FastCGI Development Kit


Embedded system / device running operating system such as Linux / BSD is not so uncommon today. Most of them fall in category as routers, servers, NAS devices and mostly have communication interface (serial port with RS-232, or even fancy USB). We can communicate with these kind of devices, by redirect our I/O to this port. That’s the hardware part, how can we feed information to it? What tools should we use?

This article will mention five ways to communicate with embedded device. Our operating system of choice is Linux.

Of course we need to specify, our embedded system is the one which is designed to send/receive data / command using communication line.


The physical port might be one and only, but how it is referred by our system? Thus we should check. The port commonly referred as ttyS*, ttyACM*, ttyUSB*. It is analogous to COM* on Windows. Let’s check by dmesg command. Connect our box with our device and invoke following command:

dmesg | egrep --color 'serial|ttyS|ttyACM|ttyUSB'

This one will be our example:

[    1.245258] serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[    1.265727] serial8250: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
[    1.286713] 00:07: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[    1.307321] 00:08: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A

Let’s get initial report regarding the port. We need the configuration information associated with serial port (in this context):

setserial -g /dev/ttyS[0123]

Sample outputs:

/dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4
/dev/ttyS1, UART: 16550A, Port: 0x02f8, IRQ: 3
/dev/ttyS2, UART: unknown, Port: 0x03e8, IRQ: 4
/dev/ttyS3, UART: unknown, Port: 0x02e8, IRQ: 3

After confirmed, we can use following method to communicate.

CU Command

You might also want to read my old article: using CU to communicate with modem.

CU, abbreviated from call up, is an old unix command used to call up another system and act as dial in terminal. In some unix it is preinstalled. If not, you can always install it, most modern distro available.

Next, we use following command to communicate:

cu -l /dev/device -s baud-rate-speed

In our case, /dev/device would be /dev/ttyS0. Our baud rate is anything predefined value you want such as 19200 or 115200. Make sure the baudrate in both end is the same value.

cu -l /dev/device -s baud-rate-speed

In this example, I’m using /dev/ttyS0 with 115200 baud-rate:

cu -l /dev/ttyS0 -s 115200

To exit enter tilde dot (~.).

Screen Command

Most case, screen is used as a trick to run a process in server when we are remotely connect to it. We can also use screen to communicate with device.

screen /dev/device baud-rate

Minicom Command

Minicom is another approach. It is a tool designed for the job. Before we use, we need to setup it.

minicom -s

You will see some menu there. The most crucial part here is Serial port setup. Make sure the port and baud rate are set correctly.

Invoke minicom to do the job. We don’t need to specify command to minicom everytime we invoke it if we have saved the configuration before.


PuTTY Command

PuTTY, yes it is available also on Linux. It is a free and open source gui X based terminal emulator client for the SSH, Telnet, rlogin, and raw TCP computing protocols and as a serial console client. To use it, invoke PuTTY and wait for its GUI.


On Session, select Serial. Again, specify the port as Serial line and the baud rate as Speed.

Tip command

Last but not least, is using tip command. To use tip, we invoke following:

tip -baud device

For example:

tip -115200 ttyS0

Social media & sharing icons powered by UltimatelySocial