Search This Blog

Oct 29, 2010

Add extension udisk support in freescale AndroidR9.1(Froyo2.2), working on iMX53 EVK rev.B

1. Android USB gadget
  Android USB gadget source code locate under /kernel_imx/drivers/usb/gadget, it contains three files.
  Android.c, f_adb.c, f_mass_storage.c

1.1 In f_mass_storage.c, macro MAX_LUNS (8) set max lun number, check the function below.

static int __init
fsg_function_bind(struct usb_configuration *c, struct usb_function *f)
{
...
  dev_attr_file.attr.mode = 0644;

  /* Find out how many LUNs there should be */
  i = fsg->nluns;
  if (i == 0)
        i = 1;
  if (i > MAX_LUNS) {
        ERROR(fsg, "invalid number of LUNs: %d\n", i);
        rc = -EINVAL;
        goto out;
  }

}

1.2 in /kernel_imx/arch/arm/mach-mx5/mx53_evk.c. Register Android USB device in function:
  static void __initmxc_board_init(void)
  {
  ...
  mxc_register_device(&android_usb_device, &android_usb_pdata);
  ...
  }
  And then we check those two structures.
  struct platform_device android_usb_device = {
   .name   = "android_usb",
  .id     = -1,
  };
  static struct android_usb_platform_data android_usb_pdata = {
   .vendor_id   = 0x0bb4,
   .product_id = 0x0c01,
   .adb_product_id = 0x0c02,
   .version     = 0x0100,
   .product_name   = "Android Phone",
   .manufacturer_name = "Freescale",
   .nluns = 3,
  };
  nluns = 3, MX53 EVK rev B has two SD card and one udisk support, and we need add extra udisk support, we change nlun = 4,
  With the modification, we can find four lun0-lun3 under
  /sys/devices/platform/fsl-usb2-udc/gadget

1.3 USB initialize
 Register adb and mass storage in android.c
static int __init android_bind_config(struct usb_configuration *c)
{
  struct android_dev *dev = _android_dev;
  int ret;
  printk(KERN_DEBUG "android_bind_config\n");

  ret = mass_storage_function_add(dev->cdev, c, dev->nluns);
  if (ret)
        return ret;
  return adb_function_add(dev->cdev, c);
}

1.4 Mount storage to host.

1.4.1 Manually Mount storage to host
  Write storage device path”/dev/block/vold/major:minor” in /lun?/file
  echo /dev/block/vold/179:1 > /sys/devices/platform/fsl-usb2-udc/gadget/lun0/file
  echo /dev/block/vold/8:1 > /sys/devices/platform/fsl-usb2-udc/gadget/lun1/file
  echo /dev/block/vold/8:17 > /sys/devices/platform/fsl-usb2-udc/gadget/lun2/file
  echo /dev/block/vold/179:0 > /sys/devices/platform/fsl-usb2-udc/gadget/lun3/file
  It will mount storage to host

1.4.2 Manually unmount storage from host.
  echo “” > /sys/devices/platform/fsl-usb2-udc/gadget/lun0

1.4.3 Automatic mount storage to host
Froyo VOLD will handle vold.fstab under /devices/fsl/imx53_evk to mount storage. We can see mount example below.

  dev_mount sdcard /mnt/sdcard auto /devices/platform/mxsdhci.0/mmc_host/mmc0
  dev_mount extsd /mnt/extsd auto /devices/platform/mxsdhci.2/mmc_host/mmc1
  dev_mount udisk /mnt/udisk auto /devices/platform/fsl-ehci.1/usb2/2-1/2-1.5
  dev_mount extudisk /mnt/extudisk auto /devices/platform/fsl-ehci.1/usb2/2-1/2-1.4


2. Android VOLD
2.1  Parse vold.fstab file.
 In /system/vold/main.cpp, open vold.fstab
