linux vim linux-kernel

Configuración de Vim para el desarrollo del kernel de Linux



linux-kernel (1)

Las principales diferencias entre el kernel de Linux y el proyecto C regular (desde el punto de vista del desarrollador) son las siguientes:

  • El kernel es un proyecto muy grande (por lo que debe elegir qué código indexar)
  • tiene un código dependiente de la arquitectura (y solo está interesado en una arquitectura específica a la vez; otras arquitecturas no deben estar indexadas)
  • tiene un estilo de codificación muy específico al que debe atenerse (y vim debe configurarse para mostrar el código en consecuencia)
  • no utiliza la biblioteca estándar de C, sino que tiene sus propias rutinas similares (por lo que su herramienta de índice no debe indexar los encabezados de libc)

Instalando herramientas de indexación

Para navegar por el código del kernel recomendaría herramientas de cscope y ctags . Para instalarlos ejecute el siguiente comando:

$ sudo aptitude install cscope exuberant-ctags

Una pequeña explicación:

  • cscope : se utilizará para navegar por el código (cambiar entre funciones, etc.)
  • ctags : es necesario para el complemento Tagbar (se Tagbar más adelante) y para la Omni completion (mecanismo de finalización automática en vim); También se puede utilizar para la navegación.

Creación de base de datos de índice

Ahora deberías indexar los archivos fuente de tu kernel. Aquí hay 2 enfoques: crear índice manualmente o usar el script disponible en el kernel. Si no está seguro de cuál es la mejor manera para usted, le recomiendo ir con el script del kernel, ya que hace muchos trucos ingeniosos detrás de la escena (como ignorar las fuentes no construidas y mover los archivos de encabezado sobre la lista de resultados).

Pero antes que nada, configure y genere el kernel para su arquitectura / placa, ya que los archivos creados se pueden usar más adelante para mejorar el proceso de indexación.

Indexación con scripts/tags.sh

Kernel tiene una secuencia de scripts/tags.sh bastante buena ( scripts/tags.sh ) para crear la base de datos de índices del kernel. Uno debe usar make cscope y make tags para crear un índice, en lugar de ejecutar ese script directamente.

Ejemplo:

$ make O=. ARCH=arm SUBARCH=omap2 COMPILED_SOURCE=1 cscope tags

