Project

General

Profile

DeprecatedPortingGuideMSMQSD » History » Version 37

Denis 'GNUtoo' Carikli, 01/03/2011 09:44 PM

1 1 Denis 'GNUtoo' Carikli
== Introduction ==
2
Many people bought many different phones, and some of them whish to help replicant and/or to port replicant to their phones or devices.
3 33 Michael Haas -
This guide will show what was done for the htc dream, so these people can understand the process better.
4 34 Michael Haas -
When talking about porting, this page talks about re-using existing product definitions. You will not learn how to
5
build Android for a device not currently supported by Android. Instead, you will learn how to build a version of
6
[Cyanogenmod http://www.cyanogenmod.com/] without proprietary parts.
7 35 Michael Haas -
To gain more insight in the Android build system, refer to [http://source.android.com/porting/build_system.html Android Build System documentation] which is part of
8 34 Michael Haas -
[http://source.android.com/porting/ Android Platform Developer's Guide]. You should find an answer there if you have any questions about the Makefiles referenced in this document.
9 32 Michael Haas -
10 1 Denis 'GNUtoo' Carikli
== Terminology ==
11 33 Michael Haas -
The RIL is the radio interface library, that is to say, a library that talks to the modem, usually (but not always) trough AT commands.
12 32 Michael Haas -
Basically the modem runs on a separate CPU,and there is some sort of communication needed between the main CPU and the modem CPU to make telephony work. For instance, the modem must tell you when you've got a call, and you must tell the modem that you want to call someone.
13 1 Denis 'GNUtoo' Carikli
TODO: point to 0707 standard or newer
14
15 31 Denis 'GNUtoo' Carikli
== Help with source code ==
16 32 Michael Haas -
Keep in mind that on most devices, the full source code of the kernel is released.
17
However, some userspace libraries, or dlopened libraries (libraries loaded at runtime after the application started) are proprietary software,
18 31 Denis 'GNUtoo' Carikli
so if you're porting to a new CPU/SOC keep in mind that you have the source code to the kernel interfaces.
19
That can help a lot, and sometimes there is even some sort of documentation in the headers.
20 1 Denis 'GNUtoo' Carikli
21
== Build the source ==
22
23
The first thing to do is to download the replicant sources:
24
[wiki:BuildDream] can be used as a reference: download and build the sources for your device.
25 32 Michael Haas -
Let's say the user has a HTC Wildfire. It is useful to know the codename of the device in question, which is "Buzz" in case
26
of the Wildfire.
27 1 Denis 'GNUtoo' Carikli
28 32 Michael Haas -
You need to configure the build tree for our device. By default, a generic image
29
for the Android emulator will be built. 
30
In [wiki:BuildDream], you would use the following command to set up the build:
31 2 Denis 'GNUtoo' Carikli
{{{
32
lunch cyanogen_dream_sapphire-eng 
33
}}}
34 32 Michael Haas -
Now, since you are not building for the HTC dream, you need to identify the right command that corresponds to your device.
35
In order to do that, run the following command and look at its output.
36 2 Denis 'GNUtoo' Carikli
{{{
37
$ source build/envsetup.sh
38
including device/geeksphone/one/vendorsetup.sh
39
including device/htc/ace/vendorsetup.sh
40
including device/htc/bravoc/vendorsetup.sh
41
including device/htc/bravo/vendorsetup.sh
42
including device/htc/buzz/vendorsetup.sh
43
including device/htc/glacier/vendorsetup.sh
44 1 Denis 'GNUtoo' Carikli
including device/htc/heroc/vendorsetup.sh
45
including device/htc/inc/vendorsetup.sh
46 2 Denis 'GNUtoo' Carikli
including device/htc/legend/vendorsetup.sh
47
including device/htc/liberty/vendorsetup.sh
48
including device/htc/supersonic/vendorsetup.sh
49
including device/htc/vision/vendorsetup.sh
50
including device/motorola/sholes/vendorsetup.sh
51
including device/nvidia/harmony/vendorsetup.sh
52
including vendor/cyanogen/vendorsetup.sh
53
}}}
54 37 Denis 'GNUtoo' Carikli
The last line is important:
55 1 Denis 'GNUtoo' Carikli
{{{
56 37 Denis 'GNUtoo' Carikli
$ cat vendor/cyanogen/vendorsetup.sh
57
add_lunch_combo cyanogen_ace-eng
58
add_lunch_combo cyanogen_bravo-eng
59
add_lunch_combo cyanogen_bravoc-eng
60
add_lunch_combo cyanogen_buzz-eng
61
add_lunch_combo cyanogen_dream_sapphire-eng
62
add_lunch_combo cyanogen_espresso-eng
63
add_lunch_combo cyanogen_glacier-eng
64
add_lunch_combo cyanogen_harmony-eng
65
add_lunch_combo cyanogen_hero-eng
66
add_lunch_combo cyanogen_heroc-eng
67
add_lunch_combo cyanogen_inc-eng
68
add_lunch_combo cyanogen_legend-eng
69
add_lunch_combo cyanogen_liberty-eng
70
add_lunch_combo cyanogen_one-eng
71
add_lunch_combo cyanogen_passion-eng
72
add_lunch_combo cyanogen_sholes-eng
73
add_lunch_combo cyanogen_supersonic-eng
74
add_lunch_combo cyanogen_vibrant-eng
75
add_lunch_combo cyanogen_vision-eng
76
add_lunch_combo cyanogen_z71-eng
77 4 Denis 'GNUtoo' Carikli
78 37 Denis 'GNUtoo' Carikli
PATH=$PATH:$PWD/vendor/cyanogen/tools ; export PATH
79 4 Denis 'GNUtoo' Carikli
}}}
80 37 Denis 'GNUtoo' Carikli
The output include the list of supported (by cyanogenmod) devices.
81
For instance if you have the Wildfire (codename 'buzz') phone do:
82 36 Michael Haas -
{{{
83 1 Denis 'GNUtoo' Carikli
lunch cyanogen_buzz-eng
84 36 Michael Haas -
}}}
85
86
Note that "cyanogen" was substituted for "generic" in the string. The build must use the Cyanogen vendor instead of the "generic" vendor
87
to avoid build failure due to missing code overlays. If you're really curious about the correct string, see vendor/cyanogen/vendorsetup.sh.
88 1 Denis 'GNUtoo' Carikli
89
Then build the source, backup what's on your device, including the operating system, and flash the new replicant image.
90 9 Denis 'GNUtoo' Carikli
91
Then test what works and what doesn't.
92 1 Denis 'GNUtoo' Carikli
93
The images are located in 
94
{{{
95
out/target/product/dream_sapphire
96 32 Michael Haas -
}}}
97 8 Denis 'GNUtoo' Carikli
in the case of the HTC Dream. You need to look in the path that corresponds to your device.
98 1 Denis 'GNUtoo' Carikli
99
== Trying free replacements ==
100 32 Michael Haas -
101
The source code you just built contains some free replacements for the proprietary
102
libraries shipped by your phone vendor with the default firmware.
103
104 1 Denis 'GNUtoo' Carikli
A list of proprietary libraries is available in
105 10 Denis 'GNUtoo' Carikli
{{{
106
device/htc/dream_sapphire/extract-files.sh
107 32 Michael Haas -
}}}
108
Note: don't run this file, just look at it. If you run it, the proprietary files will be copied from your phone into the build tree. A build containing proprietary files would put you and
109 1 Denis 'GNUtoo' Carikli
your users at risk. Additionally, it is illegal to redistribute such build, because the libraries are not redistributable(the copyright owner didn't allow you to redistribute them).
110 32 Michael Haas -
111
112
=== RIL test ===
113
I will take the example of how to use the free RIL (Radio Interface Library) to see if it works fine without modifications:
114 11 Denis 'GNUtoo' Carikli
The proprietary RIL library (which you don't have in the phone) location is found looking at the extract-files.sh
115
here's a part of extract-files.sh:
116
{{{
117
adb pull /system/lib/libhtc_ril.so ../../../vendor/htc/$DEVICE/proprietary/libhtc_ril.so
118 32 Michael Haas -
}}}
119
Note: don't run this command, just look at it. If you run it, the proprietary files will be copied from your phone into the build tree. A build containing proprietary files would put you and
120
your users at risk. Additionally, it is illegal to redistribute such build, because the libraries are not redistributable(the copyright owner didn't allow you to redistribute them).
121
122 12 Denis 'GNUtoo' Carikli
So looking at the above line the proprietary RIL is located here on the phone:
123
{{{
124
/system/lib/libhtc_ril.so
125 32 Michael Haas -
}}}
126 13 Denis 'GNUtoo' Carikli
while the free ril is located here (known fact):
127 14 Denis 'GNUtoo' Carikli
{{{
128 1 Denis 'GNUtoo' Carikli
/system/lib/libreference-ril.so
129 32 Michael Haas -
}}}
130 13 Denis 'GNUtoo' Carikli
In order to test the free RIL you could be tempted to do that:
131 14 Denis 'GNUtoo' Carikli
{{{
132 15 Denis 'GNUtoo' Carikli
# ./adb remount
133 14 Denis 'GNUtoo' Carikli
# ./adb shell
134 1 Denis 'GNUtoo' Carikli
mv /system/lib/libreference-ril.so /system/lib/libhtc_ril.so
135
}}}
136
But that wouldn't work as it wouldn't be using the right serial port, the correct way to try that is to use getprop/setprop:
137 14 Denis 'GNUtoo' Carikli
{{{
138 1 Denis 'GNUtoo' Carikli
# ./adb shell
139
# setprop
140
usage: setprop <key> <value>
141 32 Michael Haas -
}}}
142 13 Denis 'GNUtoo' Carikli
Here's how it looks on a working replicant on the HTC Dream:
143
{{{
144
# ./adb shell
145
# getprop | grep ril
146
[ro.ril.hsxpa]: [2]
147
[ro.ril.gprsclass]: [10]
148 1 Denis 'GNUtoo' Carikli
[rild.libpath]: [/system/lib/libreference-ril.so]
149
[rild.libargs]: [-d/dev/smd0]
150 15 Denis 'GNUtoo' Carikli
[init.svc.ril-daemon]: [running]
151
[ro.ril.def.agps.mode]: [2]
152
[gsm.version.ril-impl]: [android reference-ril 1.0]
153 32 Michael Haas -
}}}
154
 * /dev/smd0 is the (emulated) serial port
155 13 Denis 'GNUtoo' Carikli
 * /system/lib/libreference-ril.so is where to look for the RIL hardware specific library 
156 14 Denis 'GNUtoo' Carikli
157 12 Denis 'GNUtoo' Carikli
Then change the following properties and reboot:
158
{{{
159 7 Denis 'GNUtoo' Carikli
./adb shell reboot
160 32 Michael Haas -
}}}
161 10 Denis 'GNUtoo' Carikli
Then try the reference RIL.
162 32 Michael Haas -
163 16 Denis 'GNUtoo' Carikli
== Replacing proprietary libraries for real ==
164 32 Michael Haas -
165
On the HTC Dream the following proprietary libraries were replaced:
166 16 Denis 'GNUtoo' Carikli
(Refer to [wiki:ProprietaryHtcDreamLibsReplacement] for more up to date details(or fix it if it's less recent))
167
168
The first thing you will have to do is to modify the build system.
169 1 Denis 'GNUtoo' Carikli
The key thing to do is to change 
170 32 Michael Haas -
171
=== RIL ===
172
If the RIL you previously tried works fine, why not switching to it...directly in the build system.
173 16 Denis 'GNUtoo' Carikli
Here's the diff between A working RIL and a non-working RIL for the htcdream:
174
{{{
175
android_device_htc_dream_sapphire$ git diff 5593d2899203ec378c306701788f1c43af9a6935 -- full_dream_sapphire.mk
176
diff --git a/full_dream_sapphire.mk b/full_dream_sapphire.mk
177
index 9ec7feb..eb1b956 100644
178
--- a/full_dream_sapphire.mk
179
+++ b/full_dream_sapphire.mk
180
@@ -40,7 +40,8 @@ PRODUCT_PROPERTY_OVERRIDES := \
181
     ro.media.dec.jpeg.memcap=10000000
182
 
183
 PRODUCT_PROPERTY_OVERRIDES += \
184
-    rild.libpath=/system/lib/libhtc_ril.so \
185
+    rild.libpath=/system/lib/libreference-ril.so \
186
+    rild.libargs=-d/dev/smd0 \
187
     wifi.interface=tiwlan0
188 17 Denis 'GNUtoo' Carikli
 
189
 # Time between scans in seconds. Keep it high to minimize battery drain.
190
191
}}}
192
Note that full_dream_sapphire.mk is located here:
193
{{{
194 18 Denis 'GNUtoo' Carikli
device/htc/dream_sapphire/full_dream_sapphire.mk
195
}}}
196
The diff is self-explanatory and how to do the change is left as an exercise to the reader.
197 32 Michael Haas -
198 18 Denis 'GNUtoo' Carikli
In case the RIL need to be modified the sources are in :
199 19 Denis 'GNUtoo' Carikli
{{{
200
hardware/ril/reference-ril
201
}}}
202 21 Denis 'GNUtoo' Carikli
They are written in C.
203 19 Denis 'GNUtoo' Carikli
204 32 Michael Haas -
=== Audio libraries ===
205
On the HTC dream the audio libraries were modified.
206 19 Denis 'GNUtoo' Carikli
If your device is an msm7k "CPU" (in reality it's called a SOC, or system on a chip), it already contain the routing fix. Else I will analyse the following commit to give hints on how to modify an audio library:
207
{{{
208
commit e0b55a19b2fc004915503ebdfd7c4c02c4264611
209
Author: Denis 'GNUtoo' Carikli <GNUtoo@no-log.org>
210
Date:   Thu Dec 23 16:49:35 2010 +0100
211
212
    libaudio: AudioHardware: don't depend on the proprietary libhtc_acoustic.so for routing
213
    
214
    /system/lib/libhtc_acoustic.so is proprietary(and not redistributable),
215
      so we don't depend on it, but still we want audio routing
216
    
217
    This commit was inspired from a previous commit I made(for replicant 1.5):
218
      http://gitorious.org/replicant/msm7k/commit/6d13023d634e54814ecc74b22f77de27f1b8ac2c
219
    
220
    Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo@no-log.org>
221
222
diff --git a/libaudio/AudioHardware.cpp b/libaudio/AudioHardware.cpp
223
index 78b6a3e..af63e5a 100644
224
--- a/libaudio/AudioHardware.cpp
225
+++ b/libaudio/AudioHardware.cpp
226
@@ -43,6 +43,74 @@ const uint32_t AudioHardware::inputSamplingRates[] = {
227
         8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
228
 };
229
 // ----------------------------------------------------------------------------
230
+static int snd_get_endpoint(int cnt,msm_snd_endpoint * ept){
231
+     int fd;
232
+     int status;
233
+     fd = open("/dev/msm_snd",O_RDWR);
234
+     if (fd < 0) {
235
+	  LOGE("Cannot open msm_snd device");
236
+	  close(fd);
237
+	  return -1;
238
+     }
239
+     status = ioctl(fd,SND_GET_ENDPOINT, ept);
240
+     close(fd);
241
+     return status;
242
+}
243
+
244
+static int snd_get_num(){
245
+     int fd;
246
+     int status;
247
+     int mNumSndEndpoints;
248
+     fd = open("/dev/msm_snd",O_RDWR);
249
+     if (fd < 0) {
250
+	  LOGE("Cannot open msm_snd device");
251
+	  return -1;
252
+     }
253
+
254
+     if(ioctl(fd,SND_GET_NUM_ENDPOINTS,&mNumSndEndpoints)<0 ) {
255
+	  LOGE("get number of endpoints error");
256
+	  close(fd);
257
+	  return -1;
258
+     }
259
+     close(fd);
260
+     return mNumSndEndpoints;
261
+}
262
+
263
+static int msm72xx_enable_audpp (uint16_t enable_mask)
264
+{
265
+    int fd;
266
+
267
+
268
+    fd = open ("/dev/msm_pcm_ctl", O_RDWR);
269
+    if (fd < 0) {
270
+        LOGE ("Cannot open audio device");
271
+        return -1;
272
+    }
273
+
274
+    if (enable_mask & ADRC_ENABLE) {
275
+        enable_mask &= ~ADRC_ENABLE;
276
+    }
277
+    if (enable_mask & EQ_ENABLE) {
278
+        enable_mask &= ~EQ_ENABLE;
279
+    }
280
+    if (enable_mask & RX_IIR_ENABLE) {
281
+        enable_mask &= ~RX_IIR_ENABLE;
282
+    }
283
+
284
+    printf ("msm72xx_enable_audpp: 0x%04x", enable_mask);
285
+    if (ioctl (fd, AUDIO_ENABLE_AUDPP, &enable_mask) < 0) {
286
+	LOGE ("enable audpp error");
287
+	close (fd);
288
+	return -1;
289
+    }
290
+
291
+    close (fd);
292
+    return 0;
293
+}
294
+
295
+static int set_acoustic_parameters(){
296
+     return 0;
297
+}
298
 
299
 AudioHardware::AudioHardware() :
300
     mInit(false), mMicMute(true), mBluetoothNrec(true), mBluetoothId(0),
301
@@ -63,38 +131,10 @@ AudioHardware::AudioHardware() :
302
     SND_DEVICE_BT_EC_OFF(-1)
303
 {
304
 
305
-    int (*snd_get_num)();
306
-    int (*snd_get_endpoint)(int, msm_snd_endpoint *);
307
-    int (*set_acoustic_parameters)();
308
-
309
     struct msm_snd_endpoint *ept;
310
 
311
-    acoustic = ::dlopen("/system/lib/libhtc_acoustic.so", RTLD_NOW);
312
-    if (acoustic == NULL ) {
313
-        LOGE("Could not open libhtc_acoustic.so");
314
-        /* this is not really an error on non-htc devices... */
315
-        mNumSndEndpoints = 0;
316
-        mInit = true;
317
-        return;
318
-    }
319
-
320
-    set_acoustic_parameters = (int (*)(void))::dlsym(acoustic, "set_acoustic_parameters");
321
-    if ((*set_acoustic_parameters) == 0 ) {
322
-        LOGE("Could not open set_acoustic_parameters()");
323
-        return;
324
-    }
325
-
326
-    int rc = set_acoustic_parameters();
327
-    if (rc < 0) {
328
-        LOGE("Could not set acoustic parameters to share memory: %d", rc);
329
-//        return;
330
-    }
331
-
332
-    snd_get_num = (int (*)(void))::dlsym(acoustic, "snd_get_num_endpoints");
333
-    if ((*snd_get_num) == 0 ) {
334
-        LOGE("Could not open snd_get_num()");
335
-//        return;
336
-    }
337
+    LOGI("Not using the proprietary libhtc_acoustic library");
338
+    mInit = true;
339
 
340
     mNumSndEndpoints = snd_get_num();
341
     LOGD("mNumSndEndpoints = %d", mNumSndEndpoints);
342
@@ -102,11 +142,6 @@ AudioHardware::AudioHardware() :
343
     mInit = true;
344
     LOGV("constructed %d SND endpoints)", mNumSndEndpoints);
345
     ept = mSndEndpoints;
346
-    snd_get_endpoint = (int (*)(int, msm_snd_endpoint *))::dlsym(acoustic, "snd_get_endpoint");
347
-    if ((*snd_get_endpoint) == 0 ) {
348
-        LOGE("Could not open snd_get_endpoint()");
349
-        return;
350
-    }
351
 
352
     for (int cnt = 0; cnt < mNumSndEndpoints; cnt++, ept++) {
353
         ept->id = cnt;
354
@@ -488,17 +523,14 @@ status_t AudioHardware::doAudioRouteOrMute(uint32_t device)
355
                               mMode != AudioSystem::MODE_IN_CALL, mMicMute);
356 1 Denis 'GNUtoo' Carikli
 }
357
 
358 19 Denis 'GNUtoo' Carikli
+
359
+
360
 status_t AudioHardware::doRouting()
361
 {
362
-    /* currently this code doesn't work without the htc libacoustic */
363
-    if (!acoustic)
364
-        return 0;
365
 
366
     Mutex::Autolock lock(mLock);
367
     uint32_t outputDevices = mOutput->devices();
368
     status_t ret = NO_ERROR;
369
-    int (*msm72xx_enable_audpp)(int);
370
-    msm72xx_enable_audpp = (int (*)(int))::dlsym(acoustic, "msm72xx_enable_audpp");
371
     int audProcess = (ADRC_DISABLE | EQ_DISABLE | RX_IIR_DISABLE);
372
     AudioStreamInMSM72xx *input = getActiveInput_l();
373
     uint32_t inputDevice = (input == NULL) ? 0 : input->devices();
374
@@ -576,11 +608,7 @@ status_t AudioHardware::doRouting()
375
 
376
     if (sndDevice != -1 && sndDevice != mCurSndDevice) {
377
         ret = doAudioRouteOrMute(sndDevice);
378
-        if ((*msm72xx_enable_audpp) == 0 ) {
379
-            LOGE("Could not open msm72xx_enable_audpp()");
380
-        } else {
381
-            msm72xx_enable_audpp(audProcess);
382
-        }
383 30 Denis 'GNUtoo' Carikli
+        msm72xx_enable_audpp(audProcess);
384
         mCurSndDevice = sndDevice;
385
     }
386
}}}
387
Note several things:
388 22 Denis 'GNUtoo' Carikli
 * the routing was disabled, I had to re-enable it
389 28 Denis 'GNUtoo' Carikli
 * I had to replace some non-existant functions, for that I used public playwav2.c source code that the author released to us under the apache 2.0 license.
390
 * I had nearly no knowledge of C++
391 32 Michael Haas -
 * it was easy
392 28 Denis 'GNUtoo' Carikli
393 32 Michael Haas -
== Re-using source code ==
394
The previous source code re-used some public source code that was licensed under the Apache 2.0 license.
395 28 Denis 'GNUtoo' Carikli
The ril will also re-use some public source code licensed under Apache 2.0.
396
That is the advised way to do it as it save some time and is easier to do, however proper credit must be attributed, at least in the commit message.
397 22 Denis 'GNUtoo' Carikli
It is even advised to look at the public apache 2.0 source code of other rils libraries or components of android.
398
399 23 Denis 'GNUtoo' Carikli
=== Ril ===
400
 * vilvord ril
401
 * openmoko (android on freerunner) ril
402
403
== Source organization and commit access ==
404
Until now we made some changes in the tree, but we want the changes to land upstream in replicant.
405
For instance let's say we modified only the ril path like in the ril section in 
406
{{{
407 24 Denis 'GNUtoo' Carikli
device/htc/dream_sapphire/full_dream_sapphire.mk 
408
}}}
409
first we save our modifications:
410
{{{
411
cd device/htc/dream_sapphire/
412
git diff > git_diff.patch
413
}}}
414
then we find where is the root of the git repository we are in:
415 1 Denis 'GNUtoo' Carikli
{{{
416
cd replicant-2.2 #top replicant directory where everything is in
417 24 Denis 'GNUtoo' Carikli
cd .repo
418
cat manifest.xml
419
}}}
420
and we find that:
421
{{{
422
  <project path="device/htc/buzz" name="CyanogenMod/android_device_htc_buzz" remote="github" />
423
}}}
424
so...now our repository is in device/htc/buzz
425
We will now look where the source repository is:
426
{{{
427
cd device/htc/buzz
428
cd .git
429
cat config
430
}}}
431
We find that:
432
{{{
433
	url = git://github.com/CyanogenMod/android_device_htc_buzz.git
434
}}}
435
436 25 Denis 'GNUtoo' Carikli
Then create a directory, not under the replicant-2.2 directory that will contain your repositories:
437
{{{
438
mkdir repo
439
cd repo
440
}}}
441
and clone the source:
442
{{{
443
git clone git://github.com/CyanogenMod/android_device_htc_buzz.git
444
cd android_device_htc_buzz
445 26 Denis 'GNUtoo' Carikli
}}}
446
apply the previous patch:
447 27 Denis 'GNUtoo' Carikli
{{{
448 26 Denis 'GNUtoo' Carikli
git apply path/to/git_diff.patch
449
}}}
450
commit locally the result:
451
{{{
452
git commit -s
453
}}}
454 32 Michael Haas -
Note that the commit message should have the following format:
455
The first line should be a summary
456 1 Denis 'GNUtoo' Carikli
Followed by a linebreak
457 27 Denis 'GNUtoo' Carikli
And then the details explaining the commit
458
If you made an error writing the commit message do
459
{{{
460
git commit --amend
461
}}}
462 1 Denis 'GNUtoo' Carikli
463
TODO: complete for sending the git patch(git format-patch -1,git send-email)
464
465
==== Pushing to replicant ====
466
TODO: git remote add+git push