Forum Linux.embarqué Kernel oops lors de init (busybox) sur powerquicc

Posté par  .
Étiquettes : aucune
0
29
nov.
2007
Bonjour,
Je suis en train d'essayer de passer une carte à base de powerquicc 1 (mpc855T) sous linux embarqué. J'utilise la chaine de compilation eldk 4.1 et un noyau 2.6.19. Cependant étant débutant en débugage coté noyau, je poste ici pour essayer d'avoir un avis voir une piste de solution pour mon kernel oops.
Ma noyau utilise le cpm uart du powerquicc en tant que sortie série. Mon noyau boot correctement (je pense) jusqu'a l'init du côté utilisateur. J'utilise un initramfs basé sur busybox 1.8 compilé en static (pour évité les problèmes d'abord).
Comme conseillé avant d'utiliser la busybox en tant que programme init, j'ai testé avec un simple hello world que le noyau était capable de lancer un prog utilisateur. Cela à fonctionné correctement.

Log de démarage avec le hello world init :

> Serial: CPM driver $Revision: 0.02 $
> cpm_uart: WARNING: no UART devices found on platform bus!
> cpm_uart: the driver will guess configuration, but this mode is no
> longer supported.
> ttyCPM0 at MMIO 0xff000a80 (irq = 20) is a CPM UART
> RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
> loop: loaded (max 8 devices)
> TCP cubic registered
> Freeing unused kernel memory: 512k init
> execute init process
> Hello world test bonjour salut


Après ça j'ai compilé busybox avec allnoconfig pour commencé, activé la compile en statique dans la conf, activé l'option init, ash, et quelque commandes (le minimum). Mon initramfs est tel que :