dónde

  • O=. - use rutas absolutas (útil si desea cargar archivos de índice de cscope / ctags creados fuera del directorio del kernel, por ejemplo, para el desarrollo de módulos de kernel fuera del árbol). Si desea usar rutas relativas (es decir, solo va a realizar el desarrollo en el directorio del kernel), simplemente omita ese parámetro
  • ARCH=... - selecciona la arquitectura de la CPU para ser indexada. Ver directorios en arch/ para referencia. Por ejemplo, si ARCH=arm , el directorio arch/arm/ se indexará, el resto de los directorios arch/* se ignorarán
  • SUBARCH=... - seleccione la sub-arquitectura (es decir, los archivos relacionados con el tablero) para ser indexados. Por ejemplo, si SUBARCH=omap2 , solo se SUBARCH=omap2 arch/arm/mach-omap2/ y arch/arm/plat-omap/ , el resto de máquinas y plataformas se ignorarán.
  • COMPILED_SOURCE=1 - indexar solo archivos compilados. Por lo general, solo está interesado en los archivos de origen utilizados en su compilación (por lo tanto, compilados). Si desea indexar también los archivos que no se crearon, simplemente omita esta opción.
  • cscope - regla para hacer el índice de cscope
  • tags - regla para hacer ctags index

Indexación manual

Es posible que la secuencia de comandos del kernel ( tags.sh ) no funcione correctamente o que desee tener más control sobre el proceso de indexación. En esos casos, debe indexar las fuentes del kernel manualmente.

Las reflexiones sobre la indexación manual se tomaron de here .

Primero debe crear el archivo cscope.files que cscope.files todos los archivos que desea indexar. Por ejemplo, estoy usando los siguientes comandos para enumerar archivos para la arquitectura ARM ( arch/arm ), y particularmente para la plataforma OMAP (excluyendo el resto de plataformas para facilitar la navegación):

find $dir / -path "$dir/arch*" -prune -o / -path "$dir/tmp*" -prune -o / -path "$dir/Documentation*" -prune -o / -path "$dir/scripts*" -prune -o / -path "$dir/tools*" -prune -o / -path "$dir/include/config*" -prune -o / -path "$dir/usr/include*" -prune -o / -type f / -not -name ''*.mod.c'' / -name "*.[chsS]" -print > cscope.files find $dir/arch/arm / -path "$dir/arch/arm/mach-*" -prune -o / -path "$dir/arch/arm/plat-*" -prune -o / -path "$dir/arch/arm/configs" -prune -o / -path "$dir/arch/arm/kvm" -prune -o / -path "$dir/arch/arm/xen" -prune -o / -type f / -not -name ''*.mod.c'' / -name "*.[chsS]" -print >> cscope.files find $dir/arch/arm/mach-omap2/ / $dir/arch/arm/plat-omap/ / -type f / -not -name ''*.mod.c'' / -name "*.[chsS]" -print >> cscope.files

Para la arquitectura x86 ( arch/x86 ) puedes usar algo como esto:

find $dir / -path "$dir/arch*" -prune -o / -path "$dir/tmp*" -prune -o / -path "$dir/Documentation*" -prune -o / -path "$dir/scripts*" -prune -o / -path "$dir/tools*" -prune -o / -path "$dir/include/config*" -prune -o / -path "$dir/usr/include*" -prune -o / -type f / -not -name ''*.mod.c'' / -name "*.[chsS]" -print > cscope.files find $dir/arch/x86 / -path "$dir/arch/x86/configs" -prune -o / -path "$dir/arch/x86/kvm" -prune -o / -path "$dir/arch/x86/lguest" -prune -o / -path "$dir/arch/x86/xen" -prune -o / -type f / -not -name ''*.mod.c'' / -name "*.[chsS]" -print >> cscope.files

Donde dir variable puede tener uno de los siguientes valores:

  • . : si va a trabajar solo en el directorio de código fuente del kernel; en este caso, esos comandos deben ejecutarse desde el directorio raíz del código fuente del kernel
  • ruta absoluta al directorio de código fuente de su kernel : si va a desarrollar algún módulo de kernel fuera de árbol; En este caso, el script puede ejecutarse desde cualquier lugar.

Estoy usando la primera opción ( dir=. ), Porque no estoy desarrollando ningún módulo fuera de árbol.

Ahora, cuando el archivo cscope.files está listo, necesitamos ejecutar la indexación real:

$ cscope -b -q -k

Donde el parámetro -k le dice a cscope que no indexe la biblioteca estándar de C (ya que el kernel no la usa).

Ahora es el momento de crear la ctags de datos del índice ctags . Para acelerar esta etapa, vamos a reutilizar el ya creado cscope.files :

$ ctags -L cscope.files

De acuerdo, las bases de datos de índice de cscope y ctags están creadas, y puede eliminar el archivo cscope.files , ya que no lo necesitamos más:

$ rm -f cscope.files

Los siguientes archivos contienen bases de datos de índice (para cscope y ctags ):

- cscope.in.out - cscope.out - cscope.po.out - tags

Manténgalos en la raíz del directorio de fuentes del kernel.

plugins vim

NOTA : Además, muestro cómo usar el agente patógeno para manejar los complementos Vim. Pero ahora que se lanzó Vim 8, se puede usar la carga de paquetes nativos para el mismo propósito.

A continuación vamos a instalar algunos complementos para vim. Para comprenderlo mejor, te animo a que uses el complemento de patógenos . Le permite simplemente git clone complementos de vim a su ~/.vim/bundle/ y mantenerlos aislados, en lugar de mezclar archivos de diferentes complementos en el directorio ~/.vim .

Instale el patógeno como se describe here .

No te olvides de hacer las siguientes cosas (como se describe en el mismo enlace):

Agrega esto a tu vimrc :

execute pathogen#infect()

Si eres nuevo en Vim y te falta vimrc , vim ~/.vimrc y pega el siguiente ejemplo súper mínimo:

execute pathogen#infect() syntax on filetype plugin indent on

Instalando mapas cscope para vim

Vim ya tiene soporte para cscope (ver :help cscope ). Puedes saltar a un símbolo o archivo usando comandos como :cs fg kfree . Aunque no es tan conveniente. Para acelerar las cosas, puede utilizar los accesos directos en su lugar (para que pueda poner el cursor en alguna función, presionar una combinación de teclas y saltar a la función). Para agregar accesos directos a cscope, debe obtener el archivo cscope_maps.vim .

Para instalarlo usando un patógeno , simplemente puede clonar this repositorio a su ~/.vim/bundle :

$ git clone https://github.com/joe-skb7/cscope-maps.git ~/.vim/bundle/cscope-maps

Ahora deberías poder navegar entre funciones y archivos en vim usando atajos. Abra algún archivo fuente del kernel, ponga el cursor del teclado en alguna llamada de función y presione Ctrl + / seguido de g . Debería llevarte a la implementación de la función. O puede mostrarle todas las implementaciones de funciones disponibles, luego puede elegir cuál usar: .

Para el resto de asignaciones de claves, consulte el archivo cscope_maps.vim .

También puedes usar comandos en vim como:

:cs f g kmalloc

Ver :help cscope para más detalles.

nota de ctags

ctags aún puede ser útil para la navegación, por ejemplo cuando se busca alguna declaración #define . Puede poner el cursor en este uso de definición y presionar g seguido de Ctrl + ] . Vea esta respuesta para más detalles.

nota cscope

El siguiente truco se puede usar para encontrar la declaración de estructura en el kernel:

:cs f t struct device {

Tenga en cuenta que el comando anterior se basa en el estilo específico de declaración de estructura (utilizado en el kernel), por lo que sabemos que la declaración de estructura siempre tiene esta forma: struct some_stuct { . Este truco podría no funcionar en proyectos con otro estilo de codificación.

nota de desarrollo de módulos fuera de árbol

Si está desarrollando un módulo fuera de árbol, probablemente deba cargar las bases de datos cscope y ctags desde el directorio del kernel. Se puede hacer con los siguientes comandos en vim (en modo de comando).

Cargar la base de datos cscope externa:

:cs add /path/to/your/kernel/cscope.out

Cargar base de datos ctags externa:

:set tags=/path/to/your/kernel/tags

vimrc

~/.vimrc deben hacer algunas modificaciones a su ~/.vimrc , para apoyar mejor el desarrollo del kernel.

En primer lugar, resalte la columna 81 con una línea vertical (ya que la codificación del kernel requiere que mantenga la longitud de sus líneas a un máximo de 80 caracteres):

" 80 characters line set colorcolumn=81 "execute "set colorcolumn=" . join(range(81,335), '','') highlight ColorColumn ctermbg=Black ctermfg=DarkRed

Anule el comentario de la segunda línea si también desea resaltar más de 80 columnas.

Los espacios finales están prohibidos por el estilo de codificación del kernel, por lo que es posible que desee resaltarlos:

" Highlight trailing spaces " http://vim.wikia.com/wiki/Highlight_unwanted_spaces highlight ExtraWhitespace ctermbg=red guibg=red match ExtraWhitespace //s/+$/ autocmd BufWinEnter * match ExtraWhitespace //s/+$/ autocmd InsertEnter * match ExtraWhitespace //s/+/%#/@<!$/ autocmd InsertLeave * match ExtraWhitespace //s/+$/ autocmd BufWinLeave * call clearmatches()

Estilo de codificación del kernel

Para que vim respete el estilo de codificación del kernel, puede utilizar el complemento listo para usar: vim-linux-coding-style .

Complementos útiles

Los complementos siguientes se usan comúnmente, por lo que también puede encontrarlos útiles:

También se trata de complementos interesantes, pero es posible que deba configurarlos para el kernel:

Omni finalización

Vim 7 (y superior) ya tiene incorporado el soporte de finalización automática. Se llama Omni completion . Ver : ayuda a la nueva omisión de terminación para más detalles.

La finalización de Omni funciona bastante lento en un proyecto tan grande como el kernel. Si aún lo desea, puede habilitarlo agregando las siguientes líneas a su ~/.vimrc :

" Enable OmniCompletion " http://vim.wikia.com/wiki/Omni_completion filetype plugin on set omnifunc=syntaxcomplete#Complete " Configure menu behavior " http://vim.wikia.com/wiki/VimTip1386 set completeopt=longest,menuone inoremap <expr> <CR> pumvisible() ? "/<C-y>" : "/<C-g>u/<CR>" inoremap <expr> <C-n> pumvisible() ? ''<C-n>'' : / ''<C-n><C-r>=pumvisible() ? "/<lt>Down>" : ""<CR>'' inoremap <expr> <M-,> pumvisible() ? ''<C-n>'' : / ''<C-x><C-o><C-n><C-p><C-r>=pumvisible() ? "/<lt>Down>" : ""<CR>'' " Use Ctrl+Space for omni-completion " https://stackoverflow.com/questions/510503/ctrlspace-for-omni-and-keyword-completion-in-vim inoremap <expr> <C-Space> pumvisible() /|/| &omnifunc == '''' ? / "/<lt>C-n>" : / "/<lt>C-x>/<lt>C-o><c-r>=pumvisible() ?" . / "/"//<lt>c-n>//<lt>c-p>//<lt>c-n>/" :" . / "/" //<lt>bs>//<lt>C-n>/"/<CR>" imap <C-@> <C-Space> " Popup menu hightLight Group highlight Pmenu ctermbg=13 guibg=LightGray highlight PmenuSel ctermbg=7 guibg=DarkBlue guifg=White highlight PmenuSbar ctermbg=7 guibg=DarkGray highlight PmenuThumb guibg=Black " Enable global scope search let OmniCpp_GlobalScopeSearch = 1 " Show function parameters let OmniCpp_ShowPrototypeInAbbr = 1 " Show access information in pop-up menu let OmniCpp_ShowAccess = 1 " Auto complete after ''.'' let OmniCpp_MayCompleteDot = 1 " Auto complete after ''->'' let OmniCpp_MayCompleteArrow = 1 " Auto complete after ''::'' let OmniCpp_MayCompleteScope = 0 " Don''t select first item in pop-up menu let OmniCpp_SelectFirstItem = 0

Y usa Ctrl + Espacio para completar automáticamente.

Apariencia de ojos dulces

256 colores

En primer lugar, debe asegurarse de que su terminal admita 256 colores. Por ejemplo, se puede lograr utilizando el terminal urxvt-256 . Para gnome-terminal , simplemente puede agregar la siguiente línea a su ~/.bashrc :

export TERM="xterm-256color"

Una vez hecho esto, coloque la siguiente línea en su ~/.vimrc :

set t_Co=256

Esquema de colores

Ahora descargue los esquemas que prefiera ~/.vim/colors y selecciónelos en ~/.vimrc :

set background=dark colorscheme hybrid

Qué combinación de colores usar es una materia fuertemente basada en la opinión. Puedo recomendar mrkn256 , hybrid y solarized para empezar.

Fuente

Hay muchas buenas fuentes para programar por ahí. Muchos programadores en Linux usan la fuente Terminus , puedes probarla para empezar.

Deficiencias conocidas

Algunas características todavía faltan en vim.

  1. cscope / ctags no puede usar las definiciones de include/generated/autoconf.h e ignorar el código que no fue creado. Todavía puede ser útil tener todo el código indexado para usarlo como referencia cuando se codifica.
  2. No hay expansión de macros (bueno, hay alguna function ahí fuera (basada en gcc -E ), pero no estoy seguro de si funcionará para el núcleo).

El único IDE que conozco para manejar esos problemas es Eclipse con CDT .

El desarrollo del kernel es realmente diferente del desarrollo de un proyecto de C tradicional (desde mi punto de vista, como novato). Por lo tanto, siempre me pregunto cuál es la configuración vim de un hacker del kernel.

Lo más importante es que la forma de navegar por el árbol fuente del kernel en vim .. Intenté ctags , sin embargo, funciona terriblemente.

¿Alguien me puede dar una pista?