Hallo zusammen, ich bin dran, ein Embedded Linux zum Laufen zu bringen, oder versuche es zumindest. :-) Ich bin schon mal soweit, dass ich ein xipImage kriege, und das bootet auch teilweise, jedenfalls kann ich mir printk() Meldungen ausgeben. Jedoch irgendwo noch bevor der init-Prozess gestartet wird, läuft was schief, und ich habe noch nicht rausgefunden, was. Jetzt die Frage - kann ich diesen Kernel einfach normal mit GDB debuggen? Es handelt sich um ein ARM7 System, der Kernel soll vom ext. Flash direkt in-place ausgeführt werden, also ohne dekompression etc. Zum Debuggen möchte ich gerne ddd benutzen; was muss ich tun, um die Symbole in ddd geladen zu kriegen? "Normale" Programme kann ich auf dem Target so debuggen, aber beim Kernel bin ich mir nicht so sicher. (Dass es bei multithreading dann schwierig wird, ist natürlich klar, aber solange der Kernel nicht richtig hoch kommt, sollte es so mit ddd ja klappen, oder?) Gruss Tobias
Moin Tobias, da ich bald das selbe Problem haben werde und gerade beim einlesen bin, bin ich gerade über kgdb gestolpert. http://scottt.tw/linux-tutorials/ letztes tutorial. kgdb scheint ein gdb modul für den Kernel zu sein. Wie gesagt ich hab da auch noch keine Erfahrung, Kenne Linux bisher nur als Desktop Nutzer und da auch nur wenig von console usw. Falls du für mich n Tip hast wo man sich gut einlesen kann gern :) MfG Tec
Gast
#3172409
Musst du wirklich so tief einsteigen? Was kommt denn als Fehler bevor es nicht mehr weitergeht? Versuch mal alles was du nicht brauchst zu deaktivieren bzw. gibts da auch afaik ein paar Optionen, dass er die Module nicht automatisch beim Hochfahren läd.
Gast
#3172566
Tobias Plüss schrieb: > Ich bin schon mal soweit, dass ich ein xipImage kriege, und das bootet > auch teilweise, jedenfalls kann ich mir printk() Meldungen ausgeben. > Jedoch irgendwo noch bevor der init-Prozess gestartet wird, läuft was > schief, und ich habe noch nicht rausgefunden, was. > Jetzt die Frage - kann ich diesen Kernel einfach normal mit GDB > debuggen? Pah, das ist Highlevel :-) Kernel mit Debug-Symbols compilieren und dann den gdb mit JTAG anbinden. Da kommst du wirklich bis zur Drahtebene. http://elinux.org/Debugging_The_Linux_Kernel_Using_Gdb
Gast
#3172577
Tobias Plüss schrieb: > ich bin dran, ein Embedded Linux zum Laufen zu bringen, oder versuche es > zumindest. :-) jeder hat mal angefangen, also mach nur weiter > Ich bin schon mal soweit, dass ich ein xipImage kriege, und das bootet > auch teilweise, jedenfalls kann ich mir printk() Meldungen ausgeben. fein das ist doch schon mal was. > Jedoch irgendwo noch bevor der init-Prozess gestartet wird, läuft was > schief, und ich habe noch nicht rausgefunden, was. Wie verhält sich das "läuft was schief" genau? Endlesslop, Crashdump etc.. beschrieb das mal etwas genauer um dir zu helfen ist das entscheidend, vielleicht kann man an diesen Informationen schon das Problem soweit eingrenzen das man das schwere geschütz Debugger im Schrank lassen kann. ggf kannst du die Aussgabe der Rootconsole mitzuschneiden. (gnu/screen kann das zum Beipiel) > Jetzt die Frage - kann ich diesen Kernel einfach normal mit GDB > debuggen? Nein das geht nicht. es gibt wie schon ewähnt den kgdb, aber der geht auch nicht immer einfach so. Ausserdem brauchts du auf den host ein gdb welcher für das Taget ARM7 ist. Alles andere ist quatsch. Wichtig ist auch die System.map dort liegen die debugg informationen für dein Kernel. Alternativ liefern auch Hersteller wie Lauterbach, Windriver, Montavista und der erzeuger deines BSP meistens bessere oder schlechtere Tools für das Kernel debuggen. Der Lauterbach debugger ist toll aber mit mehren Kilo Euros so teuer, das man denn auch nur dann kauft wenn man das Hauptberuflich macht. > > Es handelt sich um ein ARM7 System, der Kernel soll vom ext. Flash > direkt in-place ausgeführt werden, also ohne dekompression etc. > geht, für das debuggen und Entwickeln ist es aber meisten eleganter, den Bootloader zu sagen den Kernel via TFTP zu laden das geht in der Regel schneller mal was auszu probieren. Btw das root als NFS ist aus denn grund auch nicht schlecht. > Zum Debuggen möchte ich gerne ddd benutzen; was muss ich tun, um die > Symbole in ddd geladen zu kriegen? "Normale" Programme kann ich auf dem > Target so debuggen, aber beim Kernel bin ich mir nicht so sicher. Auch das geht mit den passenden Arm7 gdb und denn kernel mit kgdb. Ich glaube der ddd parameter war --target-* Aber wichtiger bei solchen Problemen ist ddd als "debuggen druch Denken" zu übersetzten und sich nicht auf seine GUI zu verlassen, wie ob schon angedeutet kann man bie vielen Fehlern durch scharfes Hinsehen und logisch denken vieles schon erschlagen bevor andere Ihren gdb und ddd zum laufen gebracht haben. Ausserdem behaupten einige das man mit einen debugger die symtome bekämpft und nicht die Ursachen.
Hallo zusammen, erstmal danke für eure zahlreichen Antworten! Nun, einen JTAG-Debugger für mein Target sowie eine passende GDB executable habe ich natürlich. Das funktioniert auch, habe ich für "gewöhnliche" Programme schon getestet. Was ich vorerst mal tun will, ist ja nicht einmal, irgendwelches Scheduler-Zeugs zu testen, sondern ich will zunächst nur mal nachvollziehen, was denn nicht geht. Da ich die Hardware selber gebaut habe, gibt es auch kein fertiges BSP, was ich einfach hernehmen kann und das läuft, sondern ich musste da selber was schreiben gemäss "ARM Linux porting guide". Mein Kernel bootet eigentlich soweit hoch, dass er bis dort kommt, wo /sbin/init aufgerufen werden sollte. Mein Problem ist halt, dass der UART-TReiber bisher auch noch nicht richtig geladen wurde - ich habe einen 16c550 kompatiblen UART, aber aus irgend einem Grunde geht printk() nicht ordentlich, sondern ich habe mir mit early_printk() was zurechtgebogen. :-/ Auf jeden Fall habe ich meinen Tick-Interrupt mal so gemacht, dass bei jedem Interrupt eine Meldung via early_printk() auf der Seriellen ausgegeben wird; den Timer habe ich mal mit 10 Hz angesetzt, was locker passt. Der Tick Interrupt kommt dann einige 100 mal, bis der Kernel schliesslich versucht, init zu laden, was anscheinend fehl schlägt, und dann stürzt die Kiste ab (Reset). Sieht mir ganz danach aus, als ob da irgendwie ein ungültiger Pointer oder sowas wäre, aber bis jetzt konnte ich es noch nicht so ganz nachvollziehen.... :-( Ich will heute Abend mal mit dem Tutorial versuchen, den GDB anzuwerfen und mir mit ddd das mal anzuschauen, bin gespannt ob ich was sehe (wenigstens unversucht will ich es nicht lassen ;-) ). Gruss
Keine Ahnung, ob's auf Dein Problem passt, aber vielleicht Hilft's ja: Den Thread kennst Du? Beitrag "Linux Kernel compilieren"
Moin zusammen, danke nochmals für eure Hilfe. Was ich in der Zwischenzeit versucht habe: ich habe ein xipImage neu erstellt und dieses ins Flash geladen. Das xipImage bootet (halt fehlerhaft noch bis jetzt) und ich wollte mal den Debugger anwerfen. Wie erwähnt habe ich für mein Target einen J-Link mit GDB-Server. Das Debuggen funktioniert so, habe ich mit früheren Programmen schon getestet, allerdings ist mir nicht klar, welche der vielen beim Compilieren erzeugten Dateien ich im Debugger laden muss, damit ich die Symbole geladen kriege. xipImage enthält keine Symbole, ebenso wenig wie vmlinux. Wo sind denn diese Symbole drin? Dann noch was anderes. Ich habe bemerkt, dass mein Kernel eigentlich korrekt booten würde, wenn ich im Timerinterrupt die UART-Ausgaben weglasse. Stattdessen lasse ich bei jedem Timer-Tick einen Pin toggeln; auf dem Oszi lässt sich dies hervorragend nachvollziehen und der Timer-Tick scheint zu funktionieren! Allerdings ist der Timer das einzige, was mein Kernel bis jetzt im Stande ist, zu initialisieren :-) Zwar habe ich einen m.E. korrekten "Device Tree" erstellt, wie dies gefordert wird, aber dort drin werden meine Devices nicht gefunden, z.B. der UART wird nicht initialisiert etc. Was könnte da das Problem sein? Wenn ich es halt debuggen könnte, wäre es schon viel einfacher, aber das geht halt leider noch nicht, daher kann ich auch nur eine so schwammige Fehlerbeschreibung geben :-(
Gast
#3173322
Hallo Wenn ich das richtig lese hast du ein ARM7 also noch ohne MMU ?? oder
Ja genau!
Gast
#3173623
Ich würde mal drauf tippen das irgendwas mit der Config vom 16550 nicht stimmt. Hast du den DeviceTree mit r2 an den Kernel übergeben ? Die Symbole sind in der Datei System.map im Builddir vom Kernel. Benutzt du den vanilla Kernel oder den von uClinx.org ? Schau mal bei beiden nach welche Platform deiner CPU/SoC am nächsten kommt. Das ARM Porting Guide ist eigentlich dafür gedacht wenn du bei Null anfangen musst.
Gast
#3173654
Nur mal so am Rande. Versuch doch den Kernel mit dem Qemu laufen zu lassen. Gruss, Tobi
Hallo zusammen, so, ich bin nun ein ganzes Stück weiter! Ich konnte nun alle meine early_print() raus schmeissen, denn mein Kernel kann jetzt so weit booten, dass der UART erkannt wird und die normalen Kernel-Meldungen erscheinen!
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
leider erkennt ihr, dass nicht alles ganz so funktioniert; das "Register remapping" scheint nicht zu funktionieren. Ich schätze, wenn ich keine MMU habe, dann wird auch map_io() vom Machine Record nie aufgerufen, richtig? und ohne MMU brauche ich auch kein Remapping? Wie kriege ich dann jeweils die Basisadresse meiner Devices?
Gast
#3175108
Hast du denn schon mal nach der Fehlermeldung in den Sourcen gegreped ... Nein, da finde ich folgende Zeile
1 | |
Im Makefile drivers/clocksource/Makefile finde ich denn das
1 | |
Da ist wohl was mit deiner Config falsch. Nimm erstmal ARCH_MULTIPLATFORM raus.
Hi Hans Ulli, nein die Fehlermeldung kommt von meinem Code, habe da was kopiert und auf meine Bedürfnisse angepasst. Er scheitert halt beim Statement hier:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
Die node für den Timer findet er also, das macht er korrekt. Aber of_iomap() schlägt fehl. Aber die Frage ist halt, ob ich das wirklich brauche, auch wenn ich keine MMU habe? Edit: mein KConfig sieht so aus:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
Also nichts mit Multiplattform.
Gast
#3175471
Tobias Plüss schrieb: > Die node für den Timer findet er also, das macht er korrekt. Aber > of_iomap() schlägt fehl. Aber die Frage ist halt, ob ich das wirklich > brauche, auch wenn ich keine MMU habe? > of_iomap brauchst du hier nicht, weil wie gesagt keine MMU. Aber du brauchst ja deine BASE Addresse vom Device aka Timer. In der Funktion of_iomap () ist auch die Lösung zu finden ...
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
Wenn du folgenden Teil benutzt :
1 | |
2 | |
3 | |
4 | |
liegt in res.start deine BASE Addresse.
In einigen (alten) Treiberen wurde nach dem "get_resource" noch ioremap
"zu Fuss" gemacht"
> Also nichts mit Multiplattform.
War meine erste Annahme nach einigem grepen
Was mich auch noch stutzig mach(te) war/ist folgende Ausgabe.
bcm2835_time_init
Gast
#3175648
Hmmm ... kennst du ein gutes und preisgünstiges Board ?? Wichtig ist auch das es ein Gehäuse dafür gibt, ich habe keine Lust zum basteln. Vielleicht würde es mich mal reizen mal mit einem NOMMU System zu spielen. Ich kenne jetzt schon MIPS und ARM Systeme aber alles mit MMU ... Die Netzwerkperformance (Ethernet/Wifi) und USB dürften wohl unterirdisch sein. Achja Den CodingStyle solltest du mal überdenken ... Die geschweiften Klammer sind nicht K&R. Was jetzt mit den Spaces vor und nach den Klammern ist, lass ich ertsmal da ich es selbst nach einigen Jahren(zehnten ?) noch nicht verinnerlicht habe .
Hallo Hans Ulli, danke für den Hinweis. Das habe ich auch schon gesehen, aber war mir nicht sicher. Aber danke für deine Bestätigung, ich habe es jetzt bei mir so implementiert! Was ich mich noch frage: Es gibt ja die Timer-Initfunktion, welche auch im machine Record vermerkt wird (mit der sys_timer-Struktur). Meine Timer-Init sieht jetzt wie folgt aus:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
Testen konnte ich es noch nicht, aber es erscheint mir nun alles relativ plausibel. Was ich damit machen will - im Device Tree habe ich bei einem Timer einen Property "system-timer;" erstellt. Denjenigen Timer suche ich heraus, und benutze den dann. Dann ermittle ich aus dem Device Tree die Basisadresse des Timers, und lege Pointer auf die einzelnen Register in der Struktur timer ab (bei /* set all register addresses */). Jetzt habe ich hierzu noch ein paar Fragen: 1. zu welchem Zeitpunkt soll ich den Timer wirklich initialisieren, sodass der auch im Stande ist, Interrupts zu generieren? Ich habe mal unten als Kommentar eingefügt, an welcher Stelle ich das machen würde. Sicher bin ich mir aber nicht; im Code für den BCM2835 (bcm2835_timer.c) kann ich nicht erkennen, wo da der Timer wirklich gestartet wird. 2. setup_sched_clock(): wozu genau braucht man das? verstehe ich das richtig, dass der Scheduler die dort angegebene Callbackfunktion aufruft, und so die verstrichene Zeit zu bestimmen? rate (letzter Parameter) ist die Anzahl der Timerinterrupts pro Sekunde? 3. clocksource_mmio_init(): sieht für mich irgendwie nach dem selben aus wie setup_sched_clock(). Wozu dient das? Hoffe du hilfst mir weiter. :-) Vielen Dank & Gruss
Gast
#3175696
Portierst/entwickelst Du für einen NXP Prozessor? Darf man Fragen für welchen?
Gast
#3175804
Ich antworte erstmal schnell auf die Fragen ... Der Rest folgt dann noch heute Abend Tobias Plüss schrieb: > Jetzt habe ich hierzu noch ein paar Fragen: > 1. zu welchem Zeitpunkt soll ich den Timer wirklich initialisieren, > sodass der auch im Stande ist, Interrupts zu generieren? Ich habe mal > unten als Kommentar eingefügt, an welcher Stelle ich das machen würde. > Sicher bin ich mir aber nicht; im Code für den BCM2835 (bcm2835_timer.c) > kann ich nicht erkennen, wo da der Timer wirklich gestartet wird. Das müsste normalerweise noch dem init des Kernels ablaufen. Also nach CPU, MMU init, davor kommt noch die Meldung mit BogoMips. Der Timer wird ja auch benutzt um den internen udelay zu kalibieren, diesen braucht auch zum Teil beim Device Init. > > 2. setup_sched_clock(): wozu genau braucht man das? verstehe ich das > richtig, dass der Scheduler die dort angegebene Callbackfunktion > aufruft, und so die verstrichene Zeit zu bestimmen? rate (letzter > Parameter) ist die Anzahl der Timerinterrupts pro Sekunde? > Ja. Soweit ich das auf ich schnelle in verschiedene Sourcen Lese korreliert das mit der Anzahl der Zyklen bis zum "Timerüberlauf" siehe Timer in arch/arm/mach-sa1100/time.c obwohl ich eigentlich zu den Sourcen in arch/arm/mach-lpc32xx/timer.c tendiere, das ist näher am LPC24XX. Ich würde da ggf. einen Mix von allen dreien machen > 3. clocksource_mmio_init(): sieht für mich irgendwie nach dem selben aus > wie setup_sched_clock(). Wozu dient das? > Aus dem Kopf wusste ich es auch nicht aber gitk drivers/clocksource/mmio.c gibt schon mal den Anfang
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
So jetzt muss ich erstmal sehen was readl_relaxed() heist, readl usw. kenne ich ja schon ...
Gast
#3175806
Martin schrieb: > Portierst/entwickelst Du für einen NXP Prozessor? > Darf man Fragen für welchen? Ich Tippe mal auf das Bootlog Machine: LPC24XX SoC (Flattened Device Tree), model: LPC2468 Board
Hallo Hans Ulli, es gibt News. Der Kernel läuft nun bis hier:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
Das initialisieren des Timers funktioniert, der Interrupt wird aufgerufen. Soweit klappt es also! aber mit dem Clockevents oder so scheint noch was nicht gut zu sein - das muss ich morgen rausfinden. Gruss
Hallo zusammen, ich bin zwischenzeitlich etwas weiter gekommen. Mein Bootloag sieht jetzt so aus:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
Ich hab die Busybox compiliert und ein root file system kreiert. Das wird anscheinend auch geladen, aber man sieht es nicht, weil der UART nicht zu funktionieren scheint :-) warum auch immer. Was müsste man da wohl noch tun? BTW, was ist das Modul "brd" ? Gruss
Gast
#3179329
Moin, anstatt ständig Kernel Logs zu posten wäre es ganz schön zu wissen was du gemacht hast um es zum Laufen zu bringen. Quasi für die Nachwelt. Gruss, Tobi
Gast
#3179773
Tobias Plüss schrieb: > BTW, was ist das Modul "brd" ? > einfach mal nach grepen ...
1 | |
2 | |
3 | |
Und dann ...
1 | |
2 | |
Das ist der Treiber die RAMDISK. Wenn ich das Log richtig lese (wobei mir irgendwie noch einige Zeilen fehlen) ist das RootFS schon da, weil ja das brd (RAMDISK_DEV) geladen wird.
Gast
#3180475
Tobi schrieb: > Moin, > > anstatt ständig Kernel Logs zu posten wäre es ganz schön zu wissen was > du gemacht hast um es zum Laufen zu bringen. Quasi für die Nachwelt. gibt es denn überhaupt Interesse ?? Der Tobias Plüss ist erst am Anfang der Anfang der Kernelentwicklung ... Als Anfang würde ich erst mal dazu raten ein RootFS mal selber zu bauen und dann mal auf einem Zielsystem ARM oder MIPS per chroot zu starten ... ggf. würde ich auch mal zu Gentoo/Sabayon raten, da es dort eine sehr gute Unterstüzung für CrossCompiler Development eingebaut ist.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.