Java library for Linux Server Socket (incl. C Server Example)

Standard

(Source link: https://github.com/prl85/LinuxClientSocket-for-Java)

Java library (client socket) for communicating with Linux server socket

Requirement
– Java client: any OS
– C server: Linux OS

BLE iBeacon Scanner for Android 5.0 and later (optimized for Android 7)

Standard

(Source link: https://github.com/prl85/BLEScanner/)

iBeacon Scanner for Android 5.0 and later – resolves ‘5 tries per 30 seconds’ limit by Android 7.0 (Nougat) and later
https://stackoverflow.com/questions/43114913/android-7-0-ble-scan-no-result
https://blog.classycode.com/undocumented-android-7-ble-behavior-changes-d1a9bd87d983
https://github.com/AltBeacon/android-beacon-library/issues/418

To resolve the scan block problem by Android 7.0, my library (BLEScanner) did made some trick like following;

  • Regardless of the requested period for scanning, BLEScanner performs BLE scan at least 6 seconds (30/5= 6 s)
  • BLEScanner externally returns scan result of requested period like the scanning is performed during the period, but internally it continues to scan without reporting result
  • If new scan is requested before BLE scan is terminated internally, BLEScanner returns scan results of new request period, and delays real BLE scan stop if necessary.

By separating result report period and real BLE scan stop timing, users can be perceived that the scan is performed during request period, while BLEScanner internally adjusts real BLE scan stop timing to cope with ‘5 tries per 30 seconds’ limit.

Building NS-3 3.26 in Mac OS X 10.13 (High Sierra)

Standard

I haven’t updated the ns-3 installation guide for Mac OS X, so I updated with most recent version of Mac OS X 10.13 (High Sierra)

1. Get the source and unarchive

cd
mkdir workspace
cd workspace
wget http://www.nsnam.org/release/ns-allinone-3.26.tar.bz2
tar xjf ns-allinone-3.26.tar.bz2

2. Install required library (except goocanvas and pygoocanvas)

brew install libxml2
# if libxml2 is installed but still shows error on installing NS-3, 
# try 'brew upgrade libxml2' without quote

# install other required library (valgrind should be manually installed)
brew install gsl libgcrypt doxygen gtk cvs unrar p7zip xz cmake bzr 

brew install python python3
pip3 install meson
brew install graphviz pygtk

# install gccxml
git clone https://github.com/gccxml/gccxml.git
cd gccxml
mkdir gccxml-build
cd gccxml-build
cmake ../
make
sudo make install
cd ../..
rm -rf gccxml

# install required python library
pip2 install pygraphviz pygccxml

# install qt4 if you want to use netanim
# https://www.nsnam.org/wiki/Installation#Mac_OS_X, step 3
brew install cartr/qt4/qt-legacy-formula

# install mercurial if you want to use it
# https://www.nsnam.org/wiki/Installation#Mac_OS_X, step 4
brew install mercurial

# install valgrind by source
xcode-select --install

git clone git://sourceware.org/git/valgrind.git
cd valgrind

# Recent version is already patched to support High Sierra, so nothing to do 
./autogen.sh
./configure
make
sudo make install

valgrind --version # just for test
cd ..

3. Install goocanvas-0.14 (It is important to use 0.14, though more recent versions are available)

wget http://ftp.gnome.org/pub/gnome/sources/goocanvas/0.14/goocanvas-0.14.tar.gz
tar xvfz goocanvas-0.14.tar.gz
rm goocanvas-0.14.tar.gz

cd goocanvas-0.14
./configure
make
sudo make install
cd ..
rm -rf goocanvas-0.14

4. Install pygoocanvas-0.14.1 (tested with goocanvas 2.0.2 from homebrew)

wget https://launchpad.net/pygoocanvas/trunk/0.14.1/+download/pygoocanvas-0.14.1.tar.gz
tar xvfz pygoocanvas-0.14.1.tar.gz

cd pygoocanvas-0.14.1
wget http://study.prl85.com/wp-content/uploads/sites/2/2015/03/install-on-mac.sh
chmod 755 install-on-mac.sh

wget http://study.prl85.com/wp-content/uploads/sites/2/2015/03/pygoocanvas-0.14.1-mac.patch
patch < pygoocanvas-0.14.1-mac.patch
./install-on-mac.sh

cd ..
rm -rf pygoocanvas-0.14.1

5. Install ns-3

cd ns-allinone-3.26
python2 ./build.py --enable-examples --enable-tests

6. Test whether ns-3 is installed properly

cd ns-3.26
./test.py

7. Execute example file to check ns-3 is working or not

cp examples/tutorial/first.cc scratch/myfirst.cc
./waf
./waf --run scratch/myfirst

Reference)
https://www.nsnam.org/docs/release/3.26/tutorial/html/getting-started.html
https://www.nsnam.org/wiki/Installation#Mac_OS_X
https://stackoverflow.com/questions/39690404/brew-install-qt-does-not-work-on-macos-sierra
http://valgrind.org/downloads/repository.html
https://stackoverflow.com/questions/13421675/make-fails-while-installing-valgrind
https://github.com/mesonbuild/meson/issues/1054
https://mithunme.wordpress.com/2012/09/11/installing-ns-3-in-ubuntu

Appendix A)
In previous guide, the list of required library was following:

