spi flash不是直接access到spi flash, 而是透過mtd再往下
MTD
------------------------
SPI NOR framework
------------------------
m25p80
------------------------
SPI bus driver
------------------------
SPI NOR chip
在i.mx cpu下的架構會略有不同
MTD
------------------------
SPI NOR framework
------------------------
fsl-quadSPI
------------------------
SPI NOR chip
但是從log來看fsl-quadSPI還是有用到m25p80這隻driver
m25p80目前看來可以通用在所有的spi nor flash, 要新增只要把id相關瑱入table中就好
目前spi nor flash不透過spidev這個device來access, 所以不需要掛spidev在spi device下.
spidev目前看來是直接access spi device的, 如果有需要透過spidev直接control device才需加入device tree
http://blog.5ibc.net/p/14266.html
2017年9月20日 星期三
2017年9月8日 星期五
git branch have diverged
============ 當 Conflict when git pull =====================
如果 git pull 時發現有 Conflict, 但你又明明沒有加入任何 commit,
有可能是因為原來的 branch 已經走到分支出去了,
你可以打入 git status
如果 git pull 時發現有 Conflict, 但你又明明沒有加入任何 commit,
有可能是因為原來的 branch 已經走到分支出去了,
你可以打入 git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 32 and 83 different commit(s) each, respectively.
#
第一個數字 32 代表著你比 origin/master 多了 32 個 patch,
第二個數字 83 代表著你比 origin/master 少了 83 個 patch
如果你很有興趣知道是那一些可以利用 git cherry origin/master 來看
1. 執行 git reset --hard HEAD^ 一直到你可以做 fast-forwarded
2. 直接執行 git pull --rebase origin/master
http://pjack1981.blogspot.tw/2012/03/git.html
https://github.com/zlargon/git-tutorial/blob/master/remote/sync.md
2017年7月24日 星期一
Android propery
Android property 與BIOS的variable感覺相當類似, 都是可以作為一些變數往後傳遞.
但是property更簡單的是因為他是用檔案形式, 所以要驗證的時候開檔案來看就好.
property service是在init.c當中啟動.
1)间接调用__system_property_area_init():打开属性共享内存,并记入__system_property_area变量;
2)间接调用init_workspace():只读打开属性共享内存,并记入环境变量;
3)根据init.rc,异步激发property_service_init_action(),该函数中会:
l 加载若干属性文本文件,将具体属性、属性值记入属性共享内存;
l 创建并监听socket;
4)根据init.rc,异步激发queue_property_triggers_action(),将刚刚加载的属性对应的激发动作,推入action列表。
接著則是在init.rc中會看到一段
on load_all_props_action
load_all_props
這邊其實才會真正的load file system中的properties
從keywords.h中可以看到
KEYWORD(load_all_props, COMMAND, 0, do_load_all_props)
但是property更簡單的是因為他是用檔案形式, 所以要驗證的時候開檔案來看就好.
property service是在init.c當中啟動.
1)间接调用__system_property_area_init():打开属性共享内存,并记入__system_property_area变量;
2)间接调用init_workspace():只读打开属性共享内存,并记入环境变量;
3)根据init.rc,异步激发property_service_init_action(),该函数中会:
l 加载若干属性文本文件,将具体属性、属性值记入属性共享内存;
l 创建并监听socket;
4)根据init.rc,异步激发queue_property_triggers_action(),将刚刚加载的属性对应的激发动作,推入action列表。
接著則是在init.rc中會看到一段
on load_all_props_action
load_all_props
這邊其實才會真正的load file system中的properties
從keywords.h中可以看到
KEYWORD(load_all_props, COMMAND, 0, do_load_all_props)
所以去看在do_load_all_props在property_service.c中
load_properties_from_file(PROP_PATH_SYSTEM_BUILD, NULL);
load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT, NULL);
load_properties_from_file(PROP_PATH_VENDOR_BUILD, NULL);
load_properties_from_file(PROP_PATH_FACTORY, "ro.*");
這邊就會實際的去抓file system中的property files.
有個需注意的部份是在這邊的property_set中會將ro.開頭的property set都擋掉
if(!strncmp(name, "ro.", 3)) return -1;
所以若是在跑到load_all_props之前都還可以set ro.開頭的property, 但是在load_all_props之後ro.xxx就真的變成read only的property了.
參考資料:
Android wifi related
Android 5.1.1
1. Android 網路連線機制並不允許同時有兩個device連外, Ethernet > wifi > mobile network. 會有一個評分機制在連線時決定哪個interface可以連線, 其他的連線則會被斷掉. 但是如果在user space使用command方式連線, 是可以看到一個以上的interface 拿到ip, 但是推測從android端連線出去時, 仍只會從priority高的device連出去.
frameworks/base/services/Java/com/android/server/ConnectivityService.java 將以下選項打開
private static final boolean DBG = true;
private static final boolean VDBG = true;
private static final boolean LOGD_RULES = true;
在log中就可以看到相關評分以及切換網路的動作, 可再往下追code.
參考以下網站將相關的code mark掉的話, 先連上wifi 再接上ethernet, 那wifi並不會強制斷線.但是若先接ethernet再接wifi, 那wifi也還是無法連上, 因為這邊只能將已連上的連線不斷線, 並不能搶走舊的連線.
https://stackoverflow.com/questions/37715525/use-multiple-network-interfaces-in-an-app
https://github.com/CyanogenMod/android_frameworks_base/blob/e49d5ea0858a765c22d8aa96cc660d4708a413fb/services/core/java/com/android/server/ConnectivityService.java#L4264
評分機制ethernet固定是150, wifi則根據RSSI來決定分數, 最高不超過100. 若兩者同分, 則以先連線的interface為主.
通過ConnectivityService之後, 如果是wifi連線, 接著會到WifiStatemachine
wifi state machine就會在各個state中切換, 來完成連線的各個動作, 這部份尚待研究.
接著往下會到JNI部份 frameworks/base/core/jni/android_net_wifi_Wifi.cpp
再往下就到wifi hardware部份 hardware/libhardware_legacy/wifi/wifi.c
在wifi.c時會根據傳入的參數來知道是要sta mode, ap mode or p2p mode. 根據知道是什麼mode之後會去reload相對應的fw.
以下是別人寫的ap mode啟動流程.
Setting->WifiManger->WifiService->WifiController->NetworkManagementService(wifiFirmwareReload)->NativeDaemonConnector(execute)->CommandListener->SoftapController(fwReloadSoftap)->wifi_get_fw_path
接著則會根據是什麼mode來決定要使用什麼tool以及讀取或create相關的conf檔案.
如果是sta mode的話, 就使用wpa_supplicant, ap mode則使用hostapd.
參考資料:
http://blog.csdn.net/kangear/article/details/14446527
http://blog.csdn.net/u010961631/article/details/48629601
http://blog.csdn.net/tankai19880619/article/details/42146287
http://blog.csdn.net/myarrow/article/details/8129607
http://blog.csdn.net/xusiwei1236/article/details/48495485
http://blog.sina.com.cn/s/blog_67e1c5cc0101ttqd.html
1. Android 網路連線機制並不允許同時有兩個device連外, Ethernet > wifi > mobile network. 會有一個評分機制在連線時決定哪個interface可以連線, 其他的連線則會被斷掉. 但是如果在user space使用command方式連線, 是可以看到一個以上的interface 拿到ip, 但是推測從android端連線出去時, 仍只會從priority高的device連出去.
frameworks/base/services/Java/com/android/server/ConnectivityService.java 將以下選項打開
private static final boolean DBG = true;
private static final boolean VDBG = true;
private static final boolean LOGD_RULES = true;
在log中就可以看到相關評分以及切換網路的動作, 可再往下追code.
參考以下網站將相關的code mark掉的話, 先連上wifi 再接上ethernet, 那wifi並不會強制斷線.但是若先接ethernet再接wifi, 那wifi也還是無法連上, 因為這邊只能將已連上的連線不斷線, 並不能搶走舊的連線.
https://stackoverflow.com/questions/37715525/use-multiple-network-interfaces-in-an-app
https://github.com/CyanogenMod/android_frameworks_base/blob/e49d5ea0858a765c22d8aa96cc660d4708a413fb/services/core/java/com/android/server/ConnectivityService.java#L4264
評分機制ethernet固定是150, wifi則根據RSSI來決定分數, 最高不超過100. 若兩者同分, 則以先連線的interface為主.
通過ConnectivityService之後, 如果是wifi連線, 接著會到WifiStatemachine
wifi state machine就會在各個state中切換, 來完成連線的各個動作, 這部份尚待研究.
接著往下會到JNI部份 frameworks/base/core/jni/android_net_wifi_Wifi.cpp
再往下就到wifi hardware部份 hardware/libhardware_legacy/wifi/wifi.c
在wifi.c時會根據傳入的參數來知道是要sta mode, ap mode or p2p mode. 根據知道是什麼mode之後會去reload相對應的fw.
以下是別人寫的ap mode啟動流程.
Setting->WifiManger->WifiService->WifiController->NetworkManagementService(wifiFirmwareReload)->NativeDaemonConnector(execute)->CommandListener->SoftapController(fwReloadSoftap)->wifi_get_fw_path
接著則會根據是什麼mode來決定要使用什麼tool以及讀取或create相關的conf檔案.
如果是sta mode的話, 就使用wpa_supplicant, ap mode則使用hostapd.
參考資料:
http://blog.csdn.net/kangear/article/details/14446527
http://blog.csdn.net/u010961631/article/details/48629601
http://blog.csdn.net/tankai19880619/article/details/42146287
http://blog.csdn.net/myarrow/article/details/8129607
http://blog.csdn.net/xusiwei1236/article/details/48495485
http://blog.sina.com.cn/s/blog_67e1c5cc0101ttqd.html
2017年7月18日 星期二
Uboot passes arguments to kernel
u-boot 要傳參數到kernel可使用 setenv bootargs
cmd line sample
# setenv bootargs androidboot.selinux=disable
# saveenv
code sample
setenv("bootargs", "androidboot.selinux=disable");
但是在android時, 會在image-android.c中的android_image_get_kernel讀取boot.img中的bootargs
boot.img的bootargs放在 BOARD_KERNEL_CMDLINE
BOARD_KERNEL_CMDLINE := console=ttymxc4,115200 init=/init
需注意的是如果code當中有設bootargs的話, 那在android_image_get_kernel就不會使用BOARD_KERNEL_CMDLINE設定的bootargs
接著bootargs會傳到proc/cmdline, 可使用cat來確認傳入的parameter.
若要再交給android做為properties使用, 那可以在bootargs增加androidboot.xxx=xxx
在system/core/init/init.c當中會去處理bootargs.
在import_kernel_nv當中會將androidboot.xxx都換成ro.boot.xxx
所以如果一開始有設置androidboot.selinux=disable的話, 在經過這邊之後會被換成ro.boot.selinux=disable, boot進android之後使用getprop就可以看到了.
另外一些特定的properties則會經過export_kernel_boot_props再parsing一次.
cmd line sample
# setenv bootargs androidboot.selinux=disable
# saveenv
code sample
setenv("bootargs", "androidboot.selinux=disable");
但是在android時, 會在image-android.c中的android_image_get_kernel讀取boot.img中的bootargs
boot.img的bootargs放在 BOARD_KERNEL_CMDLINE
BOARD_KERNEL_CMDLINE := console=ttymxc4,115200 init=/init
需注意的是如果code當中有設bootargs的話, 那在android_image_get_kernel就不會使用BOARD_KERNEL_CMDLINE設定的bootargs
int len = 0; if (*hdr->cmdline) { len += strlen(hdr->cmdline); } char *bootargs = getenv("bootargs"); if (bootargs) len += strlen(bootargs); char *newbootargs = malloc(len + 2); if (!newbootargs) { puts("Error: malloc in android_image_get_kernel failed!\n"); return -ENOMEM; } *newbootargs = '\0'; if (bootargs) { strcpy(newbootargs, bootargs); } else if (*hdr->cmdline) { strcat(newbootargs, hdr->cmdline); }
接著bootargs會傳到proc/cmdline, 可使用cat來確認傳入的parameter.
若要再交給android做為properties使用, 那可以在bootargs增加androidboot.xxx=xxx
在system/core/init/init.c當中會去處理bootargs.
static void process_kernel_cmdline(void) { /* don't expose the raw commandline to nonpriv processes */ chmod("/proc/cmdline", 0440); /* first pass does the common stuff, and finds if we are in qemu. * second pass is only necessary for qemu to export all kernel params * as props. */ import_kernel_cmdline(0, import_kernel_nv); //read kernel parameter here if (qemu[0]) import_kernel_cmdline(1, import_kernel_nv); /* now propogate the info given on command line to internal variables * used by init as well as the current required properties */ export_kernel_boot_props(); } void import_kernel_cmdline(int in_qemu, void (*import_kernel_nv)(char *name, int in_qemu)) { char cmdline[2048]; char *ptr; int fd; fd = open("/proc/cmdline", O_RDONLY); if (fd >= 0) { int n = read(fd, cmdline, sizeof(cmdline) - 1); if (n < 0) n = 0; /* get rid of trailing newline, it happens */ if (n > 0 && cmdline[n-1] == '\n') n--; cmdline[n] = 0; close(fd); } else { cmdline[0] = 0; } ptr = cmdline; while (ptr && *ptr) { char *x = strchr(ptr, ' '); if (x != 0) *x++ = 0; import_kernel_nv(ptr, in_qemu); ptr = x; } }
在import_kernel_nv當中會將androidboot.xxx都換成ro.boot.xxx
static void import_kernel_nv(char *name, int for_emulator) { char *value = strchr(name, '='); int name_len = strlen(name); if (value == 0) return; *value++ = 0; if (name_len == 0) return; if (for_emulator) { /* in the emulator, export any kernel option with the * ro.kernel. prefix */ char buff[PROP_NAME_MAX]; int len = snprintf( buff, sizeof(buff), "ro.kernel.%s", name ); if (len < (int)sizeof(buff)) property_set( buff, value ); return; } if (!strcmp(name,"qemu")) { strlcpy(qemu, value, sizeof(qemu)); } else if (!strncmp(name, "androidboot.", 12) && name_len > 12) { const char *boot_prop_name = name + 12; char prop[PROP_NAME_MAX]; int cnt; cnt = snprintf(prop, sizeof(prop), "ro.boot.%s", boot_prop_name); //change to ro.boot.xxx here if (cnt < PROP_NAME_MAX) property_set(prop, value); } }
所以如果一開始有設置androidboot.selinux=disable的話, 在經過這邊之後會被換成ro.boot.selinux=disable, boot進android之後使用getprop就可以看到了.
另外一些特定的properties則會經過export_kernel_boot_props再parsing一次.
struct { const char *src_prop; const char *dest_prop; const char *def_val; } prop_map[] = { { "ro.boot.serialno", "ro.serialno", "", }, { "ro.boot.mode", "ro.bootmode", "unknown", }, { "ro.boot.baseband", "ro.baseband", "unknown", }, { "ro.boot.bootloader", "ro.bootloader", "unknown", }, };
2017年6月21日 星期三
Jenkins tips
Jenkins 注意的點, for Android Repo project
1. Use Gerrit Repo plugin, Manifest Branch的部份不需填入branch name. 在後面shell command部份使用repo start切branch即可, manifest branch亂填會導致xml檔錯誤.
2. Gerrit Repo plugin不是非常好用, 有些command的參數無法自己下, 推薦還是使用shell command直接做想下的repo command即可.
3. Gerrit trigger plugin: 先參考plug in wiki上在Gerrit server上做好Jenkins帳號的權限設定.
https://wiki.jenkins-ci.org/display/JENKINS/Gerrit+Trigger#GerritTrigger-SetUp
4. Gerrit trigger plugin: Gerrit server如果設好之後test connection就會顯示success, 如果test ok但是上層的gerrit server status一直有問題的話, 重開Jenkins server. 如果ssh key有改名或換檔案, 也需要重開Jenkins server.
5. Gerrit trigger plugin: 在工作中的設定, path 設**會去monitor 目錄下所有的project, Branches設plain branch_name.
6. Gerrit trigger plugin: plugin可使用下面這行command, 就會merge進此patch,
repo download $GERRIT_PROJECT $GERRIT_CHANGE_NUMBER/$GERRIT_PATCHSET_NUMBER
Note: merge之後並不會自動revert, code會留在目錄中. 需注意$GERRIT_PROJECT, 他會去抓gerrit上的project name, 如果project path有多幾層的話, 可以用sed刪除字串再丟回download path.
7. Shell command中如果使用cp, rm, mkdir需注意權限. copy檔案到/var/lib/jenkins/以外的路徑需先把目錄權限設到777
1. Use Gerrit Repo plugin, Manifest Branch的部份不需填入branch name. 在後面shell command部份使用repo start切branch即可, manifest branch亂填會導致xml檔錯誤.
2. Gerrit Repo plugin不是非常好用, 有些command的參數無法自己下, 推薦還是使用shell command直接做想下的repo command即可.
3. Gerrit trigger plugin: 先參考plug in wiki上在Gerrit server上做好Jenkins帳號的權限設定.
https://wiki.jenkins-ci.org/display/JENKINS/Gerrit+Trigger#GerritTrigger-SetUp
4. Gerrit trigger plugin: Gerrit server如果設好之後test connection就會顯示success, 如果test ok但是上層的gerrit server status一直有問題的話, 重開Jenkins server. 如果ssh key有改名或換檔案, 也需要重開Jenkins server.
5. Gerrit trigger plugin: 在工作中的設定, path 設**會去monitor 目錄下所有的project, Branches設plain branch_name.
6. Gerrit trigger plugin: plugin可使用下面這行command, 就會merge進此patch,
repo download $GERRIT_PROJECT $GERRIT_CHANGE_NUMBER/$GERRIT_PATCHSET_NUMBER
Note: merge之後並不會自動revert, code會留在目錄中. 需注意$GERRIT_PROJECT, 他會去抓gerrit上的project name, 如果project path有多幾層的話, 可以用sed刪除字串再丟回download path.
7. Shell command中如果使用cp, rm, mkdir需注意權限. copy檔案到/var/lib/jenkins/以外的路徑需先把目錄權限設到777
2017年3月22日 星期三
使用Eclipse開發Linux Kernel 設定
來源: http://maxron.blogspot.tw/2012/05/eclipselinux-kernel.html?view=flipcard
下面文章說3.5.1 + CDT ,不過,基本上只要下載 eclipse forr c/c++ 的版本就有附帶CDT了。功能上就和 source insight 是一樣的,是可以取代source insight 的一種選擇
下面文章說3.5.1 + CDT ,不過,基本上只要下載 eclipse forr c/c++ 的版本就有附帶CDT了。功能上就和 source insight 是一樣的,是可以取代source insight 的一種選擇
Here are some steps that I've found to get the CDT to work well with the Linux kernel source. If you exclude some of these steps, it may still work to a large degree, but some things may not work exactly right; for example it may find the wrong include file for a C file.
Anyway, as you do these steps, I think you may understand how they assist the indexer to do a good job for the Linux kernel source.
Disclaimer: these steps were developed for Eclipse 3.5.1 + CDT 6.0.0.
- Download and install Eclipse plus the CDT.
- Configure and build your kernel to define CONFIG_* and generate autoconf.h. This can be done before or after downloading and installing Eclipse.
- Ensure that you have the right kernel source (e.g. make sure you are on the right git branch). If you check out another branch later, that's ok, but you will need to re-index the source, and that takes about 20 minutes.
- Start up Eclipse.
- Click File->New->C Project
- Fill in a project name like my_kernel
- Uncheck the Use default location box and type in the root directory of your kernel into the Location box.
- In the Project type: pane, click the Makefile project and select Empty Project
- On the right side, select Linux GCC
- Click Advanced settings... and a Properties dialog will pop up.
- Select Resource on the left, and then in the Text file encoding section, select Other and ISO-8859-1 in the box, then click Apply
- Select C/C++ Build on the left.
- Click on Discovery Options
- At the bottom of the screen where it says Compiler invocation arguments, insert "-include include/generated/autoconf.h" at the beginning of that line. Also insert any other compiler options you may need that are not the default, such as "-m64" (Note: for older kernels [pre-2.6.36?], the location of autoconf.h is include/linux/autoconf.h) <-- cannot find this
- You may also need to change the compiler command from gcc to whatever compiler you are using (e.g. you are using a cross compiler).
- Open the C/C++ General selection on the left.
- Click on Indexer
- Checkmark the Enable project specific setttings box.
- Uncheck Index source files not included in the build
- Clear out the Files to index up-front box.
- Click on Paths and Symbols on the left.
- Select the Includes tab and then select GNU C
- Click Add...
- Click Workspace... then select your kernel's include directory
- Do another Add, Workspace and add arch/architecture/include, e.g., arch/powerpc/include
- Click the # Symbols tab
- Click Add...
- Set the name to __KERNEL__
- Set the value to 1 and click OK
- Click the Source Location tab
- Click the twisty for your project.
- Select the Filter item and click Edit Filter...
- Click Add Multiple... and then select all of the arch/* directories in your kernel source that will not be used (i.e. all the ones that are not for the architecture you are using)
- Click OK and OK again to dismiss that dialog.
- Click OK on the Properties dialog.
- Click Finish on the C Project dialog.
- Right click on the project and select Index then select Rebuild
- It will take about 20 minutes or so to complete.
Notes:
- Adding include and arch/architecture/include only gets you a couple of the common include paths. To fully index all of the kernel, you would have to add dozens of paths, unfortunately. Header (.h) files are not present only in include directories. For this reason, I advise against using PTP's remote indexing capability for the linux kernel, because what happens is that it will report thousands of errors in locating header files, and the process of reporting those errors over a possibly long-latency link, will cause the indexing to take many hours.
- If you change any of your CONFIG_* settings, in order for Eclipse to recognize those changes, you must do a "build" from within Eclipse. Note, this does not mean to re-build the index; this means to build the kernel, by having Eclipse invoke make (this is normally bound to the Ctrl-B key in Eclipse). Only after a build operation, will Eclipse regenerate the compilation #defines it uses when analyzing the source during indexing and editing.
- The background color of "Quick Context View" will be dark if the Ambiance theme in Ubuntu is selected.
訂閱:
文章 (Atom)