Thursday, June 18, 2015

Intro to Go Programming Package Creation

Go tools requires code organization in specific way for easy build, deploy your go code. The following section describes the process.

1) Create a specific directory $HOME/mygo
2) Set the environment variable GOPATH=$HOME/mygo
3) Create a unique namespace mkdir $GOPATH/src/github.com/nf

Develop your code inside the namespace

mkdir $GOPATH/src/github.com/nf/hello
cd $GOPATH/src/github.com/nf/hello
>> write your hello.go

build and install your hello.go with go install command in the current directory the binary will be installed in $GOPATH/bin directory

Lets create our own package to by used by other go program such as hello.go

mkdir $GOPATH/src/github.com/nf/string
cd $GOPATH/src/github.com/nf/string/string.go
>> write your string.go

================
package string

func Reverse(s string) string {
        b := []byte(s)
        for i:=0; i < len(s)/2; i++ {
                j := len(s)-i-1
                ch := b[i]
                b[i] = b[j]
                b[j] = ch
        }
        return (string(b))

}
===============
run go install in the string directory to create package string the output string.a will appear in 
$GOPATH/pkg/linux_amd64/github.com/nf/string.a 

Now lets use our string package in our hello.go

cd $GOPATH/src/github.com/nf/hello.go

===============
package main

import (
        "fmt"
        "github.com/nf/string"
)

func main() {
        fmt.Println(string.Reverse("Hello World!!"))
}
================

build the hello.go with go install

Cool!!

Let's write test program to test the package
cd $GOPATH/src/github.com/nf/string/
vi string_test.go


======================
package string

import "testing"

func Test(t *testing.T) {
        var tests = []struct {
                s, want string
        } {
                {"Backward", "drawkcaB"},
                {"Hello, # %", "% # ,olleH"},
                {"", ""},
        }

        for _, c:= range tests {
                got := Reverse(c.s)
                if got != c.want {
                        t.Errorf("Reverse(%q) == %q, want %q", c.s, got, c.want)
                }
        }

}

===============

run go test (If no error great, else fix the issue)

Sunday, May 31, 2015

Visualize CPU on your System

Visual Representation of CPU on your system
=============================
$ lstopo





Learn about your CPU (Via lscpu)
=====================
$ lscpu

Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    2
Core(s) per socket:    4
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 60
Stepping:              3
CPU MHz:               3201.250
BogoMIPS:              6385.14
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              8192K
NUMA node0 CPU(s):     0-7

Monday, February 2, 2015

get_user_pages example

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <linux/pagemap.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/mm.h>

static  struct  class *sample_class;

static int sample_open(struct inode *inode, struct file *file)
{
        printk(KERN_INFO "%s\n", __FUNCTION__);
        return (0);
}

static int sample_release(struct inode *inode, struct file *file)
{
        printk(KERN_INFO "%s\n", __FUNCTION__);
        return (0);

}

static ssize_t  sample_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
{
        int     res;
        struct  page *page;
        char    *myaddr;
        printk(KERN_INFO "%s\n", __FUNCTION__);
        down_read(&current->mm->mmap_sem);
        res = get_user_pages(current, current->mm,
                (unsigned long)buf,
                1,
                1,              
                1,
                &page,
                NULL);
        if (res) {
                printk(KERN_INFO "Got mmaped.\n");
                myaddr = kmap(page);
                printk(KERN_INFO "%s\n", myaddr);
                strcpy(myaddr, "Mohan");
                page_cache_release(page);
        }
        up_read(&current->mm->mmap_sem);
        return (0);
}

static struct   file_operations sample_ops = {
        .owner  = THIS_MODULE,
        .open   = sample_open,
        .release = sample_release,
        .write  = sample_write
};

static int __init sample_init(void)
{
        int ret;
        ret = register_chrdev(42, "Sample", &sample_ops);
        sample_class = class_create(THIS_MODULE, "Sample");
        device_create(sample_class, NULL, MKDEV(42, 0), NULL, "Sample");
        return (ret);
}

static void __exit sample_exit(void)
{
        device_destroy(sample_class, MKDEV(42, 0));
        class_destroy(sample_class);
        unregister_chrdev(42, "Sample");
}

module_init(sample_init);
module_exit(sample_exit);

MODULE_LICENSE("GPL");





======

obj-m += sample.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

all:
        $(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
        $(MAKE) -C $(KDIR) M=$(PWD) clean


========


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

int
main()
{
        int fd;
        char *ptr;
        fd = open("/dev/Sample", O_RDWR);
        if (fd < 0) {
                perror("error");
        }
        posix_memalign((void **)&ptr, 4096, 4096);
        memcpy(ptr, "krishna", strlen("krishna"));  //Write String to Driver
        write(fd, ptr, 4096);
        printf("data is %s\n", ptr);   //Read Data from Driver
        close(fd);
}