brew install wget mercurial bzr boost pkg-config gtk gsl doxygen graphviz cvs unrar p7zip xz cmake gtkmm gtkmm3 pygtk

If you have problem with installing, try installing package above.

Appendix B)
To test PyViz, see link https://www.nsnam.org/wiki/PyViz for the instruction.

iTunes (Mac/PC) and iOS built-in Podcast app are unable to process indirect download link (+Solution)

Standard

(Updated) Added solution for Nginx

Symptom)

If the audio/video URL of each item contains extension information, there is no problem.
(Example: http://prl85.com/podcast/example.mp3)

However, if the audio/video URL of each item has no information about file extension, then problem occurs. (Especially if you are using download handler instead of directly downloading file)
(Example: http://prl85.com/somehandler?episode=1)

In latter case, built-in Podcast app only can play episodes by streaming, not from downloaded file.
(After downloading episode, you can’t play that episode unless you delete the downloaded file)

Other podcast apps (Downcast, Podcruncher, …) has no problem with this (playing episodes from downloaded files).

Solution)
1. Apple fixes built-in Podcast app
(but…. when? btw, Mac/WIndows iTunes also have same problem)

2. Use direct link (http://prl85.com/example.mp3, instead of http://prl85.com/somehandler?episode=1) for media link
(but, what if it is inevitable to use download handler link?)
(it could be inevitable to use download handler link when you store the audio/video in cloud storage like dropbox, onedrive, google drive, …)

3. If solution 2 is unavailable, use redirection script (in my case, by PHP)
(http://prl85.com/redirect.mp3?episode=1 -> equivalent to http://prl85.com/somehandler?episode=1, downloads episode 1 file)

the extension of handler file should be that of media file (.mp3, .m4a, …), depending on your original media type.
(For solution 3, requires registering .mp3 or .m4a as being handled by PHP handler – recommends .htaccess in Apache case)

Example of redirection script (redirection.mp3)

<?php header('Content-Type: audio/mp3'); header('Location: http://prl85.com/somehandler?episode=1'); ?>


Example of .htaccess (For apache webserver; put this file with same directory of redirection script)

AddHandler application/x-httpd-php .mp3

Example of nginx.conf (For Nginx webserver; might be complex than Apache case because it requires modification of setting file)

server {
­	location /podcast_service/ { # where the redirection script exists
		location ~ .*\.mp3|.*\.m4a$ { # extensions you want to handle
			fastcgi_pass 127.0.0.1:9000;
			fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
			include fastcgi_params;
			fastcgi_read_timeout 180;
		}
	}
}

Make your Raspberry Pi keep time synced!

Standard

Condition) Internet connectivity

As Raspberry PI don’t have RTC module, the time will be incorrect while turned on.
Though the OS will try to sync time, it might not be sufficient because of tolerance from NTP daemon (will not fix the time if the difference is <1000 seconds, by default).

Alternatively, use cron to periodically sync time.

1. Contents of updatetime.sh (I stored in ~/, usually /home/pi)

#/bin/bash

sudo /usr/sbin/service ntp stop > /dev/null 2>&1
sudo /usr/sbin/ntpd -gq > /dev/null 2>&1
sudo /usr/sbin/service ntp start > /dev/null 2>&1

2. Change file mode to 755 (if your file directory is different, use that directory instead of ~/)

chmod 755 ~/updatetime.sh

3. type crontab -e, and append following line, and save.
(meaning ‘execute the script every 1 minute’)

*/1 * * * * /home/pi/updatetime.sh

4. Now, your PI will be keep time synced 🙂

Function – convert list of numbers (comma separated) to range (compress)

Standard

Example: 1, 3, 4, 5, 6 to 1,3-6

Implementation using PHP (For other language, you just need to modify some part of it)

function commaToRange($commaString)
{
	$rangeString = "";
	
	$arr = explode (",", $commaString);
	// to remove space
	$commaString = str_replace(" ", "", $commaString);

        // as the scope is integer, step is set to 1
	$step = 1;
		
	// if there are at least 2 numbers
	if (count($arr)> 1) 
	{
		$start = 0;
			
		for ($i = 1; $i < count($arr); $i++)
		{
			// if current range ends (=discontinued), print the last value of the range and print ',' to indicate start of new range 
			if ($arr[$i] - $arr[$i-1] > $step)
			{
				$rangeString .= $arr[$i-1];
				$rangeString .= ",";
				$start = $i;
			}
			// if current range keeps continuous, do nothing. (if the range keep continuous until second number, print the first value of the range and '-' to indicate range)
			else
			{
				if ($i - 1 == $start)
					$rangeString .= $arr[$i-1]."-";
			}
				
			// if the element is last, force printing
			if (count($arr) -1 == $i)
					$rangeString .= $arr[$i];
			}
	}
	// if there are only one number or less, return input itself
	else 
		$rangeString = $commaString;
		
	return $rangeString;
}

[XE] 회원 가입 시, 사용자가 수정 불가능한 항목 설정하기

Standard

http://study.prl85.com/xe-관리자만-수정-가능한-회원-정보-항목-설정하기/
에서는 회원 정보 수정 시, 관리자만 수정 가능한 항목을 설정하는 방법을 다루고 있습니다.

이 글에서는 이를 응용하여 회원 가입 시 사용자가 수정 불가능한 항목을 설정하는 방법을 다루겠습니다.
(활용: 특정 서비스 인증키.
즉, 회원 가입/정보 수정 시 사용자가 임의로 수정할 수는 없지만, 관리자가 정한 값을 본인 회원 정보에서는 보여주고 싶은 경우)

회원 정보 수정 때만 아니라, 회원 가입시에도 동일한 함수가 항목들을 출력하는 부분을 처리합니다.

xe – modules – member – member.admin.view.php에서
function _getMemberInputTag($memberInfo, $isAdmin = false)

다만 회원 정보 수정 때와 회원 가입 때 $readonly를 처리하는 부분이 조금 다릅니다.
회원 정보 수정 시에는, 로그인된 정보에서 관리자인지를 가려내서 수정 가능/불가능 여부가 가려지지만, 회원 가입시는 로그인된 정보라는 것이 없기 때문이죠 (로그인되지 않은 상태에서만 회원 가입이 가능하기 때문).
역으로 이 점을 이용해서, 로그인된 정보가 없을 때 (=회원 가입) 원하는 항목을 수정 불가능하게 만들면 됩니다.

$readonly = '';

if (Context::get('logged_info') == null) // 회원 가입시
    $readonly = 'readonly="readonly"';

if (Context::get('logged_info')
    && Context::get('logged_info')->is_admin != 'Y') // 회원 정보 수정시 (관리자만 가능)
    $readonly = 'readonly="readonly"';

회원 가입시에만 혹은 회원 정보 수정시 (이 경우는 관리자만)에 수정이 불가능하게 하려면 해당 항목만 남겨두면 되겠지요.

나머지 사항은 위의 링크를 참고하시면 되겠습니다.

[Ubuntu 14.04] Setting process affinity in kernel mode (2/2 – Example code)

Standard

Prerequisite)
Prerequisite and all steps from https://study.prl85.com/ubuntu-14-04-setting-process-affinity-in-kernel-mode-12-kernel-modification

Sample code (cpu_affinity_user.c)

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <sched.h>
#include <errno.h>
#include <linux/unistd.h>

void printCoreList()
{
	int i = 0;
	
	pid_t p = 0;	// meaning current process
	cpu_set_t mask;
	size_t len = sizeof(cpu_set_t);

	printf("(Current available CPU Core ID List:");	
	sched_getaffinity(p, len, &mask); // get available (movable) cpu cores

	bool printed = false;
	for (i = 0; i<CPU_SETSIZE; i++) 
	{
		if (CPU_ISSET(i, &mask))
		{
			printed = true;
			printf(" %d", i);
		}
	}
	
	if (printed == false)
		printf(" None");
	printf(")\n");
}

double measureTime(int calledID)
{
//	printf("Work - Called from cpu core %d\n", calledID);
	printf("Work - My allocated cpu core is %d\n", sched_getcpu());
		
	struct timeval currenttime;
	int i;
	
	// measure start time
	gettimeofday( &currenttime, 0 );

	long cur_time1 = 1000000 * currenttime.tv_sec + currenttime.tv_usec;
	double sec1 = cur_time1 / 1000000.0;
	
	// do some work
	for(i = 0; i < 5000000; i++)
		printf("%s", "\r");

	// measure end time
	gettimeofday( &currenttime, 0 );

	long cur_time2 = 1000000 * currenttime.tv_sec + currenttime.tv_usec;
	double sec2 = cur_time2 / 1000000.0;
	
	return sec2 - sec1;
}

int main()
{
	srand(time(NULL));

	int i = 0, j = 0, cpuChanged = 0;

	pid_t p = 0;	// meaning current process
	size_t len = sizeof(cpu_set_t);
	cpu_set_t new_mask;

	int numCpuCore = get_nprocs();		// get total number of cpu core
	int currentCore;	

	printf("Total number of CPU Core: %d\n", numCpuCore);
	printf("Current allocated CPU Core ID: %d\n", currentCore = sched_getcpu());	// get current allocated core

//	printCoreList(); // uncomment to see cpu affinity
	
	// case 1: normal mode (no cpu core fix)
	printf("<Doing some work without fixing the cpu core...>\n\n");

	int numOfRepetition = 30; // number of task repetition
	for (i = 0; i < numOfRepetition; i++) 
	{
		printf("[%3d/%3d] ", i+1, numOfRepetition);
		double elapsedTime = measureTime(currentCore = sched_getcpu());	// do work

		int newCore = sched_getcpu();	// what is current core after work?
		if (currentCore != newCore) // if the allocated cpu core is changed 
		{
			printf(" After work, my allocated CPU Core ID is moved to %d\n", currentCore = newCore);	
			cpuChanged++;
		}
	}
	printf("* Number of CPU core allocation change: %d (Out of %d trials, %.1lf%%)*\n", cpuChanged, numOfRepetition, (double) cpuChanged/(double) numOfRepetition*100.0);
	
	// case 2: special mode (cpu core fix)
	printf("\n<Randomly assigning another core...>\n");
	while(1)
	{
		int newcpuID = rand() % numCpuCore;
		if (newcpuID != currentCore)
		{
			CPU_ZERO(&new_mask);
			CPU_SET(newcpuID, &new_mask);
			break;
		}
	}
	
	cpuChanged = 0;
	
	// set to new core
	sched_setaffinity(p, len, &new_mask);
	printf("<New allocated CPU Core ID: %d>\n", sched_getcpu());
	
	printf("<Doing some work after fixing the cpu core...>\n");
	
	for (i = 0; i < numOfRepetition; i++) 
	{
		printf("[%3d/%3d] ", i+1, numOfRepetition);
		double elapsedTime = measureTime(currentCore = sched_getcpu());	// do work

		int newCore = sched_getcpu();	// what is current core after work?
		if (currentCore != newCore) // if the allocated cpu core is changed 
		{
			printf(" After work, my allocated CPU Core ID is moved to %d\n", currentCore = newCore);	
			cpuChanged++;
		}
	}
	printf("* Number of CPU core allocation change: %d (Out of %d trials, %.1lf%%)*\n", cpuChanged, numOfRepetition, (double) cpuChanged/(double) numOfRepetition*100.0);	
	return 0;
}

This code will execute measureTime() 30 times without cpu core fixed, then 30 times with cpu core fixed.
Each measureTime() takes some time, possibility of core allocation change, as shown in result.

How to run)

