2013年9月25日 星期三

KGDB + Eclipse debug Kernel on i.mx6 Android

Ref:
kgdb teaching
https://www.kernel.org/pub/linux/kernel/people/jwessel/kdb
kgdb freescale
http://cache.freescale.com/files/32bit/doc/app_note/AN4553.pdf
agent-proxy
http://stackoverflow.com/questions/17329794/sysrq-g-wont-break-kernel
eclipse setting
https://books.google.com.tw/books?id=AUsOCgAAQBAJ&pg=PA169
gcc param
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//make menuconfig
apt-get install libncurses-dev
root@stonelinux:~/project_board/free_imx/out/matrix_io/kernel# make ARCH=arm menuconfig

note: rebuild.sh will copy cover .config

/////use minicom to watch target console (option item)
http://processors.wiki.ti.com/index.php/Setting_up_Minicom_in_Ubuntu

apt-get install minicom

~# ll /dev/ttyUSB0*
crw-rw---- 1 root dialout 188,  0 10月 13 15:09 /dev/ttyUSB0

minicom -s
A -  序 列  設 備 -> /dev/ttyUSB0
F -  硬  體  Flow 控制 -> No

儲存設定為 dfl
Exit Minicom
~#minicom

ps: flow control, 它是用資料中兩個bytes XON(0x11), XOFF (0x13)來做這流量控制, 而當要送這個bytes時就會呼叫這一個call back function, 而且這兩個必須要馬上被送出, 不可放在buffer之中.

//////
backup /root/project_board/free_imx/out/matrix_io/kernel/.config
to
/root/project_board/free_imx/out/matrix_io/kernel/.config_old

cd /root/project_board/free_imx/out/matrix_io/kernel/
make ARCH=arm menuconfig
       
        Device Drivers  ---->;
        [ ]Watchdog Timer Support
    
    Kernel hacking ---->;
        [*] Compile the kernel with debug info
        [*] Kernel debugging
        [*] KGDB: kernel debugger (NEW)  --->;
                <*>   KGDB: use kgdb over the serial console (NEW)                                       
                [ ]   KGDB_KDB: include kdb frontend for kgdb                       
                [ ]     KGDB_KDB: keyboard as input device
               
save and exit

////////compare config
/root/project_board/free_imx/out/matrix_io/kernel/.config
vs
/root/project_board/free_imx/out/matrix_io/kernel/.config_old

modify new config
gedit /root/project_board/free_imx/myandroid/kernel_imx/arch/arm/configs/mx6dq_matrix_android_defconfig

Watchdog在實現上可以是硬件電路也可以是軟件定時器,能夠在系統出現故障時自動重新啟動系統。在Linux的內核下,監督的基本工作原理是:當看門狗啟動後(/dev/看門狗設備被打開後)如果在某一設定的時間間隔內的/dev/看門狗沒有被執行寫操作,硬件看門狗電路或軟件定時器就會重新啟動系統。

disable
#CONFIG_WATCHDOG=y

add
CONFIG_MAGIC_SYSRQ=y     //make sure open it
CONFIG_CONSOLE_POLL=y  //after CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_DEBUG_INFO=y
CONFIG_FTRACE=y
CONFIG_FUNCTION_TRACER=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y

note:
Kconfig's priority higher than mx6dq_matrix_android_defconfig
CONFIG_FTRACE & CONFIG_FUNCTION_TRACER will enable CONFIG_FRAME_POINTER
config FRAME_POINTER in ~/myandroid/kernel_imx/arch/arm/Kconfig.debug

///////////linux + android will start about 400 threads
///////////debug will very slow
///////Way 1. begin
gedit /root/project_board/free_imx/myandroid/kernel_imx/Makefile
KBUILD_CFLAGS    += -O2
to
KBUILD_CFLAGS    += -O1 -g

//I want debug all drivers, so
gedit /root/project_board/free_imx/myandroid/kernel_imx/drivers/Makefile
//first line add
KBUILD_CFLAGS    += -O0 -g

~#gedit /root/project_board/free_imx/myandroid/kernel_imx/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
init 2 vars;
gctUINT32 physAddr;
gctUINT32 physical;
to
gctUINT32 physAddr = 0;
gctUINT32 physical = 0;
////Way 1. end

