2013年9月25日 星期三

KGDB + Eclipse debug Kernel on i.mx6 Android

Ref:
1. Kgdb teaching
https://www.kernel.org/pub/linux/kernel/people/jwessel/kdb
2. Kgdb freescale
https://www.nxp.com/docs/en/application-note/AN4553.pdf
3. Agent-proxy
http://stackoverflow.com/questions/17329794/sysrq-g-wont-break-kernel
4. GCC param
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
5. SysRq key
https://www.kernel.org/doc/html/v4.11/admin-guide/sysrq.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, it uses two bytes XON (0x11), XOFF (0x13) in the data to do this flow control, and when this byte is to be sent, it will call this call back function, and these two must be immediately Sent, cannot be placed in 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 It can be implemented as a hardware circuit or a software timer, which can automatically restart the system when the system fails. Under the Linux kernel, the basic working principle of supervision is: when the watchdog is started (after the /dev/watchdog device is opened), if the /dev/watchdog is not executed within a certain set time interval Write operation, hardware watchdog circuit or software timer will restart the system.

disable
CONFIG_WATCHDOG=n

~~add
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_KERNEL=y
CONFIG_FTRACE=y
CONFIG_FUNCTION_TRACER=y
CONFIG_CONSOLE_POLL=y
CONFIG_MAGIC_SYSRQ=y  #make sure open it
CONFIG_KGDB=y
CONFIG_HAVE_ARCH_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 -fno-inline-functions-called-once -fno-omit-frame-pointer

//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 -fno-inline-functions-called-once -fno-omit-frame-pointer -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

1. KERNEL_CMDLINE parameter modify, select one way to do
way A:
kgdb need start after serial, uart driver and enable polling char function
//use boot.img command line: printenv or env print
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 to~~~
=>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
note: kgdbwait makes kgdb wait for a debugger connection during booting of a kernel

way B:
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).

way C:
find "#define CONFIG_BOOTARGS_COMMON" in ~/u-boot/include/configs
#define CONFIG_BOOTARGS_COMMON "earlyprintk console=ttymxc0,115200 rootwait nprofile_irq_duration=on "
~~~modify to
#define CONFIG_BOOTARGS_COMMON "earlyprintk console=ttymxc0,115200 kgdboc=ttymxc0,115200 rootwait nprofile_irq_duration=on "

way D:
~~~modify mx6dq_matrix_android_defconfig and rebuild
gedit /root/project_board/free_imx/myandroid/kernel_imx/arch/arm/configs/mx6dq_matrix_android_defconfig
CONFIG_CMDLINE="kgdboc=ttyS0,115200"
CONFIG_CMDLINE_EXTEND=y

2.
///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. registe kgdboc for sysrq
echo ttymxc0 > /sys/module/kgdboc/parameters/kgdboc
~~~KGDB: Registered I/O driver kgdboc

4. trigger sysrq break
echo g > /proc/sysrq-trigger

/////////////////using eclipse/////////////////
1. 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
2.
/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

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

4. 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]

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

6. 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]

7.
~~~open first terminal
./agent-proxy 4440^4441 0 /dev/ttyUSB0,115200
~~~open second terminal
telnet localhost 4440

8.
click startup tab
enable load symbols
disable others options

9. registe kgdboc for sysrq
echo ttymxc0 > /sys/module/kgdboc/parameters/kgdboc
~~~KGDB: Registered I/O driver kgdboc

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

ps: when running eclipse debug, close minocom

11. watch trace
eclipse console window -> GDB Hardware Debugging (gdb traces)
eclipse console window -> pin console

/////////////////////////kgdboe cross compile/////////////////////////
refer to: https://sysprogs.com/VisualKernel/kgdboe/tutorial
1.
~~~rebuild kernel with
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_KERNEL=y
CONFIG_FTRACE=y
CONFIG_FUNCTION_TRACER=y
CONFIG_KGDB=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_NETCONSOLE=y

2.
git clone --recursive https://github.com/sysprogs/kgdboe.git

3.
cd kgdboe
export PATH=$PATH:/opt/ivot/arm-ca9-linux-gnueabihf-6.5/bin
export LD_LIBRARY_PATH=/opt/ivot/arm-ca9-linux-gnueabihf-6.5/lib
make ARCH=arm CC=arm-ca9-linux-gnueabihf-gcc LD=arm-ca9-linux-gnueabihf-ld V=1 -j$CPU_NUM -C /root/nt9852x/nor/na51055_sdk_nor/BSP/linux-kernel/_install_modules/lib/modules/4.19.91/build M=$(pwd)

4.
~~~copy to target and run, default port 31337 in kgdboe_main.c
insmod kgdboe.ko

download:
https://www.mediafire.com/file/5fch9pbfnv1xm6a/nt98528_kgdboe.sh
https://www.mediafire.com/file/i5k9zejlb043knu/devicehello.tar.xz

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

1 則留言:

  1. in Makefile when use -O1 -O2 -O3
    KBUILD_CFLAGS += -O1 -g -fno-inline-functions-called-once -fno-omit-frame-pointer -U__OPTIMIZE__
    can make step trace sequence correctly

    回覆刪除