mboost-dp1

bruge rmmod og insmod fra c-kode i /proc på android/linux


Gå til bund
Gravatar #1 - Qw_freak
17. apr. 2012 15:49
Hay, jeg kan ikke finde noget omkring indsætningen og udtagningen af moduler i linux kernen direkte fra en FD i /proc folderen.

Det jeg skal, er at ECHO'e min fil et '1' og så skal den sætte en udgang høj, og samtidig unloade en driver og bagefter loade en ny...

Any ideas?
Gravatar #2 - redhead
17. apr. 2012 17:20
Hvis du ser på sovsen for rmmod*, ser du at den benytter kerne proceduren delete_module() **) fra kernel/module.c

Det samme kan du se fra sovsen til insmod, hvor den benytter init_module() ***)

Så du kan inkorporere samme kald-semantik i dit program, uden at skulle bikse med at ville kalde system programmer.

*) http://www.koders.com/c/fidDD7BCB573E8FB4388A83BB8...

**) http://www.kernel.org/doc/man-pages/online/pages/m...

***) http://www.kernel.org/doc/man-pages/online/pages/m...
Gravatar #3 - kasperd
17. apr. 2012 22:38
Qw_freak (1) skrev:
Any ideas?
For mig lyder det som om du burde genoverveje dit design. At have et modul der på den måde indlæser og fjerner andre moduler er en lidt rodet og ugennemskuelig konstruktion. Før eller siden vil det sikkert vise sig at give problemer.

Hvis du absolut vil have din modul kode til at indlæse andre moduler, så bør du nok anvende request_module() funktionen.

At fjerne moduler er der til gengæld ingen support for fra kernen. Du kan se den kernefunktion der håndterer delete_module kald fra user mode:
http://lxr.linux.no/linux+v3.3.2/kernel/module.c#L767 skrev:
SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
unsigned int, flags)


Hvad der er vigtigt at bemærke er at den bliver kaldt med en user space pointer til modulnavnet. Det vil sige at den kræver at navnet på modulet ligger i user space. Det kan ikke opnås fra et kernemodul.

Den pågældende funktion kunne have været en simpel wrapper, der kopierede modulnavnet over i kernel space og så kaldte en anden funktion med en kernel space pointer. Men sådan er den ikke lavet. Koden til at kopiere navnet og koden til at håndtere logikken omkring fjernelse af modulet ligger i en og samme funktion, du kan altså ikke lave et kald udenom. Nogle af kommentarerne antyder at lidt af logikken omkring afhængigheder overlades til rmmod kommandoen, så i sidste ende bør du nok lade sletning af modulet gøres fra user mode.