gcc cpu_affinity_user.c -o affinitytest
./affinitytest

Result)

Part 1 – CPU Core information, and initial allocated core

Total number of CPU Core: 4
Current allocated CPU Core ID: 1
(Current available CPU Core ID List: 0 1 2 3)

Part 2 – CPU core movement before fixing the cpu core

<Doing some work without fixing the cpu core...>
[  1/ 30] Work - My allocated cpu core is 1
 After work, my allocated CPU Core ID is moved to 0
[  2/ 30] Work - My allocated cpu core is 0
 After work, my allocated CPU Core ID is moved to 1
[  3/ 30] Work - My allocated cpu core is 1
[  4/ 30] Work - My allocated cpu core is 1
 After work, my allocated CPU Core ID is moved to 0
[  5/ 30] Work - My allocated cpu core is 0
 After work, my allocated CPU Core ID is moved to 3
[  6/ 30] Work - My allocated cpu core is 3
[  7/ 30] Work - My allocated cpu core is 3
[  8/ 30] Work - My allocated cpu core is 3
[  9/ 30] Work - My allocated cpu core is 3
[ 10/ 30] Work - My allocated cpu core is 3
[ 11/ 30] Work - My allocated cpu core is 3
 After work, my allocated CPU Core ID is moved to 2
[ 12/ 30] Work - My allocated cpu core is 2
 After work, my allocated CPU Core ID is moved to 3
