[LG Optimus 3D] samno:
Making The Custom Kernel

So this is the post some of youve probably been waiting for & probably going to be the hardest one to write up so im gonna apologise now for my lack of typing & explaining skill :p You will need a linux distro for this bit, as ive not tryed using compilers for Windows. Any distro should be fine im currently using Ubuntu 12.04 LTS but have sucessfully done this on older versions. Im only going to cover the basic stuff with this guide it would be impossible to show you everything but ill show you a couple of mods to get started like overclock, a few fixes of LG's mistakes (For V21E Base only, other LG kernel's may have there own problems too PM me if your stuck) & changing a few variables stuff.

Getting Set-Up

Ok first off we will need to get our source. You get this from the LG Open Source website, link is attached in the first post. Obviously we want the latest 21E source or if your doing this for P925, get the latest or the one you want for that. Then youll need to download & extract it. This will be fine to do in the 'Download' folder. Once you have extracted it youll have another 2 tar archives. You will want to extract the LGP920_Gingerbread_Kernel.tar.gz, again in the same directory your in will be fine. So now you should have a folder named 'kernel'. Before you can continue we will need to rename the base directory to something more simple like LGP920v21ESource otherwise if you have brackets and other punctuation stuff it will give you a syntax error later.

Next we will need the ARM Toolchain in order to compile your kernel source. This is in the first post, this is the same toolchain that LG uses to compile it. You can use other compilers but you will have to modify a few things to get it working. That is for another post another day maybe. So now we need to extract the toolchain, do this in the same way as before in the 'Download' folder. Now youll have a folder named 'insert proper folder name here' this is your toolchain. Now we have our toolchain and source all unpacked and ready to go, youll need to open Terminal or your prefered terminal app. This next bit will be much easier if you extracted everything in the explanation above. For the next set of instructions just change my user name with yours and if you did the same directories as me this should be simple.

Ok so in terminal cd to inside your kernel like this for expample:

cd /home/samno/Downloads/LGP920v21ESource/kernel

Dont get confused about the kernel directory inside the kernel folder you want to be at the base of the rest of the files.You should have the kernel directory open in file browser too. If you want you can type cd in terminal and then drag the folder in the top of the file manager and drag it into the terminal window where you typed cd, this will save you making typo's and be quicker/easier.

Next we need to set the export/path for our toolchain so in terminal enter this for example:

export CROSS_COMPILE=/home/samno/Downloads/arm-2010q1/bin/arm-none-linux-gnueabi-

export PATH=$PATH:/home/samno/Downloads/arm-2010q1/bin

Exporting the path isnt completely necessary but is useful if you want to compile other things than this. Now we should be ready to compile.

Compiling The zImage

First thing we will need to to is edit the makefile in the base directory. Open with gedit and add '+' to the 7 where it says EXTRAVERSION = .7. This will make the kernel compatible with the 21E modules such as wifi. If you are devoloping for sources without a '+' such as 20F you can leave this bit. You could also make your own modules if you wanted but i might cover that later. I dont do this cause it can cause compatibilty problems for people swapping kernel all the time, especially when the kernel they flash isnt compatible with the modules of another kernel for example my kernel uses stock modules found already in the roms we use where as iblue for example compiles and includes his own in the kernel package. If you flash one over another then the modules wont work with another kernel version.

Ok what we want to do next is fix the defconfig for our device or just use a different one in our case. This is located in the arch/arm/configs directory. This was a problem when devs first started compiling to find out when they flashed it they no signal and charging issues when the phone is off. Cause we are meant to use the cosmo_rev_1.11_defconfig but it had cricial lines missing. Only by me messing about did i discover that the lines needed were located in the cosmo_rev_1.11_mipi_defconfig.

So in terminal you should still be in the kernel directory, now enter this command:

make ARCH=arm cosmo_rev_1.11_mipi_defconfig zImage

Dont worry it come up with loads of stuff as it compiles but i will come to an error which we need to fix before it will continue. The good thing about the complier it will give you a good idea where to look like the file and error location.

So it should come up with something like this:

