[DEV] Kernel development HOWTO and Interactive menu

Search This thread

Droidzone

Inactive Recognized Developer
Sep 24, 2010
5,531
2,283
Kochi
www.droidzone.in
OnePlus 9 Pro
Kernel Build Menu

Thanks! I use an interactive menu.. saves a lot of keystrokes in the process

n7pNm.jpg


Attached as kmen..

Installing:
Copy it to anywhere in your path-preferably /usr/bin
Then,
Code:
mv /usr/bin/kmen.txt /usr/bin/kmen
chmod +x /usr/bin/kmen
kmen

Code:
#!/bin/bash


function msg {
  echo -e '\E[37;44m'"\033[1m$welcome\033[0m" ; tput sgr0
}

function msg_blue {
  echo -e '\E[37;44m'"\033[1m$welcome\033[0m" ; tput sgr0
}

function msg_green {
  echo -e '\E[38;42m'"\033[1m$welcome\033[0m" ; tput sgr0
}

function msg_green_wait {
  echo -ne '\E[38;42m'"\033[1m$welcome\033[0m" ; tput sgr0
}

function pushmin {
  echo "Last kernel pack with no mods:"
  echo "$lastminpack"
  echo 
  read -p "Push to SD card?" -n 1
  echo
  if [[ $REPLY =~ ^[Yy]$ ]]
  then
    adb push $lastminpack /sdcard/
  fi
  echo
  read -p "Hit a key to continue.."
  menu
}

function backup_menuconfig {  
  echo
  if [ -e $kstartpath/.config ] 
  then  
    date_str=`date '+%d%m%y_%H%M%S'` 
    nname="config_$mnameflag_$date_str.txt"
    echo "Your menuconfig information resides in .config"
    echo "It will be backed up as $nname"  
    echo "You can change the name to config_[yournametag]_$date_str"
    echo 
    read -p "Change the name?" -n 1
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]
    then
      echo
      read -p "Enter new nametag:"
      mnameflag=$REPLY
      nname="config_"$mnameflag"_"$date_str".txt"
      echo "New name will be $nname"
      echo
      read -p "Hit a key to continue.."
    fi     
    echo
    cp $kstartpath/.config $kstartpath/$nname
    if [ -e $kstartpath/$nname ]
    then
      echo "Current menuconfig info successfully backed up as $kstartpath/$nname"
      echo
    else
      echo "Warning! An error occured while trying to backup .config"
      echo "Read Only filesystems/permissions error?"
      echo
    fi    
  else
    echo
    echo "No .config information found at $kstartpath"
    echo "Are you in the kernel source root directory? "
    echo "Rerun script from correct location...Aborting!"
    echo    
  fi
  read -p "Hit a key to continue.."
  menu   
}

function pushmax {
  echo "Last kernel pack with mods: "
  echo "$lastmaxpack"
  echo 
  read -p "Push to SD card?" -n 1
  echo
  if [[ $REPLY =~ ^[Yy]$ ]]
  then
    adb push $lastmaxpack /sdcard/
  fi
  echo
  read -p "Hit a key to continue.."
  menu
}

function openlast {
  echo
  if [ ! "$lastfolder" = "" ]
  then  
    echo "Last output folder is $lastfolder"
    echo
    read -p "Open it in file manager?" -n 1
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]
    then
      if [ -e /usr/bin/dolphin ]
      then
	echo "Opening output folder in Dolphon"
	dolphin $lastfolder
      elif [ -e /usr/bin/nautilus ]
      then
	echo "Opening output folder in Nautilus"
	nautilus $lastfolder
      elif [ -e /usr/local/bin/mc ]
      then
	echo "Opening output folder in Midnight Commander"
	mc $lastfolder
      else
	echo "No compatible file managers found. Aborting.."
      fi
    fi
  else
    echo "There is no logged last output folder!"
    echo "Compile a kernel/create flashable zips before choosing this option!!"
  fi
  echo
  read -p "Hit a key to continue.."
  menu     
}

function pushzip {
  echo
  echo "Push last packed zips to sdcard"
  echo "==============================="
  
  if [ "$lastminpack" = "" ] && [ "$lastmaxpack" = "" ]
  then
    echo "Generate a zip pack before trying to push it!"
    read -p "Hit a key to continue.."
    menu
  elif [ "$lastminpack" = "" ] 
  then
    pushmax
  elif [ "$lastmaxpack" = "" ] 
  then
    pushmin
  else
    pushmin
    pushmax
  fi
  
  #menu
}

function disp_kfiles {
  echo
  echo "Display compiled files in Kernel directory"
  echo "=========================================="
  echo "Current Kernel path is : $kstartpath"
  cd $kstartpath
  echo
  echo "Locating zImage:"
  echo 
  find . -name 'zImage' -exec echo '{}' \; to temp
  echo
  echo "Locating Modules:"
  echo 
  find . -name '*.ko' -exec echo '{}' \;
  read -p "Hit a key to continue.."
  menu
}