I select Way 1. to compile

//////////gcc optimize verbose
//////////KBUILD_CFLAGS    += -O1 -g -Q -v
//////////ref. only
-fcombine-stack-adjustments \
-fcompare-elim \
-fcprop-registers \
-fdefer-pop \
-fforward-propagate \
-fguess-branch-probability \
-fif-conversion \
-fif-conversion2 \
-finline \
-fipa-profile \
-fipa-pure-const \
-fipa-reference \
-fmerge-constants \
-fsection-anchors \
-ftoplevel-reorder \
-ftree-bit-ccp \
-ftree-ccp \
-ftree-ch \
-ftree-copy-prop \
-ftree-copyrename \
-ftree-dce \
-ftree-dominator-opts \
-ftree-dse \
-ftree-fre \
-ftree-sink \
-ftree-sra \
-ftree-ter
//////////ref. only end

/////////debug all kernel in -O0
////Way 2. begin
gedit /root/project_board/free_imx/myandroid/kernel_imx/Makefile
KBUILD_CFLAGS    += -O2
to
KBUILD_CFLAGS    += -O0 -g

add after KBUILD_CFLAGS += $(KCFLAGS)
KBUILD_CFLAGS    += \
-ftoplevel-reorder \
-ftree-bit-ccp \
-ftree-ccp \
-ftree-dominator-opts

//for watch flags only can skip it
KBUILD_VERBOSE = 0
to
KBUILD_VERBOSE = 1

///**************
////way 2. -O0 need edit some files
//**************
~#gedit /root/project_board/free_imx/myandroid/kernel_imx/include/linux/huge_mm.h
/*#define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; })
#define HPAGE_PMD_MASK ({ BUILD_BUG(); 0; })
#define HPAGE_PMD_SIZE ({ BUILD_BUG(); 0; })*/
//change to
#define HPAGE_PMD_SHIFT ({ 0; })
#define HPAGE_PMD_MASK ({ 0; })
#define HPAGE_PMD_SIZE ({ 0; })

///////
~#gedit /root/project_board/free_imx/myandroid/kernel_imx/include/linux/pagemap.h
mark to
    //if (unlikely(is_vm_hugetlb_page(vma))) //equal if(0)
        //return linear_hugepage_index(vma, address);

/////
~#gedit /root/project_board/free_imx/myandroid/kernel_imx/arch/arm/kernel/traps.c
after EXPORT_SYMBOL(__bad_xchg) add
void __bad_cmpxchg(volatile void *ptr, int size)
{
    printk("cmpxchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
        __builtin_return_address(0), ptr, size);
    BUG();
}
EXPORT_SYMBOL(__bad_cmpxchg);

//////
~#gedit /root/project_board/free_imx/myandroid/kernel_imx/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
//init 2 vars;
gctUINT32 physAddr = 0;
gctUINT32 physical = 0;

///////
~#gedit /root/project_board/free_imx/myandroid/kernel_imx/fs/binfmt_elf.c
before static int alignfile(struct file *file, loff_t *foffset)
add
#define x_roundup(x, y) ((((x) + ((y)-1)) / (y)) * (y))

//DUMP_WRITE(buf, roundup(*foffset, 4) - *foffset, foffset);
to
    DUMP_WRITE(buf, x_roundup(*foffset, 4) - *foffset, foffset);
 
//dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
to
dataoff = offset = x_roundup(offset, ELF_EXEC_PAGESIZE);

////////////    
~#gedit /root/project_board/free_imx/myandroid/kernel_imx/mm/memory.c    
//err = copy_huge_pmd(dst_mm, src_mm, dst_pmd, src_pmd, addr, vma);
to
err = 0;

//else if (zap_huge_pmd(tlb, vma, pmd, addr))
to
else if (0)

//page = follow_trans_huge_pmd(vma, address, pmd, flags);
to
page = 0;

huge_pmd_set_accessed(mm, vma, address, pmd, orig_pmd, dirty);
to
//huge_pmd_set_accessed(mm, vma, address, pmd, orig_pmd, dirty);

