안녕하세요,
Android에서의 /system partition을 read-write로 mount하려고 하는데 잘 안되어서 이렇게 질문을 드립니다.
일단 사용하는 platform은 emulator이고요.
아래와 같이 해보았습니다.
Process p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes("mount -o rw remount /dev/block/mtdblock0 /system\n");
os.writeBytes("exit\n");
os.flush();
그리고는 # adb shell을 이용해서 emulator로 login을 해 보았는데, emulator에서 mount 명령을 실행해 보면 여전히 /system partion이 read-only로 mount된 것으로 보이네요.
무엇이 잘못된 것인지 조언 주시면 감사하겠습니다.
이번에는 조금 다른 질문인데요, 이미 read-write로 mount되어 있는 /data partition에 file을 생성하려고 시도해보았습니다.
아래와 같이 해보았는데요.
Process p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes("touch /data/zzz\n");
os.writeBytes("exit\n");
os.flush();
이번에도 # adb shell을 이용해서 emulator로 login을 해보았는데, /data 아래에 zzz라는 file이 생성이 되질 않아서요.
위와 같이 하면 file을 생성할 수 없는것인지,,질문 드립니다.
조언 주시면 감사하겠습니다.
그리고 아래에는 제가 사용하는 source code전체를 올립니다.
그럼,,조언 미리 감사드립니다. ~
// *****
package com.example.helloubuntu;
import java.io.DataOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloUbuntuActivity extends Activity {
/** Called when the activity is first created. */
private Boolean TryRootAccess()
{
Boolean bReturn = false;
try
{
Process p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes("mount -o rw remount /dev/block/mtdblock0 /system\n");
os.writeBytes("touch /system/bin/zzz\n");
os.writeBytes("/system/bin/touch /data/zzz\n");
os.writeBytes("exit\n");
os.flush();
}
catch(IOException e)
{
}
return bReturn;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
Boolean bRootAccess = TryRootAccess();
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView tv = new TextView(this);
tv.setText("Hello, Android Developer \n Thank you, for using Ubuntu Linux");
setContentView(tv);
}
}답변 감사드립니다, 말씀해 주신대로 rw, remount로 사이에 comma를 첨가 했는데, 결과는 동일합니다.
그리고, 역시 말씀해 주신대로 emulator에서 /system/bin아래에 su가 존재하지 않네요.
위의 code에서 su를 sh로 바꾸면 어떨까요?
sh로 바꾸어서 실행해 보았는데,,여전히 /system partition은 ro로 mount된 채로 변하지 않네요..
어떤걸 더 보면 좋을까요?
조언 주시면 감사하겠습니다.
에뮬레이터에서는 adb shell 로 들어가면 쉘이 루트권한을 갖지만, 앱에서 sh을 호출하면 루트권한이 없습니다. sh이 루트권한을 갖지 못하니 mount가 안될것으로 생각됩니다. su를 써서 해야하는게 맞을꺼구요,
알려진 방법으로 루팅된 기기가 있다면, 그 기기에서 테스트해보면 될꺼 같네요.
(혹은... 에뮬레이터를 루팅시켜서(;;;) su 바이너리와 superuser 앱을 에뮬레이터에 밀어넣고 테스트하면 되지 않을까...합니다. 에뮬레이터는 루팅시켜본적이 없어서 잘 될지 모르겠네요;;; 이미 루팅된 기기를 사용해볼 것을 추천드립니다.)
mount 명령이 올바른지는 adb shell에서 검증해보세요.
touch 정도는 sh 에서도 됩니다만, /data 디렉토리가 other에 쓰기권한이 없어서 파일 생성이 안될거라 생각합니다. /data 디렉토리에 파일 생성도 su를 이용해야할꺼 같군요.
다시 한번 조언 감사드립니다. ^^
제가 몇가지 더 시험을 해보았는데요.
제 환경에 대해서 일단 말씀을 드리면요,,
Hardware platform은 pandaboard이고 linaro에서 release된 Android 4.0.3을 사용하고 있습니다.
따라서, console을 통해서 login을 하면 언제든지 root권한을 획득할 수 있습니다.
Process p = Runtime.getRuntime().exec("sh");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes("touch /system/bin/zzz\n");
os.writeBytes("exit\n");
os.flush();위와 같이 실행을 해보았습니다.
그리고 /system/bin아래를 보니 zzz라는 file이 생성되지 않았습니다.
그 이유는 permission이 문제였던 것 같습니다.
위의 code를 실행시키는 app은 app_44라는 user의 소유로 되어 있네요.
그리고 /system과 /system/bin directory는 오직 root만이 write 가능하게 되어 있었고요.
아참..그리고 이전에 Android ramdisk를 수정해서 /system partition은 read-write로 mount되도록 고쳤고, 실제로도 read-write partition으로 mount되었습니다.
그래서, 다시 위로 돌아가면요.
이제는 /system과 /system/bin directory의 permission을 777로 수정했습니다.
물론 이건 serial console로 접속한 후에 root권한을 가지고 변경했습니다.
이렇게 변경하고 위의 code를 다시 수행하니 zzz라는 file이 /system/bin아래에 생성되네요 !
이번에는 아래의 code를 실행시켰습니다.
환경은 위와 같이 수정한대로 동일한 환경이었고요.
Process p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes("touch /system/bin/zzz\n");
os.writeBytes("exit\n");
os.flush();하지만, 이렇게 고쳐서 실행을 하니 이번에는 zzz라는 file 생성이 되지 않네요.
제 짧은 생각으로는 Process p = Runtime.getRuntime().exec("sh"); 로는 shell process가 java program 내에서 생성이 되어서 os.writeBytes()를 통해서 전달이 되는 command들이 수행이 되는 것이고,
또 Process p = Runtime.getRuntime().exec("su"); 로는 root 권한을 가지는 process가 생성이 되어서 os.writeBytes()를 통해서 전달이 되는 command들이 수행되는 거라고 이해를 했었는데요.
그렇다면 왜 두번째 시도에서 zzz라는 file이 생성이 되지 않는 것인지가 궁금합니다.
혹시 뭔가 빠진 절차가 있는걸까요?
조언 미리 감사드립니다.
점점 제가 아는 만큼의 범위를 벗어나는것 같군요^^;
전 폰 위에서 AOSP 소스로만 작업해봐서, 개발보드로 가면 아는게 별로 없어 도움이 될지 모르겠습니다^^;
일단 sh 과 su 에 대해서는 저도 같은 생각입니다. 또 예전에 루팅된 NexusOne에서 위의 소스코드와 동일한 방법으로 "/" 디렉토리를 리마운트해서 디렉토리와 심볼릭 링크를 생성한 경험도 있구요.
처음엔 다시 한 번 su의 존재를 의심했었습니다만, 말씀하신 환경의 이미지를 http://releases.linaro.org/12.03/android/leb-panda/ 에서 받아보니 /system/xbin/su 가 있더군요.
그럼 http://android-dls.com/wiki/index.php?title=Magic_Root_Access 에서 얘기하는 "In Android 1.5, the su utility was updated to allow only the shell and root users to gain root access" 와 유사한 원인이 아닌가 생각됩니다. 저 말대로라면 app_44 유저는 su 를 이용하더라도 루트권한을 받지 못할꺼 같습니다(그래서 위 링크에서는 su 를 수정한 버전을 배포하고 있습니다. 아마 저기서 배포하는 su 바이너리가 보통 루팅 툴킷에 포함된 녀석이 아닌가 싶네요). 안드로이드 버전 차이가 매우 큽니다만, su 는 안드로이드 공식 바이너리가 아니라서, 이미지 만들 때 어떤 su 바이너리를 가져다 추가했는지 알 수 없다는게 제 생각입니다. 물론 다른 원인이 있을수도 있구요.
저라면 su 바이너리를 교체해서 다시 시도해보구요, 그래도 안된다면 linaro 측에 문의해볼 것 같습니다. 아무래도 시스템 이미지를 직접 생성한것도 그 쪽이니 더 자세한 내용을 알고 있겠죠^^




2. 에뮬레이터에 su 가 존재하는지 의심스럽습니다. 에뮬레이터에는 su가 없던걸로 기억합니다. su의 존재여부도 확인해보시기 바랍니다(직접 확인하고 댓글을 달아야 마땅하나, 확인할 사정이 못되서... 양해바랍니다).