[ 13/ 30] Work - My allocated cpu core is 3
[ 14/ 30] Work - My allocated cpu core is 3
 After work, my allocated CPU Core ID is moved to 0
[ 15/ 30] Work - My allocated cpu core is 0
[ 16/ 30] Work - My allocated cpu core is 0
[ 17/ 30] Work - My allocated cpu core is 0
[ 18/ 30] Work - My allocated cpu core is 0
[ 19/ 30] Work - My allocated cpu core is 0
[ 20/ 30] Work - My allocated cpu core is 0
 After work, my allocated CPU Core ID is moved to 3
[ 21/ 30] Work - My allocated cpu core is 3
[ 22/ 30] Work - My allocated cpu core is 3
[ 23/ 30] Work - My allocated cpu core is 3
 After work, my allocated CPU Core ID is moved to 0
[ 24/ 30] Work - My allocated cpu core is 0
[ 25/ 30] Work - My allocated cpu core is 0
[ 26/ 30] Work - My allocated cpu core is 0
 After work, my allocated CPU Core ID is moved to 3
[ 27/ 30] Work - My allocated cpu core is 3
[ 28/ 30] Work - My allocated cpu core is 3
 After work, my allocated CPU Core ID is moved to 0
[ 29/ 30] Work - My allocated cpu core is 0
 After work, my allocated CPU Core ID is moved to 1