//////////
~#gedit /root/project_board/free_imx/myandroid/kernel_imx/mm/mincore.c
//if (mincore_huge_pmd(vma, pmd, addr, next, vec))
to
if (0)

//////////
~#gedit /root/project_board/free_imx/myandroid/kernel_imx/mm/mprotect.c
//else if (change_huge_pmd(vma, pmd, addr, newprot, prot_numa))
to
else if (0)

//////////
~#gedit /root/project_board/free_imx/myandroid/kernel_imx/mm/mremap.c
err = move_huge_pmd(vma, new_vma, old_addr,  new_addr, old_end, old_pmd, new_pmd);
to
err = 0;

//////////
~#gedit /root/project_board/free_imx/myandroid/kernel_imx/mm/rmap.c
pmd = page_check_address_pmd(page, mm, address, PAGE_CHECK_ADDRESS_PMD_FLAG);
to
pmd = 0;

//////////
~#gedit /root/project_board/free_imx/myandroid/kernel_imx/mm/migrate.c
hugepage_add_anon_rmap(new, vma, addr);
to
0;
*************************************
******use -O0 need edit end
*************************************
////////Way 2. end

/////another way build -O0 file, use #pragma GCC/////
#pragma GCC push_options
#pragma GCC optimize ("O0")
 ~~your code section...
#pragma GCC pop_options

//avoid /Internal error: Oops - undefined instruction: 0 [#1] PREEMPT SMP ARM
//it's FPINST FPINST2 problem
gedit /root/project_board/free_imx/myandroid/kernel_imx/arch/arm/vfp/vfphw.S
/*#ifndef CONFIG_CPU_FEROCEON //mark this section
    tst    r1, #FPEXC_EX      
    beq    1f
    VFPFMXR    FPINST, r6        //Internal error happen here
    tst    r1, #FPEXC_FP2V      
    beq    1f
    VFPFMXR    FPINST2, r8      
1:
#endif*/

//avoid /Internal error: Oops - undefined instruction: 0 [#1] PREEMPT SMP ARM
gedit /root/project_board/free_imx/myandroid/kernel_imx/arch/arm/vfp/vfpmodule.c
/*#ifndef CONFIG_CPU_FEROCEON //mark this section
        trigger = fmrx(FPINST);
        regs->ARM_pc -= 4;
#endif*/
modify to
goto exit;

//////////close watchdog service
gedit /root/project_board/free_imx/myandroid/device/fsl/matrix_io/init.matrix_io.rc
on init
    #start watchdogd   -->mark here

#service watchdogd /sbin/watchdogd 10 20 5   -->mark here
#    class core
#    seclabel u:r:watchdogd:s0

build and upload->
/root/project_board/free_im/build matrix_io android
/root/project_board/free_im/autoflash matrix_io all

/////////no android service only console
//Freescale
gedit /root/project_board/free_imx/myandroid/device/fsl/matrix/etc/init.rc
//Ti
//gedit /root/project_board/ti_u/mydroid/system/core/rootdir/init.rc
keep ueventd and console two services, delete others services
service ueventd /sbin/ueventd    #keep
service console /system/bin/sh #keep

////ps: how to pass param to watchdogd
gedit /root/project_board/free_imx/myandroid/system/core/init/watchdogd.c
//open  device
#define DEV_NAME "/dev/watchdog"
fd = open(DEV_NAME, O_RDWR);
//then go to driver
//imx2_wdt_open(struct inode *inode, struct file *file) of imx2_wdt.c

//if meet error: do_inode_allocate_extents: Failed to allocate 4495 blocks
//add android system.img size
gedit /root/project_board/free_imx/myandroid/device/fsl/matrix_io/BoardConfig.mk
modify
BOARD_SYSTEMIMAGE_PARTITION_SIZE := 547225600
to
BOARD_SYSTEMIMAGE_PARTITION_SIZE := 734003200