[fabien@localhost initramfs_external]$ ls -al ./*
lrwxrwxrwx 1 root root 11 nov 28 13:15 ./init -> bin/busybox*

./bin:
total 168
drwxr-xr-x 2 root root 4096 nov 28 14:02 ./
drwxr-xr-x 10 fabien fabien 4096 nov 28 14:02 ../
lrwxrwxrwx 1 root root 7 nov 28 14:02 ash -> busybox*
-rwxr-xr-x 1 root root 159264 nov 28 14:02 busybox*
lrwxrwxrwx 1 root root 7 nov 28 14:02 cat -> busybox*
lrwxrwxrwx 1 root root 7 nov 28 14:02 cp -> busybox*
lrwxrwxrwx 1 root root 7 nov 28 14:02 df -> busybox*
lrwxrwxrwx 1 root root 7 nov 28 14:02 echo -> busybox*
lrwxrwxrwx 1 root root 7 nov 28 14:02 ln -> busybox*
lrwxrwxrwx 1 root root 7 nov 28 14:02 ls -> busybox*
lrwxrwxrwx 1 root root 7 nov 28 14:02 mv -> busybox*
lrwxrwxrwx 1 root root 7 nov 28 14:02 rm -> busybox*
lrwxrwxrwx 1 root root 7 nov 28 14:02 sh -> busybox*
lrwxrwxrwx 1 root root 7 nov 28 14:02 uname -> busybox*

./dev:
total 8
drwxr-xr-x 2 root root 4096 nov 28 10:25 ./
drwxr-xr-x 10 fabien fabien 4096 nov 28 14:02 ../
crw-r--r-- 1 root root 5, 1 nov 22 13:32 console
crw-rw-rw- 1 root root 1, 3 nov 26 10:10 null

./etc:
total 8
drwxr-xr-x 2 root root 4096 nov 26 10:09 ./
drwxr-xr-x 10 fabien fabien 4096 nov 28 14:02 ../

./proc:
total 8
drwxr-xr-x 2 root root 4096 nov 26 10:09 ./
drwxr-xr-x 10 fabien fabien 4096 nov 28 14:02 ../

./sbin:
total 8
drwxr-xr-x 2 root root 4096 nov 28 14:02 ./
drwxr-xr-x 10 fabien fabien 4096 nov 28 14:02 ../
lrwxrwxrwx 1 root root 14 nov 28 14:02 init -> ../bin/busybox*

./sys:
total 8
drwxr-xr-x 2 root root 4096 nov 26 10:09 ./
drwxr-xr-x 10 fabien fabien 4096 nov 28 14:02 ../

./temp:
total 8
drwxr-xr-x 2 root root 4096 nov 26 10:09 ./
drwxr-xr-x 10 fabien fabien 4096 nov 28 14:02 ../

./usr:
total 12
drwxr-xr-x 3 root root 4096 nov 28 14:02 ./
drwxr-xr-x 10 fabien fabien 4096 nov 28 14:02 ../
drwxr-xr-x 2 root root 4096 nov 28 14:02 bin/


Avec busybox au lancement du noyau il y a un oops et même un double oops.


<5>Linux version 2.6.19.2 (fabien@localhost) (gcc version 4.0.0 (DENX ELDK 4.1 4.0.0)) #21 Wed Nov 28 14:03:48 CET 2007
<4>Board_init : fast 2100
<7>Entering add_active_range(0, 0, 4096) 0 entries of 256 used
<4>Zone PFN ranges:
<4> DMA 0 -> 4096
<4> Normal 4096 -> 4096
<4>early_node_map[1] active PFN ranges
<4> 0: 0 -> 4096
<7>On node 0 totalpages: 4096
<7> DMA zone: 32 pages used for memmap
<7> DMA zone: 0 pages reserved
<7> DMA zone: 4064 pages, LIFO batch:0
<7> Normal zone: 0 pages used for memmap
<4>Built 1 zonelists. Total pages: 4064
<5>Kernel command line: console=ttyCPM0,9600
<4>PID hash table entries: 64 (order: 6, 256 bytes)
<4>Decrementer Frequency = 187500000/60
<6>cpm_uart: console: compat mode
<7>CPM uart[0]:initbd
<7>CPM uart[0]:init_smc
<7>CPM uart[0]:set_termios
<4>Dentry cache hash table entries: 2048 (order: 1, 8192 bytes)
<4>Inode-cache hash table entries: 1024 (order: 0, 4096 bytes)
<4>Memory: 15080k available (776k kernel code, 220k data, 144k init, 0k highmem)
<7>Calibrating delay loop... 49.15 BogoMIPS (lpj=98304)
<4>Mount-cache hash table entries: 512
<5>Platform fast2100: Init
<6>io scheduler noop registered
<6>io scheduler anticipatory registered
<6>io scheduler deadline registered
<6>io scheduler cfq registered (default)
<6>Serial: CPM driver $Revision: 0.02 $
<6>cpm_uart: WARNING: no UART devices found on platform bus!
<6>cpm_uart: the driver will guess configuration, but this mode is no longer supported.
<7>CPM uart[0]:config_port
<7>CPM uart[0]:request port
<7>CPM uart[0]:uart_type
<6>ttyCPM0 at MMIO 0xff000a80 (irq = 20) is a CPM UART
<6>loop: loaded (max 8 devices)
<4>Freeing unused kernel memory: 144k init
<7>CPM uart[0]:startup
<7>CPM uart[0]:set_termios
<4>execute init process
<7>CPM uart[0]:start tx
<4>Oops: kernel access of bad area, sig: 11 [#1]
<4>Oops: kernel access of bad area, sig: 11 [#2]
<4>NIP: C00B4B00 LR: C00118E0 CTR: 00000000
<4>REGS: c0161ac0 TRAP: 0300 Not tainted (2.6.19.2)
<4>MSR: 00001032 <ME,IR,DR> CR: 55005095 XER: A000FF7F
<4>DAR: 3F000000, DSISR: C0000000
<4>TASK = c015eb70[1] 'init' THREAD: c0160000
<6>GPR00: 00000073 C0161B70 C015EB70 3F000000 C01169CD 0000002E 00000004 FF002920
<6>GPR08: C01169D0 0000B000 3F000000 C00DB234 00000001 0020C000 00FFE000 007FFF14
<6>GPR16: 00000000 00000001 007FFF00 C00D0000 C00D4D30 FFFFFFFF C00D0000 C00D0000
<6>GPR24: C0110000 C0110000 C00D0000 C00D0000 C00D0000 00000747 00000719 C00DB900
<4>NIP [C00B4B00] cpm_uart_console_write+0x44/0x160
<4>LR [C00118E0] __call_console_drivers+0x6c/0x8c
<4>Call Trace:
<4>[C0161B70] [C016CBC8] 0xc016cbc8 (unreliable)
<4>[C0161B80] [00000002] 0x2
<4>[C0161BA0] [C0012170] release_console_sem+0x100/0x288
<4>[C0161BE0] [C00129BC] vprintk+0x1a0/0x33c
<4>[C0161C60] [C0012BA8] printk+0x50/0x60
<4>[C0161CE0] [C00036B4] die+0x64/0x80
<4>[C0161CF0] [C000A034] bad_page_fault+0x58/0x5c
<4>[C0161D10] [C0002F80] handle_page_fault+0x7c/0x80
<4>[C0161DD0] [C0161DE8] 0xc0161de8
<4>[C0161DE0] [C00B4F78] cpm_uart_start_tx+0x4c/0xbc
<4>[C0161E00] [C00B0740] __uart_start+0x64/0x74
<4>[C0161E10] [C00B1A4C] uart_start+0x20/0x38
<4>[C0161E30] [C00B1B38] uart_write+0xd0/0x108
<4>[C0161E60] [C00AC86C] write_chan+0x208/0x3a4
<4>[C0161EB0] [C00A92E0] tty_write+0x16c/0x258
<4>[C0161EF0] [C004C988] vfs_write+0xcc/0x144
<4>[C0161F10] [C004D3E8] sys_write+0x4c/0x90
<4>[C0161F40] [C0002AE4] ret_from_syscall+0x0/0x38
<4>Instruction dump:


Serial: CPM driver $Revision: 0.02 $
cpm_uart: WARNING: no UART devices found on platform bus!
cpm_uart: the driver will guess configuration, but this mode is no longer supported.
ttyCPM0 at MMIO 0xff000a80 (irq = 20) is a CPM UART
loop: loaded (max 8 devices)
Freeing unused kernel memory: 144k init
execute init process
Oops

J'ai comme l'impression qu'il y a une sorte de conflit avec mon cpm uart comme un dépassement de mémoire, étrangement je n'ai que le début du oops sur la sortie console.
J'ai du mal à comprendre le oops, alors si quelquun peu m'éclairer :
Je comprend que l'instruction ayant causé le oops est cpm_uart_console_write à l'offset 0x44, la trace montre le chemin du noyau avant le oops, cependant vu qu'il y a deux oops comment la lire ?? Pourquoi n'y à t'il pas symbols dérriere
ces lignes :
<4>[C0161DD0] [C0161DE8] 0xc0161de8
<4>[C0161B80] [00000002] 0x2
<4>[C0161B70] [C016CBC8] 0xc016cbc8 (unreliable)
ces adresses sont-elles celles qui cause le kernel access of bad area. ?

Voila je suis un peu perdu, si quelqu'un peut m'aider à comprendre cette erreur, ou me donner des indices sur comment résoudre ce problème ou comprendre la trace ?
Merci beaucoup
Fabien
  • # Quelques pistes

    Posté par  (site Web personnel) . Évalué à 2.

    - une exception "page fault" arrive sur le CPU vers cpm_uart_start_tx+0x4c (c'est là que Linux est sensé mettre à jour les structures de données de la MMU pour mapper la page à laquelle on veut accéder).

    - Pour une raison qui m'échappe (je ne connais pas cette architecture), la demande de map est jugée mauvaise et donc handle_page_fault appelle bad_page_fault (par l'intermédiaire de do_page_fault).

    - c'est ce bad_page_fault qui affiche "kernel access of bad area" (arch/ppc/mm/fault.c).

    - linux termine le processus fautif (init) en lui envoyant un SIGSEGV (11)

    - il est tout à fait possible que le comportement que tu observes seulement avec le process init et pas avec ton petit programme vienne de l'initialisation du port série faite par init (genre le set_termios là) ce qui pourrait mettre le driver dans un état différent que ton petit test.

    - une question un peu naïve, mais on tente : es-tu sûr d'avoir toute les pages dont tu as besoin pour accéder au hard mappées ? je ne connais pas du tout ce hard, mais par exemple les registres auxquels on accède par la structure smc_t sont-ils sur la même page que le registre tx ?

    - System.map permet de déduire les symboles dans lequel tu es si tu veux faire le décodage à la main, mais là, comme tu compiles avec les symboles de debug, le plus sage est de penser que ta pile est morte lorsqu'il essaye de décoder les derniers symboles

    - Enlever ce warning : "WARNING: no UART devices found on platform bus!" en définissant le platform_device qui va bien pour ton SoC, il me semble que dans cettre structure il y a aussi les pages physiques que linux doit mapper pour ton device

    - Il y a l'air d'avoir quelques versions différentes de l'UART cpm, bien s'assurer que l'on compiler le noyau avec la bonne config pour ton hard (cpm1, cpm2, ?)

    - Le driver cpm_uart à l'air d'avoir pas mal changé entre la version 2.6.19 et la version actuelle, mettre à jour ce driver peut être une bonne idée ?

    Bon courage !
  • # Une piste

    Posté par  . Évalué à 2.

    Passe par une étape intermédiaire : remplace dans l'initramfs
    le lien

    lrwxrwxrwx 1 root root 11 nov 28 13:15 ./init -> bin/busybox*


    par ./init->/bin/ash

    Si tu obtiens un shell, tu pourras lancer des commandes et vérifier que busybox fonctionne correctement.

    Dans un second temps, tu pourras lancer l'init de busybox à partir du shell par la commande :
    exec /sbin/init </dev/console >/dev/console 2>&1

    Bon courrage

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n’en sommes pas responsables.