[ 30/ 30] Work - My allocated cpu core is 1
* Number of CPU core allocation change: 12 (Out of 30 trials, 40.0%)*

Part 3 – CPU core movement after fixing the cpu core

<Randomly assigning another core...>
<New allocated CPU Core ID: 0>
<Doing some work after fixing the cpu core...>
[  1/ 30] Work - My allocated cpu core is 0
[  2/ 30] Work - My allocated cpu core is 0
[  3/ 30] Work - My allocated cpu core is 0
[  4/ 30] Work - My allocated cpu core is 0
[  5/ 30] Work - My allocated cpu core is 0
[  6/ 30] Work - My allocated cpu core is 0
[  7/ 30] Work - My allocated cpu core is 0
[  8/ 30] Work - My allocated cpu core is 0
[  9/ 30] Work - My allocated cpu core is 0
[ 10/ 30] Work - My allocated cpu core is 0
[ 11/ 30] Work - My allocated cpu core is 0
[ 12/ 30] Work - My allocated cpu core is 0
[ 13/ 30] Work - My allocated cpu core is 0
[ 14/ 30] Work - My allocated cpu core is 0
[ 15/ 30] Work - My allocated cpu core is 0
[ 16/ 30] Work - My allocated cpu core is 0
[ 17/ 30] Work - My allocated cpu core is 0
[ 18/ 30] Work - My allocated cpu core is 0
[ 19/ 30] Work - My allocated cpu core is 0
[ 20/ 30] Work - My allocated cpu core is 0
[ 21/ 30] Work - My allocated cpu core is 0
[ 22/ 30] Work - My allocated cpu core is 0
[ 23/ 30] Work - My allocated cpu core is 0
[ 24/ 30] Work - My allocated cpu core is 0
[ 25/ 30] Work - My allocated cpu core is 0
[ 26/ 30] Work - My allocated cpu core is 0
[ 27/ 30] Work - My allocated cpu core is 0
[ 28/ 30] Work - My allocated cpu core is 0
[ 29/ 30] Work - My allocated cpu core is 0
[ 30/ 30] Work - My allocated cpu core is 0
* Number of CPU core allocation change: 0 (Out of 30 trials, 0.0%)*

 

[Ubuntu 14.04] Setting process affinity in kernel mode (1/2 – kernel modification)