static int process_config(VolumeManager *vm) {
...
if (!(fp = fopen("/etc/vold.fstab", "r"))) {
    return -1;
}
...
        if (!strcmp(part, "auto")) {
            dv = new DirectVolume(vm, label, mount_point, -1);
        } else {
            dv = new DirectVolume(vm, label, mount_point, atoi(part));
        }
...
}
  In /system/vold/DirectVolume.cpp,

  int DirectVolume::handleBlockEvent(NetlinkEvent *evt)
  {
  const char *dp = evt->findParam("DEVPATH");

  PathCollection::iterator  it;
  for (it = mPaths->begin(); it != mPaths->end(); ++it) {
  #ifdef PARTITION_DEBUG
         SLOGD("dp:%s,*it:%s.", dp, *it);
  #endif
      if (!strncmp(dp, *it, strlen(*it))) {
          /* We can handle this disk */
       ...
      }
  ...
  }
  We print “DP” and “*it“ as below, we can see *it is path you set in vold.fstab, if DP match with *it, it will handle this disk.

D/DirectVolume( 2136): dp:/devices/platform/fsl-ehci.1/usb2/2-1/2-1.4/2-1.4:1.0/host2/target2:0:0/2:0:0:0/block/sda/sda1, *it:/devices/platform/mxsdhcimmc_host/mmc0.
D/DirectVolume( 2136): dp:/devices/platform/fsl-ehci.1/usb2/2-1/2-1.4/2-1.4:1.0/host2/target2:0:0/2:0:0:0/block/sda/sda1,*it:/devices/platform/mxsdhci.2/mmc_host/mmc1.
D/DirectVolume( 2136): dp:/devices/platform/fsl-ehci.1/usb2/2-1/2-1.4/2-1.4:1.0/host2/target2:0:0/2:0:0:0/block/sda/sda1,*it:/devices/platform/fsl-ehci.1/usb2/2-1/2-1.5.


TBD

Oct 28, 2010

二 存养善性(三)

孟子曰:"仁,人心也;义,人路也;舍其路而弗由,放其心而不知求,哀哉!人有鸡犬放,则知求之。有放心,而不知求。学问之道无他,求其放心而已矣。(告子上,一一)

语译
孟子说,仁,是人的良心。义,是人的正路。舍弃正路而不行走,亡失良心而不寻求,真是可悲啊!有人鸡狗丢失了,就知道寻找。自己的良心亡失了,反而不知道寻找。研究学问的途径没有别的,就是把亡失的良心找回来罢了。

析论
良心的自觉是一切功夫的开端,必须有了良心的自觉,其他一切修养功夫才用得上,才有着落,才有依附,才能表显其意义和价值。否则一切辛苦,奋斗,本质上都只是瞎摸,摸对了好似有效,但不对的时候可能更多,挫折感与幻灭感就不断产生。所以必须良心有了自觉,人生的方向才稳得住,一切活动才谈得上成效,依照这种认知,人生修养的关键就在求其放心。
良心的自觉是要在各种事情上去表现,读书时是自觉地读书,工作时是自觉地工作,休闲是自觉的休闲,喜怒哀乐时是自觉地喜怒哀乐等等。因此良心的自觉是无所不在,无时不在的,它不只是一个开端,而且也是功夫的全部,其他的功夫都属于良心自觉的表现。所以说孟子说学问之道无他,求其放心而已矣。
发自我的 iPad

Oct 27, 2010

二 存养善性 (二)

    孟子曰:"自暴者,不可与有言也;自弃者,不可与有为也。言非礼义,谓之自暴也;吾身不能居仁由义,谓之自弃也。仁,人之安宅也;义,人之正路也。旷安宅而弗居,舍正路而不由,哀哉!"
语译:
    孟子说:"残害自身的人    ,不能和他谈论道理;抛弃自身的人,不能和他一起有所作为。一个人开口就诋毁礼义,这便叫做残害自己;以为自己不能以仁居心,不能由义而行,这边叫做抛弃自己。仁,是人类最安全的住宅;义,是人类最正大的道路。空着最安全的住宅不去住,舍弃最正大的道路不去走,真是可悲啊!"

二 存养善性(一)

孟子曰:“牛山之木尝美矣,以其郊于大国也,斧斤伐之,可以为美乎?是其日夜之所息,雨露之所润,非无萌蘖之生焉,牛羊又从而牧之,是以若彼濯濯也。人见其濯濯也,以为未尝有材焉,此岂山之性也哉?虽存乎人者,岂无仁义之心哉?其所以放其良心者,亦犹斧斤之于木也,旦旦而伐之,可以为美乎?其日夜之所息,平旦之气,其好恶与人相近也者几希,则其旦昼之所为,有梏亡之矣①。梏之反覆,则其夜气不足以存;夜气不足以存,则其违禽兽不远矣。人见其禽兽也,而以为未尝有才焉者,是岂人之情也哉?故苟得其养,无物不长;苟失其养,无物不消。孔子曰:‘操则存,舍则亡;出入无时,莫知其乡。’惟心之谓与?” 


语译:
孟子说:"牛山的树木,从前原是很茂美的。只因临近都城,人们常用斧头、砍刀去砍伐它,还能够美的起来么?这座山日夜所生长的,雨露所滋润的,并不是没有枝桠长出来,可是牛羊跟着在哪儿放牧,所以就弄成那样光秃秃的了。人们看它光秃秃的,就以为这座山没有长过树木,这难道是山的本性吗?
存在人身上的,难道没有仁义之心吗?人所以失掉他本然的善心,也就像斧头、砍刀对于树木一般,天天砍伐它,还能够美起来吗?一个放失良心的人,经过日夜的生息,在清晨时所怀有的清明之气,和一般人的好恶相接近的只有那么一点点,可是一到了白天,受惑于纷华世界,所作所为,又把那养出的一点清明之气扰乱丧失了。如果一再的扰乱丧失,那么夜间所培养出的清明之气就不能保存;清明之气不能保存,那和禽兽就相差不远了。人们看他和禽兽一样,便以为他本来没有才质,这难道是人的本性么?
所以如果得到适当的培养,没有东西不生长的;如果失去适当的培养,没有东西不消亡的。孔子说:'把持它就能留存,舍弃它就会亡失,进出没有定时,也不知道它的定处。'这大概指人心而说吧!"

Oct 15, 2010

Debugging a Running Kernel Using RealView Debugger

4.2 Debugging a Running Kernel Using RealView Debugger

    This section assumes that you are attaching an RVD session to a running kernel. Using
    RVD to boot a kernel on a target board is covered in Section 4.3.

4.2.1 Set up the Debug Connection

   1 Start RVD.
   2 Create a debug connection to the target hardware as normal
    (Target -> Connect to target...). See the RealView Debugger User
    Guide for more information about creating debug connections in RVD.
   3 Open up the debug connection, right-click on the core that you will attach the
    debugger to and select Properties from the context menu to open the
   Connection Properties dialog.
   4 Open up the selected connection in the tree view (left-hand pane) of the
Connection Properties dialog. 




   
5 Still in the tree view, open up Advanced Information and select Default.





7 In the tree view, open up Default and select ARM_config.





8 In the right-hand pane, set Vector catch to False. This will prevent RVD from
intercepting exceptions. Exceptions can occur in the normal operation of the
kernel and will be handled by it.



 


9 In the tree view, open up ARM_config and select Semihosting.





10 In the right-hand pane, set Enabled to False. The Linux C runtime does not use
semihosting and so RVD should not be attempting to provide semihosting
services. 





11 Save the changed connection properties and close the dialog.





12 The debug connection can now be used to connect to the target.
Note If you have set a Board/Chip definition file for this connection, then this file might contain
values for this connection that override the target connection settings that you have made
in this section.

4.2.2 Load Debug Symbols
1 If you have not done so already, connect to the target.
2 Open the Load Image dialog by selecting Load Image... from the Target
menu.
In the Files of Type drop-down, select All files (*).
Tick the Symbols Only check box. It is the responsibility of your boot loader to
load the kernel code: you do not want RVD to load it again.
Ensure that Auto-Set PC and Set PC to Entry Point are not ticked. Your
system is already running, so you do not want RVD to change the PC.
Navigate to the location of your kernel source tree and select the vmlinux file
that is at its root. This file contains the kernel’s debug information. 




3 Press the Open button. RVD will load the debug symbols for the Linux kernel.
This may take some time.

4 RVD now has the kernel debug information loaded and is able to proceed with
debugging in the usual manner

4.2.3 Debug the Kernel
You can debug the kernel as you would any other software running on the target.
However, there are some issues to be aware of when using RealView Debugger to debug
the Linux kernel.
1 Only statically compiled kernel code can be debugged with RVD, not Linux
applications and not loadable kernel modules (see the FAQ Can I debug Linux
applications and Kernel modules using RVD? at
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/14250.html).
2 Software breakpoints can be set at any point after the MMU has been initialized,
which means at any point from MAIN\start_kernel onwards. The RealView
Debugger User Guide has full information about setting breakpoints with RVD,
but as an example, typing the following in the Cmd window will set a breakpoint at
the beginning of MAIN\start_kernel:
binstr &@vmlinux\\MAIN\start_kernel
There are no restrictions on when hardware breakpoints (set with the bexec
instruction) may be set.
3 RVD does not provide any special awareness of the Linux kernel and will treat it
as it would any other software running directly on the hardware target. It is
therefore not possible to tell, for example, which process was running when a
kernel breakpoint is triggered, or even if two consecutive breakpoint hits were
caused by the same process.
4 Unless you are able to configure your kernel to build with no optimizations and
full debug information, you will not get a perfect debug illusion. For example, the
debugger may appear to skip source lines, or to be executing a different source
line from the one that is actually currently being executed. Note that the ARM
Embedded Linux kernel build does not permit all optimizations to be disabled.
Although the General setup submenu of the kernel configuration has an
Optimize for size option, disabling this option causes the build to
optimize for performance instead of code size, so the kernel will still contain
optimized code

Oct 13, 2010

iMX53EVK DDR2 setting

4. iMX53EVK DDR2 setting.

4.1 EVK rev B hardware connection.

There are four Hynix H5PS2G83AFR(256Mb x 8) on board.




4.2 H5PS2G83AFR parameter (JESD79-2E)






Four Active Window for 1KB page size productstFAW35ns
Refresh to Active/Refresh command timetRFC195ns
Exit self refresh to a non-read commandtXSNRtRFC + 10ns
Exit precharge power down to any non-read
command
tXP2nCK
Exit active power down to read commandtXARD2nCK
Programmable CAS latencyCAS3, 4, 5 and 6nCK
Bin(CL-tRCD-tRP)5-5-5
ACT command to internal read or write delay time (same bank)tRCD5nCK
PRE command period (same bank).tRP5nCK
ACT to ACT or REF command period (same banktRC57.5ns
ACT to PRE command period (same bank).tRAS45ns
WRITE recovery time (same bank).tWR15ns
tRP for a Precharge All command for an 8 Bank device will equal to tRP+1*tCKtRPAtRP + 1nCK
Mode Register Set command cycle (all banks).tMRD2tCK
CAS Write Latency.tCWLCAS - 1nCK
Exit self refresh to a read commandtXSRD200nCK
Internal READ command to PRECHARGE command delay (same bank)tRTP7.5ns
Internal WRITE to READ command delay (same bank)tWTR7.5ns
ACTIVE to ACTIVE command period (all banks).tRRD7.5ns




4.3 iMX53 DDR2 register setting

Please go through “Chapter 19 ESDCTLv2.5 - Enhanced DDR controller” and “Chapter 9 DDR3 PHY” in iMX53RM.pdf for detail information. iMX53 EVK use DDR800, 400Mhz, 1 clk = 2.5ns.

4.3.1 DDR2 timing setting



      Bank Interleaving On, RALAT= 3 cycles additional latency, 8 banks device is being used, DDR2 Enable


      Enable CSD0 and CSD1, row width = 15, column width = 10, burst length = 4, data width = 32bit


     tRFC = 78 ck, tXS = 82 ck, tXP = 2 ck, tXPDLL(tXARD) = 2 ck, tFAW = 14 ck, CAS latency = 5 ck


     tRCD = 5 ck, tRP = 5 ck, tRC = 23 ck, tRAS = 18 ck, tRPA = 1, tWR = 6 ck, tMRD = 2 ck, tCWL = 4 ck


     tDLLK(tXSRD) = 200 cycles, tRTP = 3 ck, tWTR = 3ck, tRRD = 3ck


     Refresh cycles will be triggered in frequency of 32KHz; Refresh Rate.=4 refreshes;

4.3.2 SDRAM Special Command Register (Address 0xBASE_001C (ESDSCR))

This register is used to issue special commands on the external device bus (such as load mode register, manual self refresh, manual precharge etc.). Every write to this register will be interpreted as a command, and a read from this register will show you the last command executed.


4-6
CMD
Command. This field contains the command to be executed:
This field will be automatically cleared after the command will be asserted.
0x0 Normal operation
0x1 Precharge. Can be to a specific bank or to all banks, according to ‘cmd_addr’. If ‘cmd_addr’ equals ‘0x400’
precharge all is issued to the chosen chip select.
Will be issued even if banks are closed. Mainly used for init sequence purpose.
0x2 Auto-Refresh Command
0x3 Load Mode Register Command
0x4 ZQ calibration.
0x5 Precharge all, only if banks open. ‘cmd_addr’ field must be equal to ‘0x400’ in this command.
0x6-0x7 Reserved
Fields CMD_CS, CMD_BA and CMD_ADDR will be used for sending: cs_b,ba,ma signals along with the choosen
command to the memory.



0x63fd901c = 0x04008010 /*Precharge*/
0x63fd901c = 0x00008032 /*write mode reg MR2 with cs0               */
0x63fd901c = 0x00008033 /*write mode reg MR3 with cs0               */
0x63fd901c = 0x00008031 /*write mode reg MR1 with cs0               */
0x63fd901c = 0x0b5280b0 /*write mode reg MR0 with cs0 , with dll_rst0 */
0x63fd901c = 0x04008010 /*Precharge*/
0x63fd901c = 0x00008020 /*Auto-Refresh Command with cs0*/
0x63fd901c = 0x00008020 /*Auto-Refresh Command with cs0*/

About DDR2 Mode Register setting, we need learn something otherwise we would not understand below setting.
0x63fd901c = 0x0a528030 /* BL = 4, CAS latency = 5, write recovery = 6*/
0x63fd901c = 0x03c68031 // OCD Calibration default
0x63fd901c = 0x00468031  // reduced drive strength, enable 50ohm ODT


     DDR2 For application flexibility, burst length, burst type, CAS latency, DLL reset function, write recovery time (WR) are user defined variables and must be programmed with a Mode Register Set (MRS) command. Additionally, DLLdisable function, driver impedance, additive CAS latency, ODT (On Die Termination), single-ended strobe, and OCD(off chip driver impedance adjustment) are also user defined variables and must be programmed with an Extended Mode Register Set (EMRS) command.


      The mode register is written by asserting LOW on CS, RAS, CAS, WE, BA0 and BA1, while     controlling the state of address pins A0 - A15.
    From 0x63fd901c = 0x0a528030 /* BL = 4, CAS latency = 5, write recovery = 6*/
    we can see (BA1-BA0) is 00b, means MR; (A2-A0) is 010b, means BL=4; (A6-A4) is 101b, means CAS=5; (A11-A9) is 101b, means write recovery equal 6.




4.3.3 iMX53 DDR phy register setting.






4.3.4 DDR2 pin IOMUX setting

     Refer from “Chapter 34 IOMUX Controller (IOMUXC)”,


           30 34 20


4.3.5 DDR2 initialize sequece

      We can find those DDR2 init code in “diag-obds\src\include\mx53\plat_startup.inc”
Don’t forget change the value of  dcd_hdr and write_dcd_cmd base on your real situation.