달력

52024  이전 다음

  • 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





Posted by neodelicious
|


ion.c


        case ION_IOC_SHARE:
        case ION_IOC_MAP:
        {
                struct ion_handle *handle;

                handle = ion_handle_get_by_id(client, data.handle.handle);
                if (IS_ERR(handle))
                        return PTR_ERR(handle);
                data.fd.fd = ion_share_dma_buf_fd(client, handle);

Kernel ion driver 에서 ION_IOC_SHARE 와 ION_IOC_MAP 은 동일한 logic 이다.


int ion_map(int fd, ion_user_handle_t handle, size_t length, int prot,
            int flags, off_t offset, unsigned char **ptr, int *map_fd)
...
    ret = ion_ioctl(fd, ION_IOC_MAP, &data);
...
    tmp_ptr = mmap(NULL, length, prot, flags, data.fd, offset);

그런데 Android libion 의 ion_map 은 ION_IOC_MAP 이후 mmap 과정을 추가로 수행한다.

이때 전달받은 length 크기만큼 prot 권한으로 mmap 한다.


int ion_share(int fd, ion_user_handle_t handle, int *share_fd)
...
    ret = ion_ioctl(fd, ION_IOC_SHARE, &data);

Android libion 의 ion_share 는 ION_IOC_MAP 과 kernel 내에서 동일한  ION_IOC_SHARE 만 수행하고, mmap 과정이 없다. 단순히 share 만을 위한 목적으로 보인다.


int ion_import(int fd, int share_fd, ion_user_handle_t *handle)
...
    ret = ion_ioctl(fd, ION_IOC_IMPORT, &data);

ION_IOC_MAP 혹은 ION_IOC_SHARE 를 통해 확보한 fd 를 통해 ion buffer handle 에 대한 handle id 를 확보한다.



fd 는 task 별로 관리되는 자료구조로서 현재 task 에서만 의미 있는 값이다. 그런데 binder driver 를 통하면 from_proc task 의 fd 에 연결된 file 을 target task 에 연결한다.




/*
 * copied from fd_install
 */             
static void task_fd_install(
        struct binder_proc *proc, unsigned int fd, struct file *file)
{
        if (proc->files)
                __fd_install(proc->files, fd, file);
}

v4.4 drivers/android/binder.c 기준으로 위와 같이 task_fd_install 부분이 이 기능을 하는 것으로 보인다.




참고 자료


Posted by neodelicious
|


I wanted to know how to set up repo based source tree.

As you know, Repo is just a wrapper of several git repositories.
To manage those repositories, repo uses a configuration file named of default.xml.

To set up repo based source tree, you need to understand the format of default.xml.
I could learn it easily from following URLs

http://repo.or.cz/w/git-repo.git/blob_plain/a949fa5d202f0a1f812d7630f3e5bf0f02ca4e98:/docs/manifest_xml.txt
http://www.omappedia.org/wiki/Android_Miscellaneous

I want to say these.
- Like normal git, default.xml can set up several remote Repo and set one of them as default.
- each git can be retrieved from different remote Repo and either follows a branch or can be stuck on a specific commit.

If you want you can refer to below too.

git://android.git.kernel.org/platform/manifest.git
git://codeaurora.org/platform/manifest.git
http://gitorious.org/android-eeepc/manifest/blobs/master/default.xml
https://github.com/CyanogenMod/android/blob/gingerbread/default.xml

I attached my work to share.
I hope it helps you out.

Posted by neodelicious
|
android source 를 좀 보려고 repo init 을 했는데 아래와 같이 안 되었다.

$ repo init -u git://android.git.kernel.org/platform/manifest.git
Getting repo ...
   from git://android.git.kernel.org/tools/repo.git
fatal: Unable to look up android.git.kernel.org (port 9418) (Name or service not known)

DNS 혹은 Port 문제인가 싶어서 이것 저것 다 확인하고 바꿔봤는데,
결론은 Android repo 의 git server 가 hacking 당해서 동작 안 한다는 것... 덜덜;;

http://php.webtutor.pl/en/2011/09/05/kernel-org-hacked-how-to-get-android-repo/
위 URL 에서 관련 사실을 확인했고 방법도 참고했는데, 9/5 날짜이니 나름 최근인가 보다.

위 URL 에서는 아래와 같이 다른 곳에서 repo 를 받으라고 되어 있다.
curl "http://php.webtutor.pl/en/wp-content/uploads/2011/09/repo" > ~/bin/repo
chmod a+x ~/bin/repo
사족인데 혹시나 해서 받은 repo 를 봤더니 역시 repo 의 default git URL 을 수정해 놓은 repo 였다. 위에서 받은 repo 를 사용하면 되는데, 굳이 이전에 받은 repo 를 사용하고자 한다면  --repo-url 옵션을 통해 repo 에 repo git URL 을 argument 로 전달하면 된다.

그리고 android platform 의 git server 도 hacking 당했는지 안 되는데 위 URL 에서 알려주듯이 아래와 같이 변경해서 받을 수 있다.

repo init -u git://codeaurora.org/platform/manifest.git -b gingerbread

알겠지만 repo init 끝에 -b gingerbread 는 gingerbread branch 를 받는 것으로 원하면 생략하거나 다른 branch 값을 쓰면 된다.

참고적으로 android kernel 을 받으려면 repo project 를 통해서 받을 수도 있지만,
android kernel 의 git server 에서 다음과 같이 바로 git clone 할 수 있다.
$ git clone git://android.git.kernel.org/kernel/common.git kernel

그런데 현재 kernel 또한 server 에 문제가 있어 위의 대체 URL 을 이용해서 받을 수 있다.
$ git clone git://codeaurora.org/kernel/common.git kernel
Posted by neodelicious
|
=========================================================
11.10.02 수정 사항 - git 관련 정리 파일 수정하여 파일 첨부

=========================================================

Android Source 를 받을 때 repo 를 알게 되었고,
Android Source 를 받을 때만 repo 를 써 봤다.
다른 Source 관리에도 repo 를 쓰면 좋을 것 같은데 어떻게 해야 할까?

아직은 잘 모르겠지만 만약 myrepo_remote 라는 directory 에
repo 형식의 repo server 가 설정되어 있을 것이다.

$ mkdir myrepo_remote
$ cd myrepo_remote

그리고 myrepo_local 이라는 directory 를 만든다.

$ mkdir myrepo_local

위 repo server 에서 source 를 download 하려면
우선 repo 설정을 아래와 같이 할 것이다.
아라? 그런데 뭔가 android server 에서 download 한다.

myrepo_local$ repo init -u ../myrepo_remote/
Getting repo ...
   from git://android.git.kernel.org/tools/repo.git
remote: Counting objects: 1309, done.
remote: Compressing objects: 100% (570/570), done.
remote: Total 1309 (delta 843), reused 1148 (delta 716)
Receiving objects: 100% (1309/1309), 357.92 KiB | 141 KiB/s, done.
Resolving deltas: 100% (843/843), done.
From git://android.git.kernel.org/tools/repo
 * [new branch]      maint      -> origin/maint
 * [new branch]      master     -> origin/master
 * [new branch]      stable     -> origin/stable
 * [new tag]         v1.7.5     -> v1.7.5
From git://android.git.kernel.org/tools/repo
 * [new tag]         v1.0       -> v1.0
 * [new tag]         v1.0.1     -> v1.0.1
(생략)
 * [new tag]         v1.7.4.3   -> v1.7.4.3
Getting manifest ...
   from ../myrepo_remote/
fatal: '../myrepo_remote' does not appear to be a git repository
fatal: The remote end hung up unexpectedly
fatal: cannot obtain manifest ../myrepo_remote/

마지막에 myrepo_remote directory 에 repo 설정이 안 되어 있어서 error 가 발생하지만,
.repo directory 가 생성되고, .repo/repo 에도 뭔가 잔뜩 만들어졌다.

myrepo_local$ ls -l .repo/
total 4
drwxr-xr-x 7 jaewon jaewon 4096 2011-08-15 10:51 repo

파일 확장자를 보니 파이썬 스크립트이고,
repo  관련 명령어를 처리해 주는 기능을 하는 것 같다.
그런데 .git directory 가 있는 것을 보니 Git 로 관리하는 것 같다.

myrepo_local$ ls -al .repo/repo/
total 380
drwxr-xr-x 7 jaewon jaewon  4096 2011-08-15 10:51 .
drwxr-xr-x 3 jaewon jaewon  4096 2011-08-15 10:51 ..
-rw-r--r-- 1 jaewon jaewon  3602 2011-08-15 10:51 color.py
-rw-r--r-- 1 jaewon jaewon  5239 2011-08-15 10:51 color.pyc
-rw-r--r-- 1 jaewon jaewon  3426 2011-08-15 10:51 command.py
-rw-r--r-- 1 jaewon jaewon  4625 2011-08-15 10:51 command.pyc
(생략)
drwxr-xr-x 8 jaewon jaewon  4096 2011-08-15 10:51 .git
(생략)

Git 안을 좀 들여다 보자.
local 에 remote/origin/stable 을 upstream 으로 하는 default branch 가 있다.

myrepo_local$ cd .repo/repo/
myrepo_local/.repo/repo$ git branch -avv
* default               30d4529 [origin/stable] Add a --depth option to repo init.
  remotes/origin/maint  08c880d Smart tag support
  remotes/origin/master e7a3bcb Merge branch 'stable'
  remotes/origin/stable 30d4529 Add a --depth option to repo init.

myrepo_local/.repo/repo$ cat .git/config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = git://android.git.kernel.org/tools/repo.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "default"]
    remote = origin
    merge = refs/heads/stable

그럼 이런 Git 로 관리하는 repo 관련 파일들을
/usr/bin/repo 실행 한 번으로 모두 받은 것이다.
이쯤에서 궁금해진다.
repo 안에 Git 관련 설정은 어떻게 되어 있을까?

결론부터 얘기해서,
repo script 를 분석해서 Git 관련 부분만 모아보면 아래와 같았다.
참고적으로 mimic_repo_init.sh 라는 파일로 만들어서 테스트할 수 있다.

mkdir -p .repo_test/repo
cd .repo_test/repo

echo 'Getting repo ...'
echo '   from git://android.git.kernel.org/tools/repo.git'

git init --quiet
git config remote.origin.url git://android.git.kernel.org/tools/repo.git
git config remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
git fetch origin
git fetch --tags origin
cur=`git describe origin/stable`
#git tag -v $cur
rev="$cur^0"
# current rev is v1.7.5^0
git update-ref refs/heads/default $rev
git config branch.default.remote origin
git config branch.default.merge refs/heads/stable
git symbolic-ref HEAD refs/heads/default
git read-tree --reset -u HEAD

위 과정을 진행하고,
repo init 한 것과 비교해 봤는데
repo init 에서 파이썬 스크립트가 더 있기는 했지만
Git 관련 파일은 거의 같다고 할 수 있었다.

myrepo_local$ repo init -u ../myrepo_remote
myrepo_local$ ./mimic_repo_init.sh
myrepo_local$ diff -qr .repo .repo_testOnly in .repo/repo: color.pyc
Only in .repo/repo: command.pyc
Only in .repo/repo: editor.pyc
Only in .repo/repo: error.pyc
Files .repo/repo/.git/index and .repo_test/repo/.git/index differ
Files .repo/repo/.git/logs/refs/heads/default and .repo_test/repo/.git/logs/refs/heads/default differ
Files .repo/repo/.git/logs/refs/remotes/origin/maint and .repo_test/repo/.git/logs/refs/remotes/origin/maint differ
Files .repo/repo/.git/logs/refs/remotes/origin/master and .repo_test/repo/.git/logs/refs/remotes/origin/master differ
Files .repo/repo/.git/logs/refs/remotes/origin/stable and .repo_test/repo/.git/logs/refs/remotes/origin/stable differ
Only in .repo/repo: git_command.pyc
Only in .repo/repo: git_config.pyc
Only in .repo/repo: git_refs.pyc
(생략)

끝으로 repo 를 다 분석하지는 못 했는데,
위 Git command 를 알아내는데 확인했던 부분 코드를 분석 없이 덧붙인다.


Posted by neodelicious
|
Android 에서는 Git 를 내부적으로 사용하면서 Repo 를 Wrapper 로 이용한다.
.repo 안에 어떻게 되어 있는 건지 궁금해서 들여다 봤다.
앞으로 더 봐야겠지만 오늘 분석한 것을 정리한다.

<download>
Android Source 전체를 받을 필요는 없고, repo sync 까지만 해서 .repo 안에 구조를 본다.

mkdir mydroid
cd mydroid/
repo init -u git://android.git.kernel.org/platform/manifest.git

<.repo>
.repo 안에 repo command 를 구현한 repo directory 가 있고,
.repo 내 프로젝트 설정 정보를 담고 있는 manifest.xml 파일이 있다.
그런데 manifest.xml 는 symbolic link 이고 실제 파일은 manifest directory 에 있는 default.xml 이다.

$ tree -L 1 .repo
.repo
|-- manifests
|-- manifests.git
|-- manifest.xml -> manifests/default.xml
`-- repo

그런데 manifest.git 는 어떤 directory 인지 궁금했는데,
manifest.xml 을 git 로 관리하는 것이다.

참고적으로 repo sync 를 통해 Source 를 받고 나니,
project 에 대한 정보가 있는 파일이 더 생겼다.
이 부분은 나중에 확인해 봐야겠다.

// would be like this after repo sync
$ tree -L 1 .repo/
.repo/
|-- manifests
|-- manifests.git
|-- manifest.xml -> manifests/default.xml
|-- project.list
|-- projects
`-- repo

<manifests VS manifests.git>
directory가 두 개가 있는데 왜 두 개인지 궁금했다.

안을 들여다 보기 전에 우선 용량부터 확인했더니,
둘 다 용량이 작은데, manifests 가 훨씬 작았다.

$ du -sh .repo/manifests
104K    .repo/manifests
$ du -sh .repo/manifests.git/
1.4M    .repo/manifests.git/

ls 로 파일을 보니, manifests 에는 파일이 몇 개 있고,
.git 가 있는 것을 보니 Git 로 관리하고 있는 것으로 보인다.

$ ls -l .repo/manifests
total 100
drwxr-xr-x 3 jaewon jaewon  4096 2011-07-29 20:48 .
drwxr-xr-x 6 jaewon jaewon  4096 2011-08-13 22:46 ..
-rw-r--r-- 1 jaewon jaewon 21776 2011-07-29 20:46 3.0-base.xml
-rw-r--r-- 1 jaewon jaewon 22340 2011-07-29 20:46 3.1-base.xml
-rw-r--r-- 1 jaewon jaewon 23240 2011-07-29 20:46 3.2-base.xml
-rw-r--r-- 1 jaewon jaewon 14378 2011-07-29 20:46 default.xml
drwxr-xr-x 2 jaewon jaewon  4096 2011-08-13 22:21 .git

그런데 .git 안을 보니 주요 파일들이 Symbolic Link 일 뿐 실제 파일이 아니고,
manifest.git 에 있는 것이 실제 파일이다.
심지어 packed-refs 와 svn 는 target 이 없는 broken link 이다.

$ ls -l .repo/manifests/.git/
total 8
lrwxrwxrwx 1 jaewon jaewon  26 2011-08-13 23:10 config -> ../../manifests.git/config
lrwxrwxrwx 1 jaewon jaewon  31 2011-08-13 23:10 description -> ../../manifests.git/description
-rw-r--r-- 1 jaewon jaewon  24 2011-08-13 23:10 HEAD
lrwxrwxrwx 1 jaewon jaewon  25 2011-08-13 23:10 hooks -> ../../manifests.git/hooks
-rw-r--r-- 1 jaewon jaewon 385 2011-08-13 23:10 index
lrwxrwxrwx 1 jaewon jaewon  24 2011-08-13 23:10 info -> ../../manifests.git/info
lrwxrwxrwx 1 jaewon jaewon  24 2011-08-13 23:10 logs -> ../../manifests.git/logs
lrwxrwxrwx 1 jaewon jaewon  27 2011-08-13 23:10 objects -> ../../manifests.git/objects
lrwxrwxrwx 1 jaewon jaewon  31 2011-08-13 23:10 packed-refs -> ../../manifests.git/packed-refs
lrwxrwxrwx 1 jaewon jaewon  24 2011-08-13 23:10 refs -> ../../manifests.git/refs
lrwxrwxrwx 1 jaewon jaewon  28 2011-08-13 23:10 rr-cache -> ../../manifests.git/rr-cache
lrwxrwxrwx 1 jaewon jaewon  23 2011-08-13 23:10 svn -> ../../manifests.git/svn

당연하겠지만 그래서 .git 가 차지하는 용량도 무척 작다.

$ du -sh .repo/manifests/.git/
12K    .repo/manifests/.git/

Symbolic Link 라서 이건 껍데기려니 하고,
그냥 diff 로 차이가 있는 파일을 봤다.
다른 건 그럭저럭 눈에 안 뜨이는데 HEAD 파일이 다르다는 것이 이상하다.

$ diff -qr .repo/manifests/.git .repo/manifests.git
Only in .repo/manifests.git: branches
Only in .repo/manifests.git: FETCH_HEAD
Files .repo/manifests/.git/HEAD and .repo/manifests.git/HEAD differ
Only in .repo/manifests/.git: index
Only in .repo/manifests/.git: packed-refs
Only in .repo/manifests.git: .repopickle_config
Only in .repo/manifests/.git: svn

<manifest>
manifest directory 를 좀 더 들여다 봤다.

$ cd .repo/manifests

config 파일을 열어 환경 설정을 보니,
origin remote 와 default branch 를 가진 일반적인 형태다.
다른 파일들이 Symbolic Link 이지만 config 파일은 mainifest.git 의 config 와 같은 내용이었다.

.repo/manifests$ cat .git/config
[core]
    repositoryformatversion = 0
    filemode = true
[remote "origin"]
    url = git://android.git.kernel.org/platform/manifest.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "default"]
    remote = origin
    merge = refs/heads/master

본 김에 HEAD commit 을 봤다.
Log Message 를 보니 새 project 를 만들었나 보다.

.repo/manifests$ git log --oneline HEAD^!
dc01e28 Add new projects

예상대로 HEAD 는 정상적으로 heads/default 즉 local default branch 를 의미했다.

.repo/manifests$ cat .git/HEAD
ref: refs/heads/default

remote branch 를 포함해서 전체 branch 를 보니,
default 는 origin/master 즉 origin remote 에서 master branch 를 upstream 으로 하고 있다.
그밖에 Android 각 version 별로 branch 를 따로 만들어서 사용했던 것 같다.
내부적으로 최신 version 으로 merge 했을 것 같지만.

.repo/manifests$ git branch -avv
* default                                  dc01e28 [origin/master] Add new projects
  remotes/origin/android-1.5               1b4d95f fixed duplicate entry
  remotes/origin/android-1.5r2             2de7a11 Manifest for 1.5r2
  (생략)
  remotes/origin/master                    dc01e28 Add new projects
  (생략)

<manifest.git>
그럼 manifest.git directory 는 어떻게 되어 있을까?

$ cd .repo/manifests.git/

branch 정보를 봤는데, manifest 와 같은 것 같다.
아라? 그런데 local default branch 에 현재 branch 를 가리키는 * 가 없다.
HEAD 값이 어떻게 되어 있길래?

.repo/manifests.git$ git branch -avv
  default                                  dc01e28 [origin/master] Add new projects
  remotes/origin/android-1.5               1b4d95f fixed duplicate entry
  remotes/origin/android-1.5r2             2de7a11 Manifest for 1.5r2
  ...
  remotes/origin/master                    dc01e28 Add new projects
  ...

우선 config 를 봤다.
특별한 사항은 없다.

.repo/manifests.git$ cat config
[core]
    repositoryformatversion = 0
    filemode = true
[remote "origin"]
    url = git://android.git.kernel.org/platform/manifest.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "default"]
    remote = origin
    merge = refs/heads/master

그럼 HEAD 는 어떻게 되어 있을까?
default branch 가 아니라 master branch 로 되어 있다!!!
왜 이렇게 해 놨을까??

.repo/manifests.git$ cat HEAD
ref: refs/heads/master

heads 즉 local branch 중에 master 는 없는데 말이다.

.repo/manifests.git$ ls refs/heads/
default

이렇게 HEAD가 잘못 되어 있으니까,
git log 와 같은 것도 안 되는 것이 당연하다.

.repo/manifests.git$ git log
fatal: bad default revision 'HEAD'

테스트용으로 master ref 를 만들어본다면,
git log 가 잘 된다.
manifest.git 내에서 git command 를 하지 못 하도록 일부러 막았을지도 모르겠다.

.repo/manifests.git$ cp refs/heads/default refs/heads/master
.repo/manifests.git$ git log --oneline HEAD^!
dc01e28 Add new projects
.repo/manifests.git$ git branch -vv
  default dc01e28 [origin/master] Add new projects
* master  dc01e28 Add new projects
.repo/manifests.git$ rm refs/heads/master


Posted by neodelicious
|
android 내부를 좀 공부하려고 source를 받으려고 했는데, 다 받으려면 시간이 너무 오래 걸린다. 그래서 이번에는 framework direcotry만 받아봤다.

repo 가 없으면 우선  repo 부터 받는다.
curl http://android.git.kernel.org/repo > ./repo
chmod a+x ./repo

디렉토리를 하나 만들고 repo를 이용해서 repository 정보를 가져온다.
mkdir android.repo
cd android.repo
../repo init -u git://android.git.kernel.org/platform/manifest.git

프로젝트 이름 없이 repo sync 를 하면 모든 프로젝트 소스를 다운로드 하는데, 나는 framewors/base 만 받고자 한다. 이게 사실 core 이고 다른 것까지 받으면 시간이 너무 오래 걸린다. 물론 build를 하려면 전체 다 받아야 한다.
../repo sync frameworks/base

프로젝트 이름은 project.list 파일에서 알 수 있다.
cat .repo/project.list
참고적으로 frameworks/base 는 git로 관리하고 있다. 그런데 .git 에 DB에 전체 소스까지 담고 있는데, 330MB를 1.4MB 로 담고 있다니... 덜덜...

$ du -sh ./frameworks/base/
336M    ./frameworks/base/
$ du -sh ./frameworks/base/.git/
1.4M    ./frameworks/base/.git/


Posted by neodelicious
|