CHK include/linux/version.h
CHK include/generated/utsrelease.h
make[2]: `include/generated/mach-types.h' is up to date.
CALL scripts/checksyscalls.sh
CHK include/generated/compile.h
CC drivers/staging/omap_hsi/xmd-hsi-ll.o
In file included from drivers/staging/omap_hsi/xmd-hsi-ll.c:33:
drivers/staging/omap_hsi/xmd-hsi-ll-internal.h:256: error: expected specifier-qualifier-list before 'if'
drivers/staging/omap_hsi/xmd-hsi-ll-internal.h:434: error: #endif without #if
drivers/staging/omap_hsi/xmd-hsi-ll.c: In function 'hsi_ll_read_complete_cb':
drivers/staging/omap_hsi/xmd-hsi-ll.c:707: error: 'struct hsi_ll_rx_ch' has no member named 'open_id'
drivers/staging/omap_hsi/xmd-hsi-ll.c:707: error: 'struct hsi_ll_rx_ch' has no member named 'open_size'
drivers/staging/omap_hsi/xmd-hsi-ll.c:708: error: 'struct hsi_ll_rx_ch' has no member named 'retry_cnt'
drivers/staging/omap_hsi/xmd-hsi-ll.c:711: error: 'struct hsi_ll_rx_ch' has no member named 'open_id'
drivers/staging/omap_hsi/xmd-hsi-ll.c:711: error: 'struct hsi_ll_rx_ch' has no member named 'retry_cnt'
drivers/staging/omap_hsi/xmd-hsi-ll.c:713: error: 'struct hsi_ll_rx_ch' has no member named 'open_id'
drivers/staging/omap_hsi/xmd-hsi-ll.c:714: error: 'struct hsi_ll_rx_ch' has no member named 'open_size'
drivers/staging/omap_hsi/xmd-hsi-ll.c:715: error: 'struct hsi_ll_rx_ch' has no member named 'retry_cnt'
drivers/staging/omap_hsi/xmd-hsi-ll.c:718: error: 'struct hsi_ll_rx_ch' has no member named 'retry_cnt'
drivers/staging/omap_hsi/xmd-hsi-ll.c:720: error: 'struct hsi_ll_rx_ch' has no member named 'retry_cnt'
drivers/staging/omap_hsi/xmd-hsi-ll.c:722: error: 'struct hsi_ll_rx_ch' has no member named 'open_id'
drivers/staging/omap_hsi/xmd-hsi-ll.c:722: error: 'struct hsi_ll_rx_ch' has no member named 'retry_cnt'
drivers/staging/omap_hsi/xmd-hsi-ll.c:733: error: 'struct hsi_ll_rx_ch' has no member named 'open_id'
drivers/staging/omap_hsi/xmd-hsi-ll.c:734: error: 'struct hsi_ll_rx_ch' has no member named 'open_size'
drivers/staging/omap_hsi/xmd-hsi-ll.c:736: error: 'struct hsi_ll_rx_ch' has no member named 'retry_cnt'
drivers/staging/omap_hsi/xmd-hsi-ll.c:737: error: 'struct hsi_ll_rx_ch' has no member named 'retry_cnt'
drivers/staging/omap_hsi/xmd-hsi-ll.c: In function 'hsi_ll_check_channel':
drivers/staging/omap_hsi/xmd-hsi-ll.c:1476: error: operator '/' has no right operand
drivers/staging/omap_hsi/xmd-hsi-ll.c: In function 'hsi_ll_open':
drivers/staging/omap_hsi/xmd-hsi-ll.c:1642: error: 'struct hsi_ll_rx_ch' has no member named 'open_id'
drivers/staging/omap_hsi/xmd-hsi-ll.c:1643: error: 'struct hsi_ll_rx_ch' has no member named 'open_size'
drivers/staging/omap_hsi/xmd-hsi-ll.c:1644: error: 'struct hsi_ll_rx_ch' has no member named 'retry_cnt'
drivers/staging/omap_hsi/xmd-hsi-ll.c: In function 'hsi_ll_reset':
drivers/staging/omap_hsi/xmd-hsi-ll.c:2725: error: 'struct hsi_ll_rx_ch' has no member named 'open_id'
drivers/staging/omap_hsi/xmd-hsi-ll.c:2726: error: 'struct hsi_ll_rx_ch' has no member named 'open_size'
drivers/staging/omap_hsi/xmd-hsi-ll.c:2727: error: 'struct hsi_ll_rx_ch' has no member named 'retry_cnt'
make[4]: *** [drivers/staging/omap_hsi/xmd-hsi-ll.o] Error 1
make[3]: *** [drivers/staging/omap_hsi] Error 2
make[2]: *** [drivers/staging] Error 2
make[1]: *** [drivers] Error 2

So lets go to the first error, line 256 of the xmd-hsi-ll-internal.h. Simply add # before 'if defined' like this '#if defined'. Save the file then go back to terminal and enter the make command or press up arrow and press enter. Youll notice alot of errors have gone when it errors out again and it should look like this:

CHK include/linux/version.h
CHK include/generated/utsrelease.h
make[2]: `include/generated/mach-types.h' is up to date.
CALL scripts/checksyscalls.sh
CHK include/generated/compile.h
CC drivers/staging/omap_hsi/xmd-hsi-ll.o
drivers/staging/omap_hsi/xmd-hsi-ll.c: In function 'hsi_ll_check_channel':
drivers/staging/omap_hsi/xmd-hsi-ll.c:1476: error: operator '/' has no right operand
make[4]: *** [drivers/staging/omap_hsi/xmd-hsi-ll.o] Error 1
make[3]: *** [drivers/staging/omap_hsi] Error 2
make[2]: *** [drivers/staging] Error 2
make[1]: *** [drivers] Error 2
make: *** [zImage] Error 2

Again fixing this error is like the first one, goto line 1476 of xmd-hsi-ll.c simply delete the '/' like this '#if 1' where it was '#if 1 /'. Save again then back to terminal again where it will you guessed it error out again. Should look like this;

CHK include/linux/version.h
CHK include/generated/utsrelease.h
make[2]: `include/generated/mach-types.h' is up to date.
CALL scripts/checksyscalls.sh
CHK include/generated/compile.h
CC drivers/staging/omap_hsi/xmd-hsi-ll.o
CC drivers/staging/omap_hsi/hsi_driver_if.o
drivers/staging/omap_hsi/hsi_driver_if.c: In function 'hsi_ioctl':
drivers/staging/omap_hsi/hsi_driver_if.c:930: error: 'HSI_IOCTL_SET_WAKE_RX_3WIRES_MODE' undeclared (first use in this function)
drivers/staging/omap_hsi/hsi_driver_if.c:930: error: (Each undeclared identifier is reported only once
drivers/staging/omap_hsi/hsi_driver_if.c:930: error: for each function it appears in.)
drivers/staging/omap_hsi/hsi_driver_if.c:945: error: 'HSI_IOCTL_SET_WAKE_RX_4WIRES_MODE' undeclared (first use in this function)
make[4]: *** [drivers/staging/omap_hsi/hsi_driver_if.o] Error 1
make[3]: *** [drivers/staging/omap_hsi] Error 2
make[2]: *** [drivers/staging] Error 2
make[1]: *** [drivers] Error 2
make: *** [zImage] Error 2

Fixing this one will be similar too. If you read the error its says this bit of code hasnt been declared for a function, most probably LG have missed some more code here for it to work or it was left over from testing the ghost call stuff. The only way to get rid of this error that i know of is to do away with the line completely. So go to line 930 of hsi_driver_if.c and delete 'case HSI_IOCTL_SET_WAKE_RX_3WIRES_MODE:' and the space that it leaves and do the same for 'case HSI_IOCTL_SET_WAKE_RX_4WIRES_MODE:'.

Do the make command again and thats it no more errors and it should look like this:

OBJCOPY arch/arm/boot/Image
Kernel: arch/arm/boot/Image is ready
AS arch/arm/boot/compressed/head.o
GZIP arch/arm/boot/compressed/piggy.gzip
AS arch/arm/boot/compressed/piggy.gzip.o
CC arch/arm/boot/compressed/misc.o
CC arch/arm/boot/compressed/decompress.o
SHIPPED arch/arm/boot/compressed/lib1funcs.S
AS arch/arm/boot/compressed/lib1funcs.o
LD arch/arm/boot/compressed/vmlinux
OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready

Congratulations! Youve just compiled your first kernel.

Making Your RamDisk & Boot.img

Well done! Now we need to package your zImage up into a useable form. This part will be similar to Urabewe's guide here http://xdaforums.com/showthread.php?t=1358717 , kudos to him for such an excellent guide, the only difference is were using our own zImage.Remember the backup you did earlier of your stock rom, were gonna need it again for this part. Firstly were gonna need to make sure we have got the tools to decompress/compress the boot.img. Again you will need a Linux distrubution like Ubuntu to be able to do this. So first off if you havnt got it already, we need to download the packaging tool using terminal. Enter the command as follows:

sudo apt-get install uboot-mkimage

Good now we need the perl script from the first post. Download and extract it to a folder and call it 'My1stKernel' for example. In this folder paste the boot.img from you stock backup. This will be used as our ramdisk base which we will work from. Now we need to unpack the boot.img but first we need to make sure were in the 'My1stKernel' directory so in terminal:

cd /home/samno/Downloads/My1stKernel

Then to unpack the kernel:

./unpack-bootimg.pl boot.img

When completed you will have a new directory inside named 'boot.img-ramdisk' & two gunzip compressed files, 'boot.img-kernel' is the stock zImage and 'boot.img-ramdisk.cpio.gz' is the stock ramdisk. The 'boot.img-ramdisk' contains the decompressed ramdisk contents. First thing to do now is delete 'boot.img-kernel' , 'boot.img-ramdisk.cpio.gz' & the old 'boot.img' since we only need the 'boot.img-ramdisk' cause were editing the ramdisk and using our own zImage. Now copy and paste the zImage you created earlier from the 'arch/arm/boot' directory of the kernel folder into 'My1stKernel' folder.

Now were gonna add some tweaks to the ramdisk to do this open the 'boot.img-ramdisk' folder and open the 'init.rc'.

First were gonna add a cpu variable for the screen off state, this helps save a bit of power.

Where the line says '# switch CPUfreq from performance to hotplug & tune it' add this underneath to keep the max frequency when screen is off to 300mhz:

write /sys/devices/system/cpu/cpu0/cpufreq/screen_off_max_freq 300000

Next were gonna add init.d support. So after these few lines in the init.rc:

service bootanim /system/bin/bootanimation
user graphics
group graphics
disabled
oneshot

Add this:

service userscript /system/bin/sh /sbin/initd.sh
user root
group system
critical
oneshot

This basically tells the system to load this file, which were gonna add next. Now save the file and start a new text document. In the document add this bit of text:

#!/system/bin/sh
if [ -d /system/etc/init.d ]
then
logwrapper busybox run-parts /system/etc/init.d
fi
sync

This is basically a script that runs the items in the init.d folder at boot so now save it as initd.sh in the sbin directory of your 'boot.img-ramdisk' folder. Youll notice the top command should turn blue, that means you have saved the file in the correct format. Good so now we should package all this up, but if you want you can add more mods to the init.rc like your memory management, more cpu controls, IO controls & lots of other stuff, anyway.

Making Your Boot.img

Almost there now guys! Let's package this up and enjoy the fruits of your labour. Assuming you still have your terminal window open in 'My1stKernel' directory type this command:

cd boot.img-ramdisk

Then this to compress the ramdisk:

find . | cpio -o -H newc | gzip > ../newramdisk.cpio.gz

Now in your 'My1stKernel' folder you will have a new gunzip archive named 'newramdisk.cpio.gz' this is the ramdisk you modified earlier. Now we need to bind it with your custom zImage to make a boot.img. So get terminal back up and go back to the previous directory:

cd /home/samno/Downloads/My1stKernel

Then enter this to combine them:

mkimage -A ARM -T multi -n newboot -C None -a 0x80008000 -e 0x80008000 -d zImage:newramdisk.cpio.gz boot.img

You should then have a lovely file named boot.img, simply just paste it into the flash package ive provided below for you then flash to your phone through CWR. Thats it, you & me we have come a long way, you should now have a rom and kernel you have made by yourself. Now lets party, unless it dosnt work :( just restore or flash another kernel :) . If you need any clarification or help just post in this thread and we can all help each other. Also would love to here your sucess stories if you used my guide and on a final note i want to thank everyone who's ever developed for this device and those who will cause youve helped me so much (even though you probably dont know ;) ) through my entire time with this.