Update forked repo with remote repo

Add remote repository

# cd <forked-repo>
# git checkout 
# git remote add upstream <remote-repo-git-link>
#git fetch upstream

Updating fork from remote repo

# git pull upstream 

Example (This is what I did to sync from remote branch and push to forked repo)

# cd <forked-repo>
# git checkout
# git remote add upstream <remote-repo-git-link>
# git fetch upstream
# git pull upstream --rebase

As local repo changes are rebased, faced error while pushing changes to forked repo. Runt these commands to rebase changes for forked branch.

# git pull --rebase
# git push origin <forked-branch>

 

GCC –gc-sections to remove unused code and data

Sometimes it is required to reduce code size. Code size may be higher due to unused functions and data which are declared but not used. Sometimes it is not easier/possible to modify code and remove that.

There are GCC options which can help here:

  1. -ffunction-sections
  2. -fdata-sections
  3. –gc-sections
  4. –print-gc-sections

First two flags are passed at compilation stage. These flags tells compiler to create separate sections for each functions and data. Third flag is passed to linker which checks each section and remove sections which are not used.

-ffunction-sections

By default every functions are combined into single .text function but when we use “-ffunction-sections” flag, compiler creates different text section for each function (e.g. .text.func1, .text.func2, etc)

-fdata-sections

By default variables belongs .data are combined into single .data function but when we use “-fdata-sections” flag, compiler creates different .data section for each data (e.g. .data.var1, .data.var2, etc)

–gc-sections

This tells linker to remove unused sections.

–print-gc-sections

This flag is useful for debugging and identifying removed sections. This prints sections which are removed.

Example:

Consider below C example:

#include

int globalval = 5;

int main()
{
printf (“Hello World!\n”);
return 0;
}

int func(void)
{
printf(“I am function\n”);
return 0;
}

Case 1: Without GCC flags

When we compile program without above flags, compiler includes all functions and data even if those are not used.

~$ gcc -c test.c -o test.o
~$ gcc -o test.bin test.o

Size of program:

~$ size test.bin
   text   data    bss    dec    hex filename
   1253    556      4   1813    715 test.bin

obj-dump snippet

~$ objdump -x test.o
 - - - - - -
SYMBOL TABLE:
0000000000000000 l    df *ABS*	0000000000000000 test.c
0000000000000000 l    d  .text	0000000000000000 .text
0000000000000000 l    d  .data	0000000000000000 .data
0000000000000000 l    d  .bss	0000000000000000 .bss
0000000000000000 l    d  .rodata	0000000000000000 .rodata
0000000000000000 l    d  .note.GNU-stack	0000000000000000 .note.GNU-stack
0000000000000000 l    d  .eh_frame	0000000000000000 .eh_frame
0000000000000000 l    d  .comment	0000000000000000 .comment
0000000000000000 g     O .data	0000000000000004 globalval
0000000000000000 g     F .text	0000000000000015 main
0000000000000000         *UND*	0000000000000000 puts
0000000000000015 g     F .text	0000000000000015 func
 - - - - - -

Case 2: With GCC flags

When we compile program with -ffunction-sections and -fdata-sections flags, compiler creates separate sections for each function and data. When we provide –gc-sections flag while linking, linker removes all unused sections.

~$ gcc -fdata-sections -ffunction-sections -c test.c -o test.o
~$ gcc -Wl,--gc-sections -Wl,--print-gc-sections -o test.bin test.o
/usr/bin/ld: Removing unused section '.rodata.cst4' in file '/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o'
/usr/bin/ld: Removing unused section '.data' in file '/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o'
/usr/bin/ld: Removing unused section '.data' in file '/usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o'
/usr/bin/ld: Removing unused section '.data.globalval' in file 'section.o'
/usr/bin/ld: Removing unused section '.text.func' in file 'section.o'

Size of program:

~$ size test.bin
   text   data    bss    dec    hex filename
   1193    536      8   1737    6c9 test.bin

obj-dump snippet

~$ objdump -x test.o
 - - - - - -
SYMBOL TABLE:
0000000000000000 l    df *ABS*	0000000000000000 test.c
0000000000000000 l    d  .text	0000000000000000 .text
0000000000000000 l    d  .data	0000000000000000 .data
0000000000000000 l    d  .bss	0000000000000000 .bss
0000000000000000 l    d  .data.globalval	0000000000000000 .data.globalval
0000000000000000 l    d  .rodata	0000000000000000 .rodata
0000000000000000 l    d  .text.main	0000000000000000 .text.main
0000000000000000 l    d  .text.func	0000000000000000 .text.func
0000000000000000 l    d  .note.GNU-stack	0000000000000000 .note.GNU-stack
0000000000000000 l    d  .eh_frame	0000000000000000 .eh_frame
0000000000000000 l    d  .comment	0000000000000000 .comment
0000000000000000 g     O .data.globalval	0000000000000004 globalval
0000000000000000 g     F .text.main	0000000000000015 main
0000000000000000         *UND*	0000000000000000 puts
0000000000000000 g     F .text.func	0000000000000015 func
 - - - - - -

Conclusion

As it can be seen from example, that in second case, different sections for each functions (.text.main and .text.func) and data (.data.globalval) are created. While linking, these are removed ,as they are not used.

Device Tree Debugging