/////bootargs
way 1. kgdb need start after serial, uart driver and enable polling char function
//use boot.img command line:
//console=ttymxc0,115200 kgdboc=ttymxc0,115200 init=/init video=mxcfb0:dev=ldb,bpp=32 video=mxcfb1:dev=hdmi,1920x1080M@60,if=RGB24,bpp=32 video=mxcfb2:off video=mxcfb3:off vmalloc=400M androidboot.console=ttymxc0 consoleblank=0 androidboot.hardware=freescale cma=384M mem=1G androidboot.serialno=0c0c81d4df647284
start target u-boot to new bootargs
Hit any key to stop autoboot:  0
=>setenv bootargs 'console=ttymxc0,115200 kgdboc=ttymxc0,115200 kgdbwait init=/init video=mxcfb0:dev=ldb,bpp=32 video=mxcfb1:dev=hdmi,1920x1080M@60,if=RGB24,bpp=32 video=mxcfb2:off video=mxcfb3:off vmalloc=400M androidboot.console=ttymxc0 consoleblank=0 androidboot.hardware=freescale cma=384M mem=1G androidboot.serialno=0c0c81d4df647284'
=>saveenv
=>boot

way 2. kgdb start after linux system on
gedit /root/project_board/free_imx/myandroid/device/fsl/matrix_io/matrix_io.cfg
export BOARD_KERNEL_CMDLINE="console=ttymxc0,115200 init=/init video=mxcfb0:dev=ldb,bpp=32 video=mxcfb1:dev=hdmi,1920x1080M@60,if=RGB24,bpp=32 video=mxcfb2:off video=mxcfb3:off vmalloc=400M androidboot.console=ttymxc0 consoleblank=0 androidboot.hardware=freescale cma=384M mem=1G"
//add kgdboc become
export BOARD_KERNEL_CMDLINE="console=ttymxc0,115200 kgdboc=ttymxc0,115200 init=/init video=mxcfb0:dev=ldb,bpp=32 video=mxcfb1:dev=hdmi,1920x1080M@60,if=RGB24,bpp=32 video=mxcfb2:off video=mxcfb3:off vmalloc=400M androidboot.console=ttymxc0 consoleblank=0 androidboot.hardware=freescale cma=384M mem=1G"
(*) If you are using the same serial line for both console and debug, now is the time to disconnect the terminal application (e.g. minicom).

///use agent-proxy instead of minicom (recommend)
git clone git://git.kernel.org/pub/scm/utils/kernel/kgdb/agent-proxy.git
cd agent-proxy
make
~#./agent-proxy 4440^4441 0 /dev/ttyUSB0,115200

//open new terminal
~#telnet localhost 4440    //now connect to target

3. for arm target command
echo g > /proc/sysrq-trigger

4. for arm-eabi-gdb lib
sudo add-apt-repository ppa:fkrull/deadsnakes
sudo apt-get update
sudo apt-get install python2.6 python2.6-dev

////find correct arm-eabi-gdb version
/root/project_board/free_imx/myandroid/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-gdb ./vmlinux
(gdb)target remote localhost:4441
or
(gdb)target remote /dev/ttyUSB0

//eclipse setting//////eclipse plugin
help -> install new software
Kepler - http://download.eclipse.org/releases/kepler
Mobile and Device Development ->  C/C++ GDB Hardware Debugging

right click project
Debug As -> Debug Configurations -> GDB Hardware Debugging
c/c++ application: /root/project_board/free_imx/out/matrix_io/kernel/vmlinux
click bottom line Select other... -> GDB(DSF) Hardware Debugging Launcher
check [disable auto build]

click Debugger tab
GDB Command: /root/project_board/free_imx/myandroid/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-gdb

~#./agent-proxy 4440^4441 0 /dev/ttyUSB0,115200
//open new terminal
~#telnet localhost 4440

Jtag device: Generic TCP/IP
Host name or ip address:localhost
port number:4441
or
Jtag device: Generic Serial
GDB connection string: /dev/ttyUSB0
uncheck [force thread list update on suspend]

click startup tab
enable load symbols
disable others options

for target console
~# echo g > /proc/sysrq-trigger
or
insert sysrq.h and handle_sysrq('g') in your C code

when running eclipse debug, close minocom

//look trace
eclipse console window -> GDB Hardware Debugging (gdb traces)
eclipse console window -> pin console

Demo:
https://picasaweb.google.com/106185541018774360364/AndroidPorting#6206175245984214658
https://picasaweb.google.com/106185541018774360364/AndroidPorting#6206672875075140178

沒有留言:

張貼留言