function lflashery {  
  clear

  
  if [ ! -d $ksource/arch ]
  then
    echo "The kernel location could not be located. Please re-run script from within kernel source root."
    echo "Script will now terminate!"
    exit 1
  fi


  echo    " =============================================="
  welcome="   FLASHABLE ZIP MAKER 1.0   by Droidzone      "
  msg
  #echo "	FLASHABLE ZIP MAKER 1.0   by Droidzone"
  echo    " =============================================="
  echo "Output dir is " $outdir/home/droidzone/kernel_flashable
  echo "Anykernel source is at " $anykdir
  echo "Kernel source is at " $ksource
  echo " " 
  #echo -e '\E[38;42mThis prints in blue.'; tput sgr0
  welcome="Creating a flashable zip in temporary location..."
  msg_green
  #echo "Creating a flashable zip in temporary location..."
  
  if [ ! -d $outdir ]; then mkdir $outdir; fi
  if [ ! -d $packagedir ]; then mkdir $packagedir; fi 
  if [ ! -d $tempdir ]; then mkdir $tempdir; fi
  #Copying the new kernel files
  
  if [ ls $outdir/*.zip > /dev/null 2>&1 ]
  then 
    rm $outdir/*.zip  
  fi  
  
  if [ ls $tempdir/README > /dev/null 2>&1 ]
  then 
    rm $tempdir/README  
  fi 
  
  #echo "Working in temporary directory: $tempdir"
  echo
  cp -a $anykdir/* $tempdir/

  sync

  #echo "Cleaning up remnants..."
  if [ -e $outdir/kernel/zImage ]; then rm $outdir/kernel/zImage; fi
  
  if [ ls $outdir/system/lib/modules/* > /dev/null 2>&1 ]
  then 
    rm $outdir/system/lib/modules/* 
  fi 

 
  if [ -d $ksource ]
  then
    if [ ! -e $ksource/arch/arm/boot/zImage ]
    then
      echo "Kernel source location: $ksource/arch/arm/boot/zImage"
      
      echo "zImage was not located at kernel location. Please re-run script from within kernel source root."
      echo "Script will now terminate!"
      exit 1
    else
      #echo "Copying zImage..."
      cp $ksource/arch/arm/boot/zImage $outdir/kernel/
      err=$?
      if [ ! $err -eq 0 ] 
      then
	echo "An error occured while copying zImage!"
	echo "A flashable zip cannot be created!"
	echo
	read -p "Hit a key to continue!"
	menu
      else
	echo " zImage copied"
      fi
    fi
  else
    echo "Kernel source folder: $ksource"
      
    echo "Kernel source folder not found! Please re-run script from within kernel source root."
    echo "Script will now terminate!"
    exit 1
  fi
  cd $outdir
  #echo "At temp location: $(pwd)...About to cleanup!"
  #read -p "Hit a key to continue!"
  
  #Precleaning temp folder
  find . -name '*.ko' -exec rm '{}' \;
  find . -name '*~' -exec rm '{}' \;
  find . -name 'README*' -exec rm '{}' \;
  
  #echo
  #echo "Cleaned up the temp directory."
  #echo "Temp directory contains the following modules:"
  #find . -name '*.ko' -exec echo '{}' \;
  #read -p "Hit a key to continue!"
  
  cd $ksource
  
  #find . -name '*.ko' -exec cp '{}' $outdir/system/lib/modules/ \;
  #echo "Adding Network Driver..."
  find . -name 'bcm4329.ko' -exec cp '{}' $outdir/system/lib/modules/ \;
  if [ ! -e $outdir/system/lib/modules/bcm4329.ko ] 
  then
    echo "WARNING! Wifi module was not compiled. Aborting.."
    exit 1
  else
    echo " Network driver (bcm4329.ko) copied"
  fi
  
  date_str=`date '+%d%m%y_%H%M%S'` 
  dirname="kernel_$nameflag_$date_str"
  echo
  echo "Current kernel output dir name is $dirname"
  echo "You can change the name to kernel_[yourname]_$date_str"
  echo 
  read -p "Change the name?" -n 1
  echo
  if [[ $REPLY =~ ^[Yy]$ ]]
  then
    read -p "Enter new name:"
    #echo "Repy is " $REPLY
    nameflag=$REPLY
    dirname="kernel_"$nameflag"_"$date_str
    echo "New name will be $dirname"
    echo
    read -p "Hit a key to continue.."
  fi     
  
  pckdir="$packagedir/$dirname"
  mkdir $pckdir
  
  lastfolder=$pckdir
  cd $outdir/
  echo
  zipnoname="kbase_"$nameflag"_"$date_str
  zipaddnoname="kmods_"$nameflag"_"$date_str
  zipname=$zipnoname".zip"
  zipaddname=$zipaddnoname".zip"
  echo "Creating $zipname from $(pwd)"
  zip -r $zipnoname ./ 
  mv $zipname $pckdir/
  #echo $packagedir
  echo
  welcome="Created flashable zip: $pckdir/$zipname"
  msg_green
  
  read -p "Push to sdcard(N/y)?" -n 1
  echo
  if [[ $REPLY =~ ^[Yy]$ ]]
  then
    lastminpack=$pckdir"/"$zipname
    adb push $pckdir/$zipname /sdcard/ 
  fi  
  
  #welcome="Make Package with Additional Modules (N/y)?"
  #msg_green_wait
  read -p "Make Package with Additional Modules (N/y)?" -n 1
  echo  
  if [[ $REPLY =~ ^[Yy]$ ]]
  then    
    echo 
    cd $ksource
    echo "Kernel source is at $ksource"
  
    #find . -name '*.ko' -exec cp '{}' $outdir/system/lib/modules/ \;
    echo "Adding Additional Modules (if any)..."
    echo
    echo "Found the following modules:"
    find . -name '*.ko' -exec echo '{}' \;
    echo
    read -p "Hit a key to continue!"
    find . -name '*.ko' -exec cp '{}' $outdir/system/lib/modules/ \;
    read -p "Copying over. Hit a key to continue!"
    cd $outdir/
    
    echo "Creating $zipaddname from $(pwd)"
    zip -r $zipaddnoname ./ 
    mv $zipaddname $pckdir/
    ###############################
    
    welcome="Created a Full flashable package at $pckdir/$zipaddname"
    msg
    echo    
    
    read -p "Push to sdcard(N/y)?" -n 1
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]
    then
      lastmaxpack=$pckdir"/"$zipname
      adb push $pckdir/$zipaddname /sdcard/ 
    fi    
  fi
  
  
  read -p "Open Output folder in Dolphin (N/y)?" -n 1
  echo
  if [[ $REPLY =~ ^[Nn]$ ]]
  then
    menu
    exit 0
  else
    dolphin $pckdir &
    exit 0
  fi  
  menu
  exit 0
}

function menuconf {
  cd $kstartpath
  echo
  echo "Entering Menuconfig..."  
  #Working on Kubuntu
  #make ARCH=arm CC="arm-linux-gcc" LD="arm-linux-ld" AR="arm-linux-ar" RANLIB="arm-linux-ranlib" AS="arm-linux-as" -j10 -i all
  if [ ! -e ./Makefile ]
  then
    echo "This script should be executed from within the root directory of kernel"
    echo "Makefile could not be located in your current location. Aborting..."
    exit 1
  fi
  make ARCH=arm CROSS_COMPILE=$toolchain menuconfig
  menu
}

function defconf {
  cd $kstartpath
  echo
  echo "Generating defconfig"
  make ARCH=arm CROSS_COMPILE=$toolchain bravo_defconfig
  echo "Entering Menuconfig..."  
  #Working on Kubuntu
  #make ARCH=arm CC="arm-linux-gcc" LD="arm-linux-ld" AR="arm-linux-ar" RANLIB="arm-linux-ranlib" AS="arm-linux-as" -j10 -i all
  if [ ! -e ./Makefile ]
  then
    echo "This script should be executed from within the root directory of kernel"
    echo "Makefile could not be located in your current location. Aborting..."
    exit 1
  fi
  make ARCH=arm CROSS_COMPILE=$toolchain menuconfig
  menu
}

function cleanup {
  echo
  echo "Cleaning up.."
  make ARCH=arm CROSS_COMPILE=$toolchain clean
  read -p "Hit a key to continue.."
  menu
}

function toolch {
  echo
  echo "Current toolchain prefix is:$toolchain"
  echo "Note that script will not add paths for you. Do it manually!"
  echo 
  read -p "Enter new toolchain (including the -):"
  tempchain=$REPLY
  echo
  echo "New toolchain will be set as $tempchain"
  read -p "Confirm (y/N)?" -n 1
  if [[ $REPLY =~ ^[Yy]$ ]]
  then
    toolchain=$tempchain
    echo 
    echo "New toolchain prefix is now :$toolchain"
  else
    echo
    echo "Ok, Nothing will be modified!"
  fi
  read -p "Hit a key to continue.."
  menu
}

function disp_path () {
  echo
  echo "Current PATH is :"
  echo "$PATH"
  echo 
  read -p "Hit a key to continue.."
  menu  
}

function findcompilestatus {
    echo 
    welcome="Post compilation status"
    msg_blue
    welcome="Generated the following files:"
    msg_green
    cd $ksource
    find . -name 'zImage' -exec echo '{}' \; 
    find . -name '*.ko' -exec echo '{}' \;
    echo
    read -p "Hit a key to continue.."
    menu
    
}

function comp () {
  echo
  echo "Compiling Kernel..."
  if [ ! -e ./Makefile ]
  then
    echo "This script should be executed from within the root directory of kernel"
    echo "Makefile could not be located in your current location. Aborting..."
    exit 1
  fi
  make ARCH=arm CROSS_COMPILE=$toolchain -j$jobs
  if [ ! -e arch/arm/boot/zImage ]
  then
    echo "ERROR: An error occured. Kernel was not compiled."
    exit 1
  else
    echo "Making Modules..."
    echo
    make ARCH=arm CROSS_COMPILE="arm-bravo-" modules
    echo -en "\007"     
  fi
  findcompilestatus
  read -p "Hit a key to continue.."
  menu
}

function menu () {
clear
echo
echo " ======================================================="
welcome=" Kernel Compilation Script by Droidzone 01-11-2011 "
msg
echo " ======================================================="
echo 
echo " (D)efault config"
echo " (E)rase - Make Clean"
echo " (M)enuconfig"
echo " (C)ompile now"
echo " (F)lashable zip maker"
echo " (P)ush last zip to sdcard"
echo " (O)pen last output folder"
echo
echo " (Q)uit"
echo 
echo " Advanced Compilation Options"
echo " ----------------------------"
echo " 1. Change Toolchain prefix (Current : $toolchain )"
echo " 2. Pick a Toolchain from menu"
echo " 3. Change Number of simultaneous jobs (Current : $jobs )"
echo " 4. Display Current path"
echo " 5. Display Kernel Files"
echo " 6. Backup Menuconfig/.config"
echo
read -p " Choose an option :" -n 1
if [[ $REPLY =~ ^[1]$ ]]
then
  echo
  toolch
elif [[ $REPLY =~ ^[2]$ ]]
then
  echo    
  tcmenu  
elif [[ $REPLY =~ ^[4]$ ]]
then
  echo
  disp_path
elif [[ $REPLY =~ ^[5]$ ]]
then
  echo
  disp_kfiles
elif [[ $REPLY =~ ^[6]$ ]]
then
  echo  
  backup_menuconfig
elif [[ $REPLY =~ ^[Dd]$ ]]
then
  echo
  defconf
elif [[ $REPLY =~ ^[Ee]$ ]]
then
  echo
  cleanup
elif [[ $REPLY =~ ^[Mm]$ ]]
then
  echo
  menuconf
elif [[ $REPLY =~ ^[Cc]$ ]]
then
  echo
  comp
elif [[ $REPLY =~ ^[Ff]$ ]]
then
  echo
  lflashery
elif [[ $REPLY =~ ^[Pp]$ ]]
then
  echo  
  pushzip
elif [[ $REPLY =~ ^[Oo]$ ]]
then
  echo  
  openlast
elif [[ $REPLY =~ ^[Qq]$ ]]
then  
  echo
  exit 0
else
  menu
fi  
}

function additional () {
  ksource=$(pwd)
  read -p "Configure Menuconfig?" -n 1
  echo
  if [[ $REPLY =~ ^[Yy]$ ]]
  then
    menuconf
  fi  

  if [ ! -d $outdir ]; then mkdir $outdir; fi
  if [ ! -d $packagedir ]; then mkdir $packagedir; fi
  if [ ! -d $tempdir ]; then mkdir $tempdir; fi
  #Copying the new kernel files>

  if ls $outdir/*.zip > /dev/null 2>&1
  then
  rm $outdir/*.zip
  fi

  if ls $tempdir/README > /dev/null 2>&1
  then
  rm $tem
  fi
  read -p "Compile Kernel now?" -n 1
  echo
  if [[ $REPLY =~ ^[Yy]$ ]]
  then
    comp
  fi

  echo
  echo "Kernel compilation is over.."
  welcome="Generated the following files:"
  msgMm
  find . -name 'zImage' -exec echo '{}' \; 
  find . -name '*.ko' -exec echo '{}' \;
  echo ""
  read -p "Make Flashable zip now?" -n 1
  echo ""
  if [[ $REPLY =~ ^[Yy]$ ]]
  then
    lflashery
  fi
  menu
  exit 0
}

function tcmenu () {
  echo
  echo "Available Toolchains"
  echo "===================="
  echo "1. arm-bravo-"
  echo "2. NDK Toolchain: arm-linux-androideabi-"
  echo
  echo "Currently selected toolchain: $toolchain"
  echo
  read -p "Pick your toolchain:" -n 1
  echo
  if [[ $REPLY =~ ^[1]$ ]]
  then
    toolchain="arm-bravo-"
  elif [[ $REPLY =~ ^[2]$ ]]
  then
    toolchain="arm-linux-androideabi-"
  else
    echo "Invalid choice!"
  fi
  echo
  echo "Currently set as toolchain :$toolchain"
  echo
  read -p "Hit a key to continue.."
  menu    
}

#Compiled toolchain:
toolchain="arm-bravo-"

#NDK
#toolchain="arm-linux-androideabi-"
jobs=50
kstartpath=$(pwd)
lastfolder=""
nameflag=""
anykdir=/home/droidzone/flasher/AnyKernel
ksource=$kstartpath
outdir=~/kernel_flashable
packagedir=/home/droidzone/flasher/outdir
tempdir=~/kernel_flashable
mnameflag=""

#Main menu
menu
exit 0
 

Attachments

  • kmen.txt
    15 KB · Views: 161
Last edited:

sixstringsg

Retired Forum Mod / Retired Recognized Developer
Apr 11, 2009
5,171
6,903
Dallas, TX
If anyone needs kernel hosting, let me know. I have a helluva dedicated server that people are welcome to a piece of.
 

Chaqmol

Senior Member
Aug 19, 2010
121
273
I'v read 3 instructions with the same subject before...none of them were this much clear and usefull...tnx a lot
 

Droidzone

Inactive Recognized Developer
Sep 24, 2010
5,531
2,283
Kochi
www.droidzone.in
OnePlus 9 Pro
I'v read 3 instructions with the same subject before...none of them were this much clear and usefull...tnx a lot

I'm glad to hear that! I'm working on a bigger project on the same topic, integrating a Boot.img kitchen along with the other kernel menus. It has a lot of logic within and hence is proving very difficult to script. If all goes well, I may release it today. :)
 
  • Like
Reactions: Kalashnikitty

Kalashnikitty

Senior Member
Jun 12, 2010
427
214
im on work now and cant test your script, but i found this function in your source:

Code:
function menuconf {
  cd $kstartpath
  echo
  echo "Entering Menuconfig..."  
  #Working on Kubuntu
  #make ARCH=arm CC="arm-linux-gcc" LD="arm-linux-ld" AR="arm-linux-ar" RANLIB="arm-linux-ranlib" AS="arm-linux-as" -j10 -i all
  if [ ! -e ./Makefile ]
  then
    echo "This script should be executed from within the root directory of kernel"
    echo "Makefile could not be located in your current location. Aborting..."
    exit 1
  fi
  make ARCH=arm CROSS_COMPILE=$toolchain menuconfig
  menu
}

is this only a workaround for kubuntu? - because im working on mint (ubuntu)
 

Droidzone

Inactive Recognized Developer
Sep 24, 2010
5,531
2,283
Kochi
www.droidzone.in
OnePlus 9 Pro
im on work now and cant test your script, but i found this function in your source:

Code:
function menuconf {
  cd $kstartpath
  echo
  echo "Entering Menuconfig..."  
  #Working on Kubuntu
  #make ARCH=arm CC="arm-linux-gcc" LD="arm-linux-ld" AR="arm-linux-ar" RANLIB="arm-linux-ranlib" AS="arm-linux-as" -j10 -i all
  if [ ! -e ./Makefile ]
  then
    echo "This script should be executed from within the root directory of kernel"
    echo "Makefile could not be located in your current location. Aborting..."
    exit 1
  fi
  make ARCH=arm CROSS_COMPILE=$toolchain menuconfig
  menu
}

is this only a workaround for kubuntu? - because im working on mint (ubuntu)

Nope..the script works equally good on both kde and gnome...the $kstartpath is actually only the kernel start path.. Note that the script isnt self contained. For generation of flashable zip, you'll need to extract the zip template to $anykdir..

The only difference b/w kde and gnome is in opening the file managers-nautilus for gnome, dolphin for kde; similiarly text editors-kate for kde and gedit for gnome.. Newer script is even more intelligent! So much more syntax errors atm... :D
 

pRo_lama

Senior Member
May 10, 2008
1,407
346
Prague
I know that it is stupid question, but how flash kernel ??? Just via CWM (install zip from sdcard > choose zip from sdcard > zip file of kernel )or any other way ??
 

Alex-V

Inactive Recognized Developer
Aug 26, 2008
9,514
5,254
ok :)

after i must make this

sudo apt-get install ncurses-dev

i get the options menu :) before i get a error

with kind regards
 
  • Like
Reactions: Droidzone

Alex-V

Inactive Recognized Developer
Aug 26, 2008
9,514
5,254
mmhh...next prob...(sorry have said that iḿ a noob with kernel compile)

arm-linux-androideabi-gcc: command not found...

Did this means the path in bashrc is not right..? Or must i simple restart the laptop...did not rebootet after i set the line

with kind regards..Alex

EDIT...Sorry what i thought...a simple reboot did the trick...now compile... :) :)

but now i must go to bed :( but tomorrow :)
 
Last edited:

Alex-V

Inactive Recognized Developer
Aug 26, 2008
9,514
5,254
mmhh...sorry again...compile seems to be fine...but where is the zImage...? maybe it was a error and i did not see..will try tomorrow again

with kind regards
 
Last edited:

Top Liked Posts

  • There are no posts matching your filters.
  • 47
    I havent yet found a simple guide for compiling kernels. Some of them assume too much, and some are just outdated. So I thought I'd write my own for devs/budding devs. Here you go!

    Note:
    This is not a guide for newbies. It's a dev guide for devs.
    Research before asking questions, please

    For The Menu driven interactive kernel build script, see Post #31


    I will be developing this guide as I go, so it will be incomplete initially, or lacking in detailed explanations.

    Essentials:
    1. Ubuntu Box (By this I mean a PC with a Ubuntu installation, not a live CD)
    2. A toolchain-Either the Android NDK, or your own toolchain
    3. HTC Desire GB/Froyo source from htcdevs.com, or sources from github
    4. Familiarity with the linux shell and basic linux commands.
    5. The will to learn ;)

    First things first,

    1. Getting the sources


    The HTC Desire source is available from two kinds of resources-you can either get it from htcdevs.com (official HTC Dev site), or from source code uploaded from someone else. For the purpose of this tutorial, I'll assume we're working on the official HTC GB source code. So download bravo_2.6.35_gb-mr.tar.gz from htcdevs.com.


    2. Setting up the compilation box and preparing source code

    2.1 Install some essential linux packages from the Linux terminal:

    Code:
    sudo apt-get install libncurses5-dev


    2.2 Extract the source code

    The file you downloaded is a tar archive (like a zip file), so you need to extract it to a convenient location. Let's hit the linux shell-open a terminal window in linux (Accessories->Terminal)

    Type:
    Let's go to our home directory:
    Code:
    cd ~/
    Now, create the directories for our kernel compilation box.

    Code:
    mkdir -p ~/android/kernel
    Now you need to copy the tar.gz file from wherever you downloaded it to, to this dir.

    Extract the archive:
    Code:
    tar -xvf ~/android/kernel/bravo_2.6.35_gb-mr.tar.gz
    
    cd ~/android/kernel/bravo_2.6.35_gb-mr
    Now we can view the extracted files within the directory ~/android/kernel/bravo_2.6.35_gb-mr/

    2.3 Set up the toolchain

    A toolchain is a set of programs which allow you to compile source code (any source code, not just kernels). The toolchain is specific for the processor and hardware, so we need a toolchain specific for Android and especially the Desire. If you're a semiadvanced-pro user, you may consider compiling your own toolchain (See theGanymedes' guide for doing so). If compilation of kernels is all that you require, fortunately for you, there is an easy way-the Android NDK - v7 (latest as of now) is available here

    Get the NDK for Linux - android-ndk-r7-linux-x86.tar.bz2


    Code:
    mkdir -p ~/android/ndk
    Now copy the NDK file to ~/android/ndk

    Whenever I say copy, you have to manually copy the file with any file manager. Nautilus comes with Ubuntu, and Dolphin with Kubuntu. You may also use the shell of course with

    Code:
    cp [sourcefile] [destination]
    Extract it:

    Code:
    tar -jvxf android-ndk-r7-linux-x86.tar.bz2
    Now add the path for your toolchain to the env variable:

    Code:
    gedit ~/.bashrc
    At the end of the file, add this line:
    Code:
    PATH=$PATH:~/android/ndk/android-ndk-r7-linux-x86/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin


    3. Setting up kernel parameters

    Kernels are compiled with a program called gnu make, and use a set of configuration options specified within a file called Makefile.

    A vital point to note is that kernels are compiled with a program called gcc (basically the gnu C compiler), and our NDK itself has its own optimized version of gcc. While compiling, we're actually cross compiling it (meaning compiling a binary package on a system which is different from the actual system which is meant to run it- you're compiling it on your PC while it's actually meant to run on your Desire)

    This means that when you compile it, you have to make sure that you compile it with the NDK's version of gcc instead of the system version. Otherwise you end up with a kernel meant to run on your pc, duh! Specifying which gcc to use is by the CROSS_COMPILE variable. You can set it up with this command:
    Code:
    CROSS_COMPILE=arm-linux-androideabi-
    Note the hyphen (-) at the end, and do not forget to include it! At compilation time, system will actually use this variable to find all the programs it needs. Eg: The path for gcc will become arm-linux-androideabi-gcc

    We can compile kernels with many different options, like with ext4 support, or without; ext4 support as part of the kernel zImage (in which case it makes the kernel larger), or as a loadable module (of the form somename.ko, which is loaded at init.d/init.rc with the command insmod modulename.ko)

    We specify the exact options we require with the help of a useful configuration program called menuconfig (which as the name suggests, is a menu for configuration of make options).

    An important thing to note is that as far as kernel compilation is concerned, there are a vast amount of options to setup, and unless you're thorough with kernel compilation, you wont be able to set up the options correctly and get your kernel to boot. Fortunately for us, the kernel source already comes with a default set of parameters which can be easily set up.

    Note that all make commands must be executed within the directory bravo_2.6.35_gb-mr. Let's go there now:

    Code:
    cd  ~/android/kernel/bravo_2.6.35_gb-mr
    make ARCH=arm CROSS_COMPILE=arm-linux-androideabi- bravo_defconfig
    This produces a .config file (used by the menuconfig) containing essential parameters to produce a booting kernel for the Desire.

    Note: There is a simpler way to get the basic .config file, and this is to get it from a running kernel built by someone else. You can extract the .config from a running kernel with these commands:

    Code:
    cd  ~/android/kernel/bravo_2.6.35_gb-mr
    adb pull /proc/config.gz
    zcat config.gz > .config
    Now we can open menuconfig and add anything we need in addition.

    Code:
    make ARCH=arm CROSS_COMPILE=arm-linux-androideabi- menuconfig
    You can view the huge amount of options available in menuconfig.

    You can add ext4 support for example (See image above)
    Once you're done choosing options, you can exit menuconfig.

    4. Compiling it

    This is simple. The basic command is:

    make ARCH=arm CROSS_COMPILE=arm-linux-androideabi- -j10

    The -j10 specifies the number of jobs to execute per operation. I can usually go upto 50 on my Quad core CPU. Beware, this can bring a slow CPU to a crawl and freeze up linux itself.

    During compilation, you will see all sorts of messages, which may include warnings too. In most cases, its safe to ignore warnings. If there are errors, the compilation will stop, and you will have to fix the issues.

    5. Distributing your kernel to users
    At the end of compilation, it generates files named zImage, and various .ko files.

    You have to copy them from their default location to a zip file. The best way is to use my variant of koush's Anykernel, and copy the files to it. Then, you can zip the whole folder and lo and behold-you have your flashable kernel zip which you can distribute to others.

    You can also remove the zImage and the modules from /system/lib/modules of any kernel zip available with you, and copy over your files to it, at the correct location.

    So, let's say that you have extracted an existing kernel zip to the location ~/flashable

    The file structure should be like this:

    Code:
    |-- kernel
    |   |-- dump_image
    |   |-- mkbootimg
    |   |-- mkbootimg.sh
    |   |-- unpackbootimg
    |   `-- zImage
    |-- META-INF
    |   |-- CERT.RSA
    |   |-- CERT.SF
    |   |-- com
    |   |   `-- google
    |   |       `-- android
    |   |           |-- update-binary
    |   |           `-- updater-script
    |   `-- MANIFEST.MF
    `-- system
        `-- lib
            `-- modules
                `-- bcm4329.ko
    
    8 directories, 11 files
    I've included my flashable zip directory along with this post. Download file kernel_flashable.tar.bz2.zip to ~/

    Code:
    cd ~/
    tar -jvxf kernel_flashable.tar.bz2.zip
    This will create the directory structure outlined above.

    Now after every compilation of the kernel, execute these commands from where you executed make:

    Code:
    cp arch/arm/boot/zImage ~/kernel_flashable
    find . -name '*ko' -exec cp '{}' ~/kernel_flashable/system/lib/modules/ \;
    cd ~/kernel_flashable
    zip -r mykernel ./
    This will create mykernel.zip at ~/kernel_flashable. You can distribute this to your users to flash. Make sure you edit updater-script before though :)
    20
    Common errors and other stuff

    Ok, post #1 was simple stuff. Now, supposing you get errors while compiling. Post #2 is about that, and ups the level of knowledge a bit..

    Some kernel compilation errors:

    Treat warnings as errors-Solved by removing the string "-Werror" from all Makefiles of the file which failed to compile. Some people had said that the real error (Array out of bounds warning) was because of gcc optimizations. But putting -O2 to -O0 didnt do a thing.
    No of jobs - ought not to exceed 50.
    "warning: variable set but not used [-Wunused-but-set-variable]"-Look at KBUILD_CFLAGS in the main Makefile. Add -Wno-error=unused-but-set-variable to the existing set of flags.


    Note the following from gcc manual:



    -WerrorMake all warnings into hard errors. Source code which triggers warnings will be rejected.
    -w Inhibit all warning messages. If you're familiar with C code and like to fix stuff, rather than ignoring potential bugs, use this only as a last resort- A 'brahmastram' (most powerful weapon in your time of gravest need) as the epics would say ;)
    -WerrorMake all warnings into errors.
    -Werror=Make the specified warning into an error. The specifier for a warning is appended, for example -Werror=switch turns the warnings controlled by -Wswitch into errors. This switch takes a negative form, to be used to negate -Werror for specific warnings, for example -Wno-error=switch makes -Wswitch warnings not be errors, even when -Werror is in effect. You can use the -fdiagnostics-show-option option to have each controllable warning amended with the option which controls it, to determine what to use with this option.

    So what I did to suppress errors was to add:
    Code:
    KBUILD_CFLAGS += -w
    KBUILD_CFLAGS += -Wno-error=unused-but-set-variable


    Though the -Wunused-but-set-variable is not a real issue in itself, it generates so much "noise" that you may miss actual make errors.

    This is the error what I was talking about..

    Code:
    drivers/net/wireless/bcm4329_204/wl_iw.c: In function 'wl_iw_set_pmksa':
    drivers/net/wireless/bcm4329_204/wl_iw.c:5075:5: error: array subscript is above array bounds [-Werror=array-bounds]
    drivers/net/wireless/bcm4329_204/wl_iw.c:5078:5: error: array subscript is above array bounds [-Werror=array-bounds]

    Solution:
    Edit drivers/net/wireless/bcm4329_204/Makefile

    Locate -Werror within DHDCFLAGS, and delete it.


    Code:
    DHDCFLAGS = -DLINUX -DBCMDRIVER -DBCMDONGLEHOST -DDHDTHREAD -DBCMWPA2 \
    -DUNRELEASEDCHIP -Dlinux -DDHD_SDALIGN=64 -DMAX_HDR_READ=64 \
    -DDHD_FIRSTREAD=64 -DDHD_GPL -DDHD_SCHED -DBDC -DTOE -DDHD_BCMEVENTS \
    -DSHOW_EVENTS -DBCMSDIO -DDHD_GPL -DBCMLXSDMMC -DBCMPLATFORM_BUS \
    -Wall -Wstrict-prototypes -Werror -DOOB_INTR_ONLY -DCUSTOMER_HW2 \
    -DDHD_USE_STATIC_BUF -DMMC_SDIO_ABORT -DWLAN_PFN -DWLAN_PROTECT \
    -DBCMWAPI_WPI \

    This will prevent gcc from treating mere warnings as errors.
    15
    How to modify kernels by applying mods - Applying Kernel Patches

    Ok, you have compiled a simple stock kernel. Now what? Would you like to add fixes/mods developed by other kernel devs? This post explains patches and how exactly to do this.

    Patches to the kernel are applied via patch files. Patch files are simple text files generated by the linux diff program which takes two text files, compares them and writes the differences (hence called diff) to another text file which by convention has the extension .patch

    Attached to this post is a patch containing my "Extended battery" fix with Sibere's battfix. I'll explain patching with this. Let's understand the patch file. Open it up in any text editor.

    Code:
    diff -rupN -X /home/droidzone/android/kernel/exclude.opts bravo_2.6.35_gb-mr/drivers/power/ds2784_battery.c bravo_2.6.35_gb-mr.main//drivers/power/ds2784_battery.c
    --- bravo_2.6.35_gb-mr/drivers/power/ds2784_battery.c    2011-08-25 13:16:53.000000000 +0530
    +++ bravo_2.6.35_gb-mr.main//drivers/power/ds2784_battery.c    2011-11-06 16:43:21.544317342 +0530
    @@ -118,8 +118,11 @@ PS. 0 or other battery ID use the same p
     /* Battery ID = 1: HT-E/Formosa 1400mAh */
     #define BATT_ID_A                1
     #define BATT_FULL_MAH_A            1400
    -
     #define BATT_FULL_MAH_DEFAULT    1500
    +#define BATT_FULL_MAH_CAMERONSINO    2400
    +#define BATT_ID_CAMERONSINO
    +#define BATT_TYPE 0
    +
    Note the first line:
    Code:
    diff -rupN -X /home/droidzone/android/kernel/exclude.opts  bravo_2.6.35_gb-mr/drivers/power/ds2784_battery.c  bravo_2.6.35_gb-mr.main//drivers/power/ds2784_battery.c
    diff -rupN basically describes the command that was used to generate this patch. The -u means that the patch file is something called a universal patch

    bravo_2.6.35_gb-mr/drivers/power/ds2784_battery.c was the original file, and bravo_2.6.35_gb-mr.main//drivers/power/ds2784_battery.c was the target file or file which contains the mod..

    How to apply patch files?

    The command depends on where your current directory is. If you're in ~/android/kernel/bravo_2.6.35_gb-mr/ and your current directory contains the directory 'drivers', you can apply this patch with this command:

    Code:
    patch -p1<extended_battfix.patch

    If you're within drivers, then you have to modify the command like this:

    Code:
    patch -p2<extended_battfix.patch

    Hope you get the gist. Basically, as you move into the source tree, you have to increment the patch level by the number of directories you've moved down into. Very simple, isnt it?
    5
    Sharing and Collaborating - Using Github and Commits

    Kernel compilation is a group effort (at least it ought to be). When different devs work on different parts of the code and create their own mods, development progresses. For this purpose, it is important that you share your code with other devs. The best way to do this to upload your sources to github.

    First, create a github account.

    Next you can view other devs' github sources and examine their commits. Commits are basically patches applies to the previous source uploaded. Github commits use the universal patch format and can be viewed directly, downloaded as patch files, and applied to your code. You can also choose to download the whole source tree uploaded by another dev and examine it.
    4
    Ok, the basic guide is done, guys... If you have doubts, I'll try to clear them