Standard

Prerequisite)

Step 1 and 2 from http://study.prl85.com/building-ubuntu-kernel/
(=Ready to compile kernel)

Procedure)

1. Find the file containing sched_setaffinity function from non-compiled kernel source directory.
(In this case, kernel/sched/core.c)

bsw@bsw-P5K:~$ cd linux-3.13.0-orig/
bsw@bsw-P5K:~/linux-3.13.0-orig$ grep -R "long sched_setaffinity" *
include/linux/sched.h:extern long sched_setaffinity(pid_t pid, const struct cpumask *new_mask);
kernel/sched/core.c:long sched_setaffinity(pid_t pid, const struct cpumask *in_mask)

2. In kernel/sched/core.c, add EXPORT_SYMBOL_GPL(sched_setaffinity); after the end of sched_setaffinity() definition.

long sched_setaffinity(pid_t pid, const struct cpumask *in_mask)
{
cpumask_var_t cpus_allowed, new_mask;
struct task_struct *p;
int retval;
...
out_unlock:
free_cpumask_var(new_mask);
out_free_cpus_allowed:
free_cpumask_var(cpus_allowed);
out_put_task:
put_task_struct(p);
return retval;
}
EXPORT_SYMBOL_GPL(sched_setaffinity);

3. In kernel/sched/core.c, add EXPORT_SYMBOL_GPL(sched_getaffinity); after the end of sched_getaffinity() definition.

long sched_getaffinity(pid_t pid, struct cpumask *mask)
{
        struct task_struct *p;
        unsigned long flags;
        int retval;

        rcu_read_lock();

        retval = -ESRCH;
        p = find_process_by_pid(pid);
        if (!p)
                goto out_unlock;

        retval = security_task_getscheduler(p);
        if (retval)
                goto out_unlock;

        raw_spin_lock_irqsave(&p->pi_lock, flags);
        cpumask_and(mask, &p->cpus_allowed, cpu_active_mask);
        raw_spin_unlock_irqrestore(&p->pi_lock, flags);

out_unlock:
        rcu_read_unlock();

        return retval;
}
EXPORT_SYMBOL_GPL(sched_getaffinity);

4. Build new kernel and reboot
(Refer to step 5~9 from http://study.prl85.com/building-ubuntu-kernel)

Reference)
http://stackoverflow.com/questions/1151285/setting-process-affinity-in-kernel-mode
http://study.prl85.com/building-ubuntu-kernel

[Ubuntu 14.04] Building Linux Kernel

Standard

Procedure)

1. Download kernel source of current version

apt-get source linux-image-$(uname -r)
bsw@bsw-P5K:~$ apt-get source linux-image-$(uname -r)

Reading package lists... Done
Building dependency tree
Reading state information... Done
Picking 'linux' as source package instead of 'linux-image-3.13.0-44-generic'
NOTICE: 'linux' packaging is maintained in the 'Git' version control system at:
http://kernel.ubuntu.com/git-repos/ubuntu/ubuntu-trusty.git
Need to get 125 MB of source archives.
Get:1 http://kr.archive.ubuntu.com/ubuntu/ trusty-updates/main linux 3.13.0-55.92 (dsc) [11.8 kB]
Get:2 http://kr.archive.ubuntu.com/ubuntu/ trusty-updates/main linux 3.13.0-55.92 (tar) [116 MB]
Get:3 http://kr.archive.ubuntu.com/ubuntu/ trusty-updates/main linux 3.13.0-55.92 (diff) [8752 kB]
Fetched 125 MB in 23min 56s (87.1 kB/s)
...
 linux-3.13.0/virt/kvm/async_pf.c
 linux-3.13.0/virt/kvm/coalesced_mmio.c
 linux-3.13.0/virt/kvm/ioapic.c
 linux-3.13.0/virt/kvm/iommu.c
 linux-3.13.0/virt/kvm/kvm_main.c

2. Configure build environment (one-time)

sudo apt-get build-dep linux-image-$(uname -r)
sudo apt-get update
sudo apt-get install curses-dev
bsw@bsw-P5K:~$ sudo apt-get build-dep linux-image-$(uname -r)
[sudo] password for bsw:
Reading package lists... Done
Building dependency tree
Reading state information... Done
Picking 'linux' as source package instead of 'linux-image-3.13.0-44-generic'
The following NEW packages will be installed:
  asciidoc docbook-dsssl docbook-utils docbook-xml docbook-xsl gawk jadetex
  kernel-wedge libaudit-dev libdw-dev libdw1 libelf-dev libiberty-dev
  libnewt-dev libosp5 libostyle1c2 libsgmls-perl libslang2-dev libsp1c2
  libunwind8 libunwind8-dev lynx lynx-cur makedumpfile openjade sgml-data
  sgmlspl sp transfig xmlto xsltproc