Du har fem muligheder:
1. Flyt alt din kode til at indlæse og fjerne moduler over i user mode.
2. Refaktoriserer kernen således at delete_module bliver til en wrapper omkring en funktion du kan kalde andre steder i kernen.
3. Duplikere det meste af indholdet af delete_module og kald kopien i din egen kode.
4. Brug get_fs() og set_fs() kaldene til at ændre betydningen af user space pointers (jeg aner ikke om dette stadig er muligt på nyere kerner).
5. Kald en user mode helper på samme måde som request_module() gør (se http://lxr.linux.no/linux+v3.3.2/kernel/kmod.c)

Jeg vil anbefale at du vælger mulighed 1 eller 5 fra ovenstående liste. Hvis du vælger mulighed 2 og sender din refaktorisering til mailinglisten vil du finde ud af om kerneudviklerne er enige med mig. Mit gæt er at de vil fortælle dig at det du laver på ingen måde høre hjemme i kernen og der vil nok ikke blive lagt fingre imellem.
Gravatar #4 - Qw_freak
18. apr. 2012 08:14
kasperd (3) skrev:
Hvis du vælger mulighed 2 og sender din refaktorisering til mailinglisten vil du finde ud af om kerneudviklerne er enige med mig. Mit gæt er at de vil fortælle dig at det du laver på ingen måde høre hjemme i kernen og der vil nok ikke blive lagt fingre imellem.

Hvad er det for noget, den mailing liste??

Det ser for mig ud til at jeg kan kalde:

init_module(modulnavn);
cleanup_module(modulnavn);

Fra mit modul i /proc

Jeg arbejder på et custum Android build som er meget HW specifik, så jeg tror ikke det bliver rodet at gøre det jeg vil modul baseret.'

Hvis ikke det bliver sådan, bliver det istedet gjort via et script som så også kører mit GPIO modul, som jeg ellers ville inkoorpere modul udskiftningen i. Men jeg er sådan set imod at gøre det via et script fordi jeg synes det ville gøre det endnu mere indviklet.

modulbasert:
app -> modul -> driverudskiftning og GPIO

scriptbaseret:
app -> script -> modul -> GPIO
__________-> driverudskiftning
Gravatar #5 - kasperd
18. apr. 2012 09:13
Qw_freak (4) skrev:
Hvad er det for noget, den mailing liste??
http://lkml.org/

Qw_freak (4) skrev:
init_module(modulnavn);
Den funktion skal også kaldes med pointers til user space. Altså kan du ikke bruge den fra dit modul. Brug i stedet for request_module() som er beregnet til formålet.

Når du kalder request_module() startes der en ny process som kalder modprobe programmet. Tråden der kaldte request_module() vil sove indtil modprobe er færdig (der er en anden funktion du kan kalde, hvis du ikke vil sove).

Qw_freak (4) skrev:
cleanup_module(modulnavn);
Reference? Den eneste cleanup_module funktion jeg kunne finde frem til er oprydningsfunktionen i selve modulet. Den tager ingen argumenter og fjerner i øvrigt ikke modulet.

Det er delete_module() som fjerner et modul, hvilket involverer flere ting som skal gøres hhv. før og efter modulets oprydningsfunktion kaldes.

Som tidligere forklaret kan delete_module() ikke kaldes fra kernekode.

Qw_freak (4) skrev:
Hvis ikke det bliver sådan, bliver det istedet gjort via et script som så også kører mit GPIO modul, som jeg ellers ville inkoorpere modul udskiftningen i.
En GPIO driver skal selvfølgelig skrives som et kernemodul. Men indlæsning og fjernelse af moduler hører ikke til i et modul.

Hvis du i stedet forklarer hvad de andrer moduler gør og hvorfor du tror det giver mening på skift at indlæse og fjerne modulerne, så kan jeg måske give et bud på hvad du skal lave om for at få det til at virke.

Hvis ikke man bare kan indlæse alle modulerne en gang for alle og så beholde dem indlæst indtil systemet rebootes, så er det en fejl i modulkoden.
Gravatar #6 - Qw_freak
18. apr. 2012 09:17
kasperd (5) skrev:
Hvis du i stedet forklarer hvad de andrer moduler gør og hvorfor du tror det giver mening på skift at indlæse og fjerne modulerne, så kan jeg måske give et bud på hvad du skal lave om for at få det


Det er fordi jeg skal lave en slags lowtech USB On The Go løsning som skal skifte mellem at gøre enheden til enten en device eller en host.

GPIO udgangen er for at switche mellem at være fysisk host og være modtager af strøm.

Gravatar #7 - kasperd
18. apr. 2012 09:34
Qw_freak (6) skrev:
Det er fordi jeg skal lave en slags lowtech USB On The Go løsning som skal skifte mellem at gøre enheden til enten en device eller en host.
Ok. Hvad sker der hvis driverne til begge sider er indlæst samtidigt?

Qw_freak (6) skrev:
GPIO udgangen er for at switche mellem at være fysisk host og være modtager af strøm.
Det lyder rimeligt nok. Og GPIO driveren skal naturligvis være indlæst hele tiden. Spørgsmålet er nu om GPIO driveren skal være en separat driver som intet andet gør eller om den skal være integreret med USB koden. Det kan jeg nok give et bud på, når jeg har lidt bedre fornemmelse for hvordan din enhed skal fungere.

Hvad styrer om enheden fungerer som USB device eller USB host? Regner du med at den kan komme til at skifte automatisk når kablet sættes i? Eller er det noget man selv skal vælge gennem brugerfladen?
Gravatar #8 - Qw_freak
18. apr. 2012 09:48
kasperd (7) skrev:
Ok. Hvad sker der hvis driverne til begge sider er indlæst samtidigt?


Det ved jeg ikke, men jeg må jo designe det sådan at det ikke kan ske... !?!?


kasperd (7) skrev:
Hvad styrer om enheden fungerer som USB device eller USB host? Regner du med at den kan komme til at skifte automatisk når kablet sættes i? Eller er det noget man selv skal vælge gennem brugerfladen?


Det er selve hoved appen der skal kunne bestemme hvordan enheden skal agere, den skal egentlig kun bruges som host, men under udviklingen af hoved app'en skal enheden være device... derfor kun denne low-tech løsning.
Gravatar #9 - kasperd
18. apr. 2012 11:56
Qw_freak (8) skrev:
Det er selve hoved appen der skal kunne bestemme hvordan enheden skal agere, den skal egentlig kun bruges som host, men under udviklingen af hoved app'en skal enheden være device...
Hvis det kun er til debugging formål, så flytter det jo grænsen lidt for hvor grimme løsninger man kan tillade sig at anvende. ;-)

Jeg mener dog stadig du kommer længst ved at holde koden i user mode. En ganske simpel daemon der udskifter driverne er nok den rette løsning. Så må applikationen fortælle denne daemon hvornår der skal skiftes.

Måske vil du få glæde af en watchdog funktionalitet således at daemonen automatisk skifter til device mode, hvis ikke den modtager et heartbeat fra applikationen.

Her er et forslag til hvordan daemonen kunne se ud, hvis den blev lavet som et shell script
#!/bin/bash

CURRENT_MODE=none

while sleep 3
do
if [ -N /tmp/heartbeat ]
then
NEW_MODE=host
cat /tmp/heartbeat >/dev/null
else
NEW_MODE=device
fi

if [ "$NEW_MODE" != "$CURRENT_MODE" ]
then
echo "$(date) switching from $CURRENT_MODE to $NEW_MODE"
case "$NEW_MODE" in
host)
echo "Switching to host mode"
rmmod device_module
echo 1 >/dev/gpiodriver
modprobe host_module
;;
device)
echo "Switching to device mode"
rmmod host_module
echo 0 >/dev/gpiodriver
modprobe device_module
;;
esac
CURRENT_MODE="$NEW_MODE"
fi
done
Så skal applikationen blot skrive til /tmp/heartbeat en gang i sekundet for at daemonen ved at den stadig kører og ønsker at enheden skal være i host mode.
Gå til top

Opret dig som bruger i dag

Det er gratis, og du binder dig ikke til noget.

Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.

Opret Bruger Login