DTB-DTS conversion (Linux kernel)

  • Convert DTS file to DTB
  • ./scripts/dtc/dtc -I dts -O dtb -o .dtb .dts
  • Convert DTB file to DTS

  • ./scripts/dtc/dtc -I dtb -O dts -o .dts .dtb

 U-boot FDT commands

  • print fdt address
  • print $fdt_addr_r (or $fdt_addr)
  • Set FDT node property
  • fdt addr $fdt_addr
    fdt set /testnode testprop testvalue
  • remove FDT node property
  • fdt addr $fdt_addr
    fdt rm /testnode testprop
  • Remove DT node
  • fdt rm /testnode
  • List FDT nodes
  • fdt list                         /* All nodes */
    fdt list /cpus                   /* All nodes under cups node */
  • Create node
  • fdt mknode / testnode

References:

Cross compiling and Linking

  • Compilation
    arm-uclinuxeabi-gcc  -g  -Os   -g2 -mthumb -mcpu=cortex-m3 -fsigned-char -O2 -fno-builtin-puts -fno-common -ffixed-r8 -D__KERNEL__ -I -fno-builtin -ffreestanding -isystem  -pipe  -DCONFIG_ARM -D__ARM__ -D<MACRO="(VALUE)"> -Wall -Wstrict-prototypes -fno-stack-protector   -o   -c
    
  • De-assemble
    arm-uclinuxeabi-objdump -S <O_FILE>
    
  • Library
    arm-uclinuxeabi-ar crv <A_FILENAME> <O_FILES> 
    
  • Linking
    arm-uclinuxeabi-ld -Bstatic -T<LDS_FILENAME> -u<UNDEFINED_SYMBOLS> <O_FILES> <A_FILES> -lgcc -Map <MAP_FILE> -o <OUT_FILENAME>
    

    Example linker script:

    OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
    OUTPUT_ARCH(arm)
    ENTRY(main)
    
    MEMORY
    {
     /* SmartFusion internal eSRAM */
     ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k
    }
    
    SECTIONS
    {
     .text :
     {
       . = ALIGN(4);
        *(.text*)
    	. = ALIGN(4);
        _etext = .;
     } >ram
    }
    end = .;
  • Other format output
    arm-none-eabi-objcopy --gap-fill=0xff -O ihex myprog  "myprog.hex"
    arm-none-eabi-objcopy --gap-fill=0xff -O binary myprog  "myprog.bin"
    arm-none-eabi-objcopy -O srec myprog "myprog.srec"
    arm-none-eabi-objdump -h -S myprog > "myprog.lst"

Linux Kernel – Tools/Scripts

Here are few tools/scripts which are useful for static analysis of code:

  • Checkpatch
    # ./script/checkpath.pl <patch_file(s)>
    # ./script/checkpatch.pl --file <file_name(s)>
    
  • kmemleak
    Check kernel memory leak using kmemleak:

    # cppcheck <source-dir>

    Kmemleak usage

  • Coccicheck
    • make coccicheck MODE=<mode>

    Where,

    ‘patch’ proposes a fix, when possible.

    ‘report’ generates a list in the following format: file:line:column-column: message

    ‘context’ highlights lines of interest and their context in a diff-like style.Lines of interest are indicated with ‘-‘

    ‘org’ generates a report in the Org mode format of Emacs.

    • To apply Coccinelle to a specific directory, M= can be used.
      For example, to check drivers/net/wireless/ one may write:
    make coccicheck M=drivers/net/wireless/
    • To apply Coccinelle on a file basis, instead of a directory basis, the
      following command may be used:

      make C=1 CHECK="scripts/coccicheck"
    • To check only newly edited code, use the value 2 for the C flag, i.e.
      make C=2 CHECK="scripts/coccicheck"
  • kselftest
    • Run kselftest install tool in tools/testing/selftests
       # cd tools/testing/selftests
       # ./kselftest_install.sh [ install_location ]
    • Default install tool: in tools/testing/selftests
    • Specify install location:
    # ./kselftest_install.sh /tmp
    • Kselftest install creates run_kselftest.sh
    • Run tests:
# cd install_dir
# ./run_kselftest.sh

The C++ compilation process

Copied from: http://faculty.cs.niu.edu/~mcmahon/CS241/Notes/compile.html

The C++ compilation process

C++ compilation process

Compiling a source code file in C++ is a four-step process. For example, if you have a C++ source code file named prog1.cpp and you execute the compile command

   g++ -Wall -ansi -o prog1 prog1.cpp

the compilation process looks like this:

  1. The C++ preprocessor copies the contents of the included header files into the source code file, generates macro code, and replaces symbolic constants defined using #define with their values.
  2. The expanded source code file produced by the C++ preprocessor is compiled into the assembly language for the platform.
  3. The assembler code generated by the compiler is assembled into the object code for the platform.
  4. The object code file generated by the assembler is linked together with the object code files for any library functions used to produce an executable file.

By using appropriate compiler options, we can stop this process at any stage.

  1. To stop the process after the preprocessor step, you can use the -E option:
       g++ -E prog1.cpp
    

    The expanded source code file will be printed on standard output (the screen by default); you can redirect the output to a file if you wish. Note that the expanded source code file is often incredibly large – a 20 line source code file can easily produce an expanded file of 20,000 lines or more, depending on which header files were included.

  2. To stop the process after the compile step, you can use the -S option:
       g++ -Wall -ansi -S prog1.cpp
    

    By default, the assembler code for a source file named filename.cpp will be placed in a file namedfilename.s.

  3. To stop the process after the assembly step, you can use the -c option:
       g++ -Wall -ansi -c prog1.cpp
    

    By default, the assembler code for a source file named filename.cpp will be placed in a file namedfilename.o.