0 upgraded, 31 newly installed, 0 to remove and 3 not upgraded.
Need to get 11.1 MB of archives.
After this operation, 51.3 MB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 http://kr.archive.ubuntu.com/ubuntu/ trusty/main gawk amd64 1:4.0.1+dfsg-2.1ubuntu2 [781 kB]
...
Setting up xmlto (0.0.25-2) ...
Setting up docbook-dsssl (1.79-7ubuntu1) ...
Processing triggers for sgml-base (1.26+nmu4ubuntu1) ...
Setting up docbook-utils (0.6.14-3ubuntu1) ...
Processing triggers for libc-bin (2.19-0ubuntu6.6) ...

3. Confirm the location of kernel source (/linux-3.13.0)

Screen Shot 2015-06-16 at 10.34.18 PM

4. Example of kernel modification (keep settings) (in linux-3.13.0 directory)
cf) If you have things to modify, do that instead of this.
cf) If you don’t have things to change or just want to test kernel compile, then go to next step (step 5)

This takes the current configuration for each architecture/flavour supported and calls menuconfig to edit its config file. The chmod is needed because the way the source package is created, it loses the executable bits on the scripts.
(from https://wiki.ubuntu.com/Kernel/BuildYourOwnKernel)

chmod a+x debian/scripts/*
chmod a+x debian/scripts/misc/*
fakeroot debian/rules clean
fakeroot debian/rules editconfigs

5. Build the kernel (might take awhile…) (in linux-3.13.0 directory)

fakeroot debian/rules clean
fakeroot debian/rules binary-headers binary-generic

6. Deb packages are created after successful build

cd ..
ls *.deb

Screen Shot 2015-06-17 at 12.16.00 AM

7. Before install deb packages, install linux-tools for right version (one-time)
(3.13.0-55 should be replaced to your kernel version)
(You might see errors when installing linux-tools, but that’s okay)

sudo apt-get install linux-tools-3.13.0-55
sudo apt-get install -f

8. Install these package to test new kernel (3.13.0-55.92 should be replaced to your kernel version, the string after generic_ and before _amd64)

sudo dpkg -i linux*3.13.0-55.92*.deb

When install deb packages, you should see messages like below (no errors)

...
Generating grub configuration file ...
Found memtest86+ image: /boot/memtest86+.elf
Found memtest86+ image: /boot/memtest86+.bin
Found linux image: /boot/vmlinuz-3.13.0-55-generic
Found initrd image: /boot/initrd.img-3.13.0-55-generic
Found linux image: /boot/vmlinuz-3.13.0-44-generic
Found initrd image: /boot/initrd.img-3.13.0-44-generic
Found linux image: /boot/vmlinuz-3.13.0-32-generic
Found initrd image: /boot/initrd.img-3.13.0-32-generic
Found Windows Recovery Environment (loader) on /dev/sda1
Found linux image: /boot/vmlinuz-3.13.0-55-generic
Found initrd image: /boot/initrd.img-3.13.0-55-generic
Found linux image: /boot/vmlinuz-3.13.0-44-generic
Found initrd image: /boot/initrd.img-3.13.0-44-generic
Found linux image: /boot/vmlinuz-3.13.0-32-generic
Found initrd image: /boot/initrd.img-3.13.0-32-generic
done
Setting up linux-tools-3.13.0-55-generic (3.13.0-55.92) ...

To confirm the deb packages are correctly installed (=you are ready to boot using the new kernel), type cat /boot/grub/grub.cfg | grep menuentry
You can see “Ubuntu with Linux 3.13.0-55-generic”, the version of compiled kernel.

Screen Shot 2015-06-17 at 12.56.52 AM

9. Reboot and print current kernel version

sudo reboot

After reboot, print current kernel version.

bsw@bsw-P5K:~$ uname -r
3.13.0-55-generic

Reference)
https://wiki.ubuntu.com/Kernel/BuildYourOwnKernel
http://askubuntu.com/questions/270381/how-do-i-install-ncurses-header-files