美国之旅

忙了好长一段时间,终于可以坐下来喘口气了,打开wordpress登录,确发现https的登录界面已经被墙,看来wordpress好景不长了~~~还好,通过www.wordpress.com网站还是可以登录的,因为没有使用https.

一直以来都很想去美国看看,机会也倒是有,可是由于这样那样的原因,没能实现。前段时间正好有个机会,再加上那边的朋友一再邀请,于是跑了趟。这次比较匆忙,跑了旧金山的Petaluma朋友家,跑了硅谷Santa Clara, Mountain View,又去了Oregon的Hillsbora,一直在赶路~~~

美国给我好的感觉是环境很自然很美,车轮上的国家,人少冷清但安静,人们都很礼貌。也给我留下了一起奇怪的感觉,比如难道美国有很多残疾人吗?到处是残疾人车位,还有美国的GPS实在太老土了,竟然不是手写输入~~~

美国确实是一个自由的国家,自由到什么都需要DIY,比如自己要休整自家的院子(不知道有没有物业一说),汽车加油都要自己动手(我差点把油喷出来)。

下面看图说话~~~

硅谷的街道真是冷清,除了车就没有人,但是环境真的很美,难怪我和美国同事说起周末去公园玩的时候,美国同事都很惊讶,因为在美国到处都是公园~~

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

美国开车和中国大部分规则一样,但是有些区别,比如美国的街道上有很多stop的标志,而不是红绿灯,这个时候要求司机停下来,观察四周没人了再走。这个我很不习惯,总有种做贼的感觉。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

车轮上的国家,没办法,我也只好租了车,反正公司报销哈~~~这其实已经是我到了Portland的Hillsboro了

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

美国的导航仪实在太土了。。。不支持手写输入,不支持语音输入,只能选择字母,还好美国的所有单词由26个字母组成。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

美国著名的黄颜色校车,红红的stop标志让人感觉到美国人对小孩的权益是如何的重视。相比中国的校车都是小小的面包车,电视经常报道某某校车出事~~

久违的KFC藏在树丛中,西餐中我唯一喜欢的就是KFC,本以为来了美国可以好好吃吃KFC,吃了才发现真的好难吃,面包特别的僵硬,害的我足足饿了好几天。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

位于硅谷MountainView的Computer History Museum, 这也是我们这次做demo的地方~

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

辛苦了几天的demo,还算成功,最后临走前,匆匆留了个纪念~~

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Intel的Amberglen office,位于乡村一角,景色十分美丽。

 

Intel Jone Farm的会议中心大门~

Use XBMC as home media center

XBMC is an award-winning free and open source (GPL) software media player and entertainment hub for digital media. XBMC is available for Linux, OSX, and Windows.

Use your media as-is: XBMC can play CDs and DVDs directly from the disk or image file, almost all popular archive formats from your hard drive, and even files inside ZIP and RAR archives. It will even scan all of your media and automatically create a personalized library complete with box covers, descriptions, and fanart. There are playlist and slideshow functions, a weather forecast feature and many audio visualizations. Once installed, your computer will become a fully functional multimedia jukebox.

xmbc1

1, Support chinese TV and online movie.

XBMC design a strong addon system. After installing chinese add-on, it can play most chinese TV and online movie.

Download and install chinese addon from http://code.google.com/p/xbmc-addons-chinese/downloads/list

xbmc-tv1

xbmc-video1

2, Support remote control from my android

xbmc-remote

 

v0.6.1

Also it support MCE control device from microsoft.

xbmc-control2

3, Support many source of media

xbmc-source

4, Support many input device and can be easily extended

xbmc-control

The XBMC’s extension are written into python language, for example, to support chinese pinyin input method, http://code.google.com/p/xbmc-addons-chinese/downloads/list gives python’s script, following is piece of code:

class InputWindow(xbmcgui.WindowXMLDialog):
    def __init__( self, *args, **kwargs ):
        self.totalpage = 1
        self.nowpage = 0
        self.words = ''
        self.inputString = kwargs.get( "default" ) or ""
        self.heading = kwargs.get( "heading" ) or ""
        xbmcgui.WindowXMLDialog.__init__( self, *args, **kwargs )

    def onInit(self):
        self.setKeyToChinese()
        self.getControl(CTRL_ID_HEAD).setLabel(self.heading)
        self.getControl(CTRL_ID_CODE).setLabel('')
        self.getControl(CTRL_ID_TEXT).setLabel(self.inputString)
        self.confirmed = False

5, Strong program plug-in

5.1 can check email/news ~~~

xbmc-gmail

5.2 Play game in MAME simulator

xbmc-game

5.3 BT download ~~~

xbmc-bt

6, Beautify weather forcast build-in program

xbmc-wether

7, 1080p output

xbmc-display

Android’s kernel for beagleboard-xm

Rowboat port enable TI device on android’s linux kernel at http://gitorious.org/rowboat

1, Build

   1: make CROSS_COMPILE=arm-eabi- distclean

   2: make CROSS_COMPILE=arm-eabi- omap3_beagle_android_defconfig

   3: make CROSS_COMPILE=arm-eabi- uImage

The generated uImage is in arch/arm/boot.

2, Modifications

2.1 arm\mach-omap2\board-omap3beagle.c

This file is major BSP for beagleboard. It defines __mach_desc_OMAP3_BEAGLE for architecture features as follows

MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
    /* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */
    .phys_io    = 0x48000000,
    .io_pg_offst    = ((0xfa000000) >> 18) & 0xfffc,
    .boot_params    = 0x80000100,
    .map_io     = omap3_beagle_map_io,
    .init_irq   = omap3_beagle_init_irq,
    .init_machine   = omap3_beagle_init,
    .timer      = &omap_timer,
MACHINE_END

This structure is put into .arch.info.init section referenced in link script file at arm\kernel\vmlinux.lds.S

    .init : {           /* Init code and data       */
        _stext = .;
        _sinittext = .;
            HEAD_TEXT
            INIT_TEXT
        _einittext = .;
        __proc_info_begin = .;
            *(.proc.info.init)
        __proc_info_end = .;
        __arch_info_begin = .;
            *(.arch.info.init)
        __arch_info_end = .;
        __tagtable_begin = .;
            *(.taglist.init)
        __tagtable_end = .;

The machine description structure is as follows:

struct machine_desc {
    /*
     * Note! The first four elements are used
     * by assembler code in head.S, head-common.S
     */
    unsigned int        nr;     /* architecture number  */
    unsigned int        phys_io;    /* start of physical io */
    unsigned int        io_pg_offst;    /* byte offset for io 
                         * page tabe entry  */

    const char      *name;      /* architecture name    */
    unsigned long       boot_params;    /* tagged list      */

    unsigned int        video_start;    /* start of video RAM   */
    unsigned int        video_end;  /* end of video RAM */

    unsigned int        reserve_lp0 :1; /* never has lp0    */
    unsigned int        reserve_lp1 :1; /* never has lp1    */
    unsigned int        reserve_lp2 :1; /* never has lp2    */
    unsigned int        soft_reboot :1; /* soft reboot      */
    void            (*fixup)(struct machine_desc *,
                     struct tag *, char **,
                     struct meminfo *);
    void            (*map_io)(void);/* IO mapping function  */
    void            (*init_irq)(void);
    struct sys_timer    *timer;     /* system tick timer    */
    void            (*init_machine)(void);
};

 

3, Reference

[1] http://processors.wiki.ti.com/index.php?title=TI-Android-FroYo-DevKit-V2_UserGuide

[2] http://gitorious.org/rowboat

Android’s Binder

 

The Binder communicates between processes using a small custom kernel module.This is used instead of standard Linux IPC facilities so that we can efficiently model our IPC operations as “thread migration”. That is, an IPC between processes looks as if the thread instigating the IPC has hopped over to the destination process to execute the code there, and then hopped back with the result.

Why android need IPC communication/binder? Although all android app are using java language, but android uses dalvik VM, unlike traditional OSGi’s JVM, each dalvik app resided in single linux process. As Radoslav Gerganow said, this prevent all app closed when VM is broken. So the IPC is necessary for each android app’s communication.

The binder in android is based on OpenBinder with some modifications. The binder’s protocol version used in android-kernel 2.6.32 is 7. Binder IPC in android is based on binder driver /drivers/staging/android/binder.c.

1 Workflow

image

2 Binder Driver

When a user-space thread wants to participate in Binder IPC (either to send an IPC to another process or to receiving an incoming IPC), the first thing it must do is open the driver supplied by the Binder kernel module. This associates a file descriptor with that thread, which the kernel module uses to identify the initiators and recipients of Binder IPCs.

2.1 binder_init()

  • Create procfs /proc/binder and some entries as:
    • state
    • stats transactions
    • transaction_log
    • failed_transaction_log
  • Register binder device via misc_register()

2.2 binder_ioctl()

  • BINDER_WRITE_READ

sends zero or more Binder operations, then blocks waiting to receive incoming operations and return with a result. (This is the same as doing a normal write() followed by a read() on the file descriptor, just a little more efficient.)

The ioctl’s  data structure is

struct binder_write_read {
    signed long write_size; /* bytes to write */
    signed long write_consumed; /* bytes consumed by driver */
    unsigned long   write_buffer;
    signed long read_size;  /* bytes to read */
    signed long read_consumed;  /* bytes consumed by driver */
    unsigned long   read_buffer;
};

Upon calling the driver, write_buffer contains a series of commands for it to perform, and upon return read_buffer is filled in with a series of responses for the thread to execute.

Here is a list of the commands that can be sent by a process to the driver, with comments describing the data that follows each command in the buffer:

enum BinderDriverCommandProtocol {
    BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data),
    BC_REPLY = _IOW('c', 1, struct binder_transaction_data),
    /*
     * binder_transaction_data: the sent command.
     */

    BC_ACQUIRE_RESULT = _IOW('c', 2, int),
    /*
     * not currently supported
     * int:  0 if the last BR_ATTEMPT_ACQUIRE was not successful.
     * Else you have acquired a primary reference on the object.
     */

    BC_FREE_BUFFER = _IOW('c', 3, int),
    /*
     * void *: ptr to transaction data received on a read
     */

    BC_INCREFS = _IOW('c', 4, int),
    BC_ACQUIRE = _IOW('c', 5, int),
    BC_RELEASE = _IOW('c', 6, int),
    BC_DECREFS = _IOW('c', 7, int),
    /*
     * int: descriptor
     */

    BC_INCREFS_DONE = _IOW('c', 8, struct binder_ptr_cookie),
    BC_ACQUIRE_DONE = _IOW('c', 9, struct binder_ptr_cookie),
    /*
     * void *: ptr to binder
     * void *: cookie for binder
     */

    BC_ATTEMPT_ACQUIRE = _IOW('c', 10, struct binder_pri_desc),
    /*
     * not currently supported
     * int: priority
     * int: descriptor
     */

    BC_REGISTER_LOOPER = _IO('c', 11),
    /*
     * No parameters.
     * Register a spawned looper thread with the device.
     */

    BC_ENTER_LOOPER = _IO('c', 12),
    BC_EXIT_LOOPER = _IO('c', 13),
    /*
     * No parameters.
     * These two commands are sent as an application-level thread
     * enters and exits the binder loop, respectively.  They are
     * used so the binder can have an accurate count of the number
     * of looping threads it has available.
     */

    BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14, struct binder_ptr_cookie),
    /*
     * void *: ptr to binder
     * void *: cookie
     */

    BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15, struct binder_ptr_cookie),
    /*
     * void *: ptr to binder
     * void *: cookie
     */

    BC_DEAD_BINDER_DONE = _IOW('c', 16, void *),
    /*
     * void *: cookie
     */
};

The most interesting commands here are BC_TRANSACTION and BC_REPLY, which initiate an IPC transaction and return a reply for a transaction, respectively. The data structure following these commands is:

enum transaction_flags {
    TF_ONE_WAY  = 0x01, /* this is a one-way call: async, no return */
    TF_ROOT_OBJECT  = 0x04, /* contents are the component's root object */
    TF_STATUS_CODE  = 0x08, /* contents are a 32-bit status code */
    TF_ACCEPT_FDS   = 0x10, /* allow replies with file descriptors */
};

struct binder_transaction_data {
    /* The first two are only used for bcTRANSACTION and brTRANSACTION,
     * identifying the target and contents of the transaction.
     */
    union {
        size_t  handle; /* target descriptor of command transaction */
        void    *ptr;   /* target descriptor of return transaction */
    } target;
    void        *cookie;    /* target object cookie */
    unsigned int    code;       /* transaction command */

    /* General information about the transaction. */
    unsigned int    flags;
    pid_t       sender_pid;
    uid_t       sender_euid;
    size_t      data_size;  /* number of bytes of data */
    size_t      offsets_size;   /* number of bytes of offsets */

    /* If this transaction is inline, the data immediately
     * follows here; otherwise, it ends with a pointer to
     * the data buffer.
     */
    union {
        struct {
            /* transaction data */
            const void  *buffer;
            /* offsets from buffer to flat_binder_object structs */
            const void  *offsets;
        } ptr;
        uint8_t buf[8];
    } data;
};

Thus, to initiate an IPC transaction, you will essentially perform a BINDER_READ_WRITE ioctl with the write buffer containing bcTRANSACTION follewed by a binder_transaction_data. In this structure target is the handle of the object that should receive the transaction, code tells the object what to do when it receives the transaction, priority is the thread priority to run the IPC at, and there is a data buffer containing the transaction data, as well as an (optional) additional offsets buffer of meta-data.

Given the target handle, the driver determines which process that object lives in and dispatches this transaction to one of the waiting threads in its thread pool (spawning a new thread if needed). That thread is waiting in a BINDER_WRITE_READ ioctl() to the driver, and so returns with its read buffer filled in with the commands it needs to execute. These commands a very similar to the write commands, for the most part corresponding to write operations on the other side:

enum BinderDriverReturnProtocol {
    BR_ERROR = _IOR('r', 0, int),
    /*
     * int: error code
     */

    BR_OK = _IO('r', 1),
    /* No parameters! */

    BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data),
    BR_REPLY = _IOR('r', 3, struct binder_transaction_data),
    /*
     * binder_transaction_data: the received command.
     */

    BR_ACQUIRE_RESULT = _IOR('r', 4, int),
    /*
     * not currently supported
     * int: 0 if the last bcATTEMPT_ACQUIRE was not successful.
     * Else the remote object has acquired a primary reference.
     */

    BR_DEAD_REPLY = _IO('r', 5),
    /*
     * The target of the last transaction (either a bcTRANSACTION or
     * a bcATTEMPT_ACQUIRE) is no longer with us.  No parameters.
     */

    BR_TRANSACTION_COMPLETE = _IO('r', 6),
    /*
     * No parameters... always refers to the last transaction requested
     * (including replies).  Note that this will be sent even for
     * asynchronous transactions.
     */

    BR_INCREFS = _IOR('r', 7, struct binder_ptr_cookie),
    BR_ACQUIRE = _IOR('r', 8, struct binder_ptr_cookie),
    BR_RELEASE = _IOR('r', 9, struct binder_ptr_cookie),
    BR_DECREFS = _IOR('r', 10, struct binder_ptr_cookie),
    /*
     * void *:  ptr to binder
     * void *: cookie for binder
     */

    BR_ATTEMPT_ACQUIRE = _IOR('r', 11, struct binder_pri_ptr_cookie),
    /*
     * not currently supported
     * int: priority
     * void *: ptr to binder
     * void *: cookie for binder
     */

    BR_NOOP = _IO('r', 12),
    /*
     * No parameters.  Do nothing and examine the next command.  It exists
     * primarily so that we can replace it with a BR_SPAWN_LOOPER command.
     */

    BR_SPAWN_LOOPER = _IO('r', 13),
    /*
     * No parameters.  The driver has determined that a process has no
     * threads waiting to service incomming transactions.  When a process
     * receives this command, it must spawn a new service thread and
     * register it via bcENTER_LOOPER.
     */

    BR_FINISHED = _IO('r', 14),
    /*
     * not currently supported
     * stop threadpool thread
     */

    BR_DEAD_BINDER = _IOR('r', 15, void *),
    /*
     * void *: cookie
     */
    BR_CLEAR_DEATH_NOTIFICATION_DONE = _IOR('r', 16, void *),
    /*
     * void *: cookie
     */

    BR_FAILED_REPLY = _IO('r', 17),
    /*
     * The the last transaction (either a bcTRANSACTION or
     * a bcATTEMPT_ACQUIRE) failed (e.g. out of memory).  No parameters.
     */
};

The recipient, in user space will then hand this transaction over to the target object for it to execute and return its result. Upon getting the result, a new write buffer is created containing the bcREPLY reply command with a binder_transaction_data structure containing the resulting data. This is returned with a BINDER_WRITE_READ ioctl() on the driver, sending the reply back to the original process and leaving the thread waiting for the next transaction to perform.

The original thread finally returns back from its own BINDER_WRITE_READ with a brREPLY command containing the reply data.

Note that the original thread may also receive BR_TRANSACTION commands while it is waiting for a reply. This represents a recursion across processes the receiving thread making a call on to an object back in the original process. It is the responsibility of the driver to keep track of all active transactions, so it can dispatch transactions to the correct thread when recursion happens.

  • BINDER_SET_MAX_THREADS

  • BINDER_SET_CONTEXT_MGR

  • BINDER_THREAD_EXIT

  • BINDER_VERSION

  • BINDER_SET_IDLE_TIMEOUT

(Not used in android)

  • BINDER_SET_WAKEUP_TIME

(Not used in android)

Reference

Android on my beagleboard-xm

Ha, I get android boot on my beagleboard-xm and output to 24 ich screen in 1920 * 1080.

Seems the startup frame buffer is not correct:

It does a big android….too large screen…..

Seems it cost about 5 minutes booting from welcome screen to android desktop. I think it is caused by too slow for booting from MMC directly, I need try put rootfs in usb disk but it requires enable usb hub early.

android_calc

android_setting_menu

beagleboard-xm research(2)–u-boot

1, Build

From http://code.google.com/p/beagleboard/wiki/BeagleSourceCode, download u-boot 1.3.3 for beagleboard

If you uses latest ARM gcc from codesourcery, you maybe get following error

arm-none-linux-gnueabi-gcc -g  -Os   -fno-strict-aliasing  -fno-common -ffixed-r8 -msoft-float  -D__KERNEL__ -DTEXT_BASE=0x80e80000 -I/home/ken/bb/u-boot/u-boot-beagle/include -fno-builtin -ffreestanding -nostdinc -isystem /opt/sourcery_g++/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/include -pipe  -DCONFIG_ARM -D__ARM__ -march=armv7a  -Wall -Wstrict-prototypes -c -o hello_world.o hello_world.c
hello_world.c:1: error: bad value (armv7a) for -march= switch

This issue is caused by latest GCC changing for ARMV7-A architecture, that should uses -march=armv7-a but not -march=armv7a.

To fix it, in u-boot\cpu\omap3\config.mk, change following line:

PLATFORM_CPPFLAGS += -march=armv7a

To:

PLATFORM_CPPFLAGS += -march=armv7-a

Although success to build uboot.bin image, but beagleboard-xm fail to boot it:

a) the serial baudrate is changed from 115200 to 57600

b) system hang after find no NAND memory.

But the u-boot image built from git mainline git://git.denx.de/u-boot.git with omap3 patch can work correctly, please reference http://www.elinux.org/BeagleBoard

   1: git clone git://git.denx.de/u-boot.git u-boot-main

   2: cd u-boot-main

   3: git checkout --track -b omap3 origin/master

Build

   1: make CROSS_COMPILE=arm-none-linux-gnueabi- mrproper

   2: make CROSS_COMPILE=arm-none-linux-gnueabi- omap3_beagle_config

   3: make CROSS_COMPILE=arm-none-linux-gnueabi- 

As mentioned by previous discussion, u-boot.bin is loaded into the first of internal SDRAM at address 0x80008000. So in uboot\board\ti\beagle\config.mk:

   1: #

   2: # Physical Address:

   3: # 8000'0000 (bank0)

   4: # A000/0000 (bank1)

   5: # Linux-Kernel is expected to be at 8000'8000, entry 8000'8000

   6: # (mem base + reserved)

   7:  

   8: # For use with external or internal boots.

   9: CONFIG_SYS_TEXT_BASE = 0x80008000

CONFIG_SYS_TEXT_BASE as macro passed into build options as:

arm-none-linux-gnueabi-gcc   -D__ASSEMBLY__ -g  -Os   -fno-common -ffixed-r8 -msoft-float   -D__KERNEL__ -DCONFIG_SYS_TEXT_BASE=0x80008000 -I/home/ken/bb/u-boot/u-boot-mailine/include -fno-builtin -ffreestanding -nostdinc -isystem /opt/sourcery_g++/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/include -pipe  -DCONFIG_ARM -D__ARM__ -marm  -mabi=aapcs-linux -mno-thumb-interwork -march=armv5   -o start.o start.S –c

(BTW: there is some interesting compiler options used: –ffreestanding, –isystem, –mabi=aapcs-linux)

It is worth to mention that uboot will keep some information into a global_data in top of stack, the structure is defined in uboot\arch\arm\include\asm\global_data.h:

   1: typedef    struct    global_data {

   2:     bd_t        *bd;

   3:     unsigned long    flags;

   4:     unsigned long    baudrate;

   5:     unsigned long    have_console;    /* serial_init() was called */

   6:     unsigned long    env_addr;    /* Address  of Environment struct */

   7:     unsigned long    env_valid;    /* Checksum of Environment valid? */

   8:     unsigned long    fb_base;    /* base address of frame buffer */

   9: #ifdef CONFIG_VFD

  10:     unsigned char    vfd_type;    /* display type */

  11: #endif

  12: #ifdef CONFIG_FSL_ESDHC

  13:     unsigned long    sdhc_clk;

  14: #endif

  15: #ifdef CONFIG_AT91FAMILY

  16:     /* "static data" needed by at91's clock.c */

  17:     unsigned long    cpu_clk_rate_hz;

  18:     unsigned long    main_clk_rate_hz;

  19:     unsigned long    mck_rate_hz;

  20:     unsigned long    plla_rate_hz;

  21:     unsigned long    pllb_rate_hz;

  22:     unsigned long    at91_pllb_usb_init;

  23: #endif

  24: #ifdef CONFIG_ARM

  25:     /* "static data" needed by most of timer.c on ARM platforms */

  26:     unsigned long    timer_rate_hz;

  27:     unsigned long    tbl;

  28:     unsigned long    tbu;

  29:     unsigned long long    timer_reset_value;

  30:     unsigned long    lastinc;

  31: #endif

  32:     unsigned long    relocaddr;    /* Start address of U-Boot in RAM */

  33:     phys_size_t    ram_size;    /* RAM size */

  34:     unsigned long    mon_len;    /* monitor len */

  35:     unsigned long    irq_sp;        /* irq stack pointer */

  36:     unsigned long    start_addr_sp;    /* start_addr_stackpointer */

  37:     unsigned long    reloc_off;

  38: #if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE))

  39:     unsigned long    tlb_addr;

  40: #endif

  41:     void        **jt;        /* jump table */

  42:     char        env_buf[32];    /* buffer for getenv() before reloc. */

  43: } gd_t;

The structure size maybe different according to configure macros, so at beginning of build, a script is used to calculate current size of global data:

   1: arm-none-linux-gnueabi-gcc -DDO_DEPS_ONLY \

   2:         -g  -Os   -fno-common -ffixed-r8 -msoft-float   -D__KERNEL__ -DCONFIG_SYS_TEXT_BASE=0x80008000 -I/home/ken/bb/u-boot/u-boot-mailine/include -fno-builtin -ffreestanding -nostdinc -isystem /opt/sourcery_g++/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/include -pipe  -DCONFIG_ARM -D__ARM__ -marm  -mabi=aapcs-linux -mno-thumb-interwork -march=armv5 -Wall -Wstrict-prototypes -fno-stack-protector   \

   3:         -o lib/asm-offsets.s lib/asm-offsets.c -c -S

   4: Generating include/generated/generic-asm-offsets.h

   5: tools/scripts/make-asm-offsets lib/asm-offsets.s include/generated/generic-asm-offsets.h

In EFI, there is similar design that put PeiCore’s private data at top of stack as global data.

2, Memory Map

0x9fff0000  ~  TLB table

0x9ff7f000 ~ 0x9fff0000 : Reserved for U-boot (449K)

0x9ff1f000 ~ 0x9ff7f000: for malloc(384k)

0x9ff1efe0 ~ 0x9ff1f000: board info (32 bytes)

0x9ff1ef68 ~ 0x9ff1efe0: global data (120 bytes)

0x9ff1ef68: New stack point

0x80008000                              reset vector

0x8007020 ~0x80008028      interrupt vectors

0x8000100 : Linux boot parameters

SDRAM #1

0x4020FF80 ~ 0x40210000  global_data

0x4020F800 ~0x4020FF80   stack

 

2, Workflow

  1. uboot\arch\cpu\armv7\start.S
    • Like x-load, start.S provide the first assemble loader for u-boot
    • The first instruction is reset vector and the interrupt/exception handle are closed to it. As system.map file:
80008000 T _start

80008020 t _undefined_instruction

80008024 t _software_interrupt

80008028 t _prefetch_abort

8000802c t _data_abort

80008030 t _not_used

80008034 t _irq

80008038 t _fiq

    • Switch CPU to SVC32 mode.
   1: mrs    r0, cpsr

   2: bic    r0, r0, #0x1f

   3: orr    r0, r0, #0xd3

   4: msr    cpsr,r0

    • Copy interrupt vectors to ROM indirect address: 0x4020F800
    • Because beagleboard-xm does not have NAND/OneNand device, so need copy DPLL initialize code into ROM indirect address after interrupt vectors
    • Init CPU in assemble like x-load:
      • Setup important registers: mmu, cache
      • Setup memory timing.
    • Setup stack for C code at 0x4020FF80 (uboot\include\configs\omap3_beagle.h):
   1: #define CONFIG_SYS_INIT_RAM_ADDR    0x4020f800

   2: #define CONFIG_SYS_INIT_RAM_SIZE    0x800

   3: #define CONFIG_SYS_INIT_SP_ADDR        (CONFIG_SYS_INIT_RAM_ADDR + \

   4:                      CONFIG_SYS_INIT_RAM_SIZE - \

   5:                      GENERATED_GBL_DATA_SIZE)

 

As above mentioned, before top of stack, global_data will be stored, the size of global_data is determined/generated at build time (include\generated\generic-asm-offices.h)

   1: #define GENERATED_GBL_DATA_SIZE (128) /* (sizeof(struct global_data) + 15) & ~15 */

    • Call C function board_init_f (uboot\arch\arm\lib\board.c):
      • Assign/Init global data structure at 0x4020F800
      • Disable memory I/O cache for compiler optization, just like MemoryFence() used in edk2 MdePkg:
   1: __asm__ __volatile__("": : :"memory");

Because many hardware intialization or I/O accessing will use write/read same MMIO address, the compiler maybe optimizate these code out or re-arrange read/write sequence, so it will break. Above instruction like asm volatitle used.

      • call all function defined in init_sequence array:
        • timer_init (arch/arm/cpu/armv7/omap-common/timer.c)
          • here used GPTIMER2 (there are 12 GP time in OMAP3), which base adress is 0x49032000
        • Initialize environment, because no NAND, so the environment is relocated to RAM as in arch\arm\include\asm\global_data.h
   1: #define    GD_FLG_RELOC        0x00001    /* Code was relocated to RAM        */

            By default, some configuration value comes from global variable default_environment in common\env_common.c such as baudrate.

        • serial initliazation

beagleboard-xm use NS16650 serial at COM3 0x49020000, datasheet at http://www.national.com/ds/PC/PC16550D.pdf

        • Init stage1 console for print
        • Print CPU/board information
        • Init I2C device.
        • Init SDRAM device, caculate the bank’s size.
      • Reserve RAM memory for u-boot at top of RAM1 started from 0x80000000
      • Relocate code for new location at 0x9ff7f000/stack at 0x9ff1ef60 (arch\arm\cpu\armv7\start.S, relocate_code())
      • Jump to board_init_r() in new location in RAM, (The sequence is very like PeiCore relocation in EFI)
      • In beaglboard’s board_init_r() (board\ti\beagle\beagle.c):
        • Init GPMC
        • set board id for linux as 1546
        • set boot parameter address at 0x80000100
        • Init MMC driver
        • Init stdio drivers such as serial, nulldev
        • Init jumptable?
        • Evalute board version, for beagleboard-xm board, set VAUX2 to 1.8v for EHCI PHY. And print DIE ID at 0x4830A200
        • Init IRQ/FIQ stack which size are all 4K
        • Change CPSR to enable interrupt
        • Enter main_loop() function to read boot/user script …

beagleboard-xm research(1) — Initialization & x-load

1, General boot process and device

The initialization process for OMAP Dm37x beagleboard:

  • Preinitialization
  • Power/clock/reset ramp sequence
  • Boot ROM
  • Boot Loader
  • OS/application

Six external pins(sys_boot[5:0]) are used to select interfaces or devices for booting. The interfaces are GPMC, MMC1, MMC2, USB and UART.

The ROM code has two booting functions: peripheral booting and memory booting:

  • In peripheral booting, the ROM code pools a selected communication interface such as UART or USB, downloads the executable code over the interface, and execute it in internal SRAM. Downloaded software from an external host can be used to program flash memories connected to the device.
  • In memory booting, the ROM code finds bootstrap in permanent memories such as flash memory or memory cards and executes it. The process is normally performed after cold or warm device reset.

Overall boot sequence is as follows:

Following is 32K SRAM memory map of GP device, which is used only during the booting process.

Beagleboard-xm is OMAP3, so use 64K SRAM which range is 40200000-4020FFFF.

2, Boot from MMC/SD card

In general, beagleboard-xm uses memory booting from MMC/SD card, because this board does not have NAND device. There are some limitations as follows:

  • Supports MMC/SD cards compliant with the Multimedia Card System Specification v4.2 from the MMCA Technical Committee and the SD I/O Card Specification v2.0 from the SD Association. Includes high-capacity (size >2GB) cards: HC-SD and HC MMC
  • 3-V power supply, 3-V I/O and 1.8-V I/O voltages on port 1
  • Supports eMMC/eSD (1.8-V I/O voltage and 3.0-V Core voltage) on port 2. The external transceiver mode on port 2 is not supported.
  • Initial 1-bit MMC mode, 4-bit SD mode
  • Clock frequency:
                –   Identification mode: 400 kHz
                –   Data transfer mode: 20 MHz
  • Only one card connected to the bus 
  • Raw mode, image data read directly from card sectors 
  • FAT12/16/32 support, with or without a master boot record (MBR). 
  • For a FAT (12/16/32)-formatted memory card, the booting file must not exceed 128 KB.
  • For a raw-mode memory card, the booting image must not exceed 128 KB.  

The image used by the booting procedure is taken from a booting file named MLO. This file must be in the root directory on an active primary partition of type FAT12/16 or FAT32.

An MMC/SD card can be configured as floppy-like or hard-drive-like:

  • When acting like a floppy, the content of the card is a single FAT12/16/32 file system without an MBR holding a partition table.
  • When acting like a hard drive, an MBR is present in the first sector of the card. This MBR holds a table of partitions, one of which must be FAT12/16/32, primary, and active.

3, MLO image format

For a GP device, the image is simple and must contain a small header having the size of the software to load and the destination address of where to store it when a booting device is other than XIP. The XIP device image is even simpler and starts with executable code.



4, x-load

4.1 Why uses x-load

As above mentioned, the SRAM in beagleboard-xm is very tiny as 64K, the u-boot image size is almost 196K, so beagleboard-xm can not use u-boot as MLO. The x-load is used here, which can be considered as u-boot loader, and it’s size is around 24K.

4.2 How to build x-load

  • Get mainline x-load source code from

git clone git://gitorious.org/x-load-omap3/mainline.git

make CROSS_COMPILE=arm-none-linux-gnueabi- omap3530beagle_config

make CROSS_COMPILE=arm-none-linux-gnueabi-
       Although beagleboard-xm use DM3735 process, there is updated config file in x-load mainline’s tree. So it is ok for reuse omap3530beagle_config file.

  • Generate MLO file

After building, x-load.bin is generated as raw executable binary. As above mentioned about non-XIP image format, the size and address should be added at image’s first 16 bytes. So use signGP scipt to do it. The source code of signGP is http://beagleboard.googlecode.com/files/signGP.c

4.3 x-load’s research

4.3.1 memory map

In beagleboard-xm, ROM code will load x-load binary into SRAM (0x4020000 ~ 0x4020FFFF) 64K range. The range is allocated as follows:

Runtime stack: 0x4020000 ~ 0x40207FFF

MLO                : 0x4020800 ~ 0x4020FFFF

please reference board\omap3530beagle\config.mk for TEXT_BASE setting:

   1: # For XIP in 64K of SRAM or debug (GP device has it all availabe)

   2: # SRAM 40200000-4020FFFF base

   3: # initial stack at 0x4020fffc used in s_init (below xloader).

   4: # The run time stack is (above xloader, 2k below)

   5: # If any globals exist there needs to be room for them also

   6: TEXT_BASE = 0x40200800

Please reference cpu\omap3\start.S for stack pointer setting:

   1: /* Set up the stack                            */

   2: stack_setup:

   3:     ldr    r0, _TEXT_BASE        /* upper 128 KiB: relocated uboot   */

   4:     sub    sp, r0, #128        /* leave 32 words for abort-stack   */

   5:     and    sp, sp, #~7        /* 8 byte alinged for (ldr/str)d    */

Because the x-load is non-XIP code, so TEXT_BASE is passed to compiler:

arm-none-linux-gnueabi-gcc -Wa,-gstabs -D__ASSEMBLY__ -g  -Os   -fno-strict-aliasing  -fno-common -ffixed-r8  -D__KERNEL__ -DTEXT_BASE=0x40200800 -I/home/ken/bb/x-load/mainline/include -fno-builtin -ffreestanding -nostdinc -isystem /usr/lib/gcc/i486-linux-gnu/4.4.3/include -pipe  -DCONFIG_ARM -D__ARM__ -march=armv7-a  -c -o cpu/omap3/start.o /home/ken/bb/x-load/mainline/cpu/omap3/start.S

 

4.3.2 startup process

  1. The boot is started from cpu\omap3\start.S and the first instruction is reset vector.
  2. set cpu mode to Supervisor (SVC) 32 bit mode.
  3. Copy vectors to indirect address 0x4020F800 (SRAM_OFFSET0 + SRAM_OFFSET1 + SRAM_OFFSET2)
  4. relocates clock code into SRAM where its safer to execute
  5. Initialize CPU
    1. Invalidate instruction, L2 cache, and invalidate TLBs, disable MMU
    2. Initialize SRAM stack at 0x4020FFFC, so can use C code now.
    3. In C code s_init do some early initialization such watchdog,  configure SDRAM.
  6. Relocate code section
  7. Set runtime stack
  8. Clear bss section for uninitialization value.
  9. Jump to C code start_armboot().
    1. Initialize the serial device
    2. print version information like
      Texas Instruments X-Loader 1.4.4ss
    3. Initialize I2C which base address is 0x48070000 in L4 core.
    4. reading GPIO173, 172, 171 to determin the version of beagleboard then print it, for beagleboard-xm board, the value should be 0, 0, 0
    5. Initialize MMC card and load u-boot.bin from MMC card into pop SDRAM 0x80008000
      1. If no MMC found, try to boot from onenand or nand, but beagleboard-xm does not has these devices
      2. try to boot from serial ……
    6. Jump to 0x80008000, over for x-load.

4.3.3 x-load vs EFI’s SEC phase

So we can see the x-load is very like SEC phase in UEFI specification, in Intel’s tiano implementation, the SEC phase mainly:

  • Enter protect mode
  • Prepare early C stack in CAR, the CAR is instruction cache in process for temporary stack/heap, just like Omap’s internal SRAM for boot phase. Unlike SRAM, the CAR will be disabled/destroyed after SEC phase.
  • Initialize CPU such as MTRR for flash range.
  • Initialize early ACPI timer for performance collection.
  • Find the PeiCore from flash and shadow into CAR for PEI phase.

5, Reference
=======
1) DM37x Multimedia Device Silicon Revision 1.x

关于ARM指令集



众所周知.Intel通过发布新版的”多媒体指令集”领跑X86处理器.就是SSE啦..
一旦相关厂商未能及时跟上Intel的脚步,那么最新版的应用程序就无法使用指令集接口做优化…
而我们所看到的ARM处理器也是有指令集的.
同理可得.如果使用的处理器指令集更新了,却不对应用软件做新指令集的优化则无法得到真正的性能提升…
为什么在这里说这个问题.主要是由于嵌入式系统的开发,都必须要过这个坎….选指令集….
通常一个小公司一旦选择择某个指令集的就一直会按照那个指令集走下去…为什么?因为重写代码的成本是很高的.而且软件编译器也得重新开发,否则第三方软件编译之后无法更有效率的运行在使用新指令集的CPU上.
我们可以注意到…iphone是跨指令集的(v6和v7).因为曾经使用过ARM11架构(v6指令集),而3GS是cortex A8(V7指令集),所以个人认为从3G到3Gs的开发是相当费钱的一步..
______________________________________________________________
当然google的系统和nokia的系统也都是跨指令集的….nokia是元老级的,而google的情况和apple差不多.
nokia每次要跨指令集通常都会发布新的FP补丁包过渡(比如说S603rd FP2),所以会显得比较明显.而且最糟的是nokia在兼容性方面做的相当差(也可能是故意的),S60v2就和S60v3的软件完全不兼容,v2支持v5te和v4t指令集的CPU,而v3支持v5te和v6指令集的CPU,甚至非常遗憾的说S60系统现在不支持V7指令集,这也是为什么nokia要特地生产一款linux终端来用cortex A8.
当然,这也可能未必是由于nokia实力太差.而是,兼容性确实很难兼顾.
如果苹果也是和nokia一样从v4t指令集开始做,它就能保证一路走下来全部兼容吗?
google目前似乎更倾向支持v6指令集的CPU,以换取更统一的平台(nexus one的ARM11CPU)
________________________________________________________________
这么说起来,是否支持A8的优劣就出来了.
支持A8,开发成本会上升(且在频率没有拉升之前无法看到性能提升),开发周期会延长,但会便于今后A9处理器的无痛过渡.可以扩大OS的使用范围,因为还有预留的性能提高空间.
不支持A8,节约开发成本,保持兼容性,缩短开发周期,降低开发难度.但会缩小终端的使用范围,因为性能已接近上限.
这在GPGPU未雨绸缪的时候显得非常敏感,如果GPGPU可以解决CPU性能瓶颈,那么便携式设备是否还会对CPU的速度如此渴求呢?也许A4处理的真实架构可以为我们揭开apple的想法…
tips:RTOS为实时系统realtime os,这个通常不会出现手机平台上,而只会出现在一些对可靠性要求极高的设备上(医疗装置,生命维持装置).
      而红色的platform OS就是我们的手机系统或者机顶盒一类的嵌入式系统了.

我的beagleboard-xm到货拉

好久没玩过OMAP了,绕来绕去这几年最终又从Intel的架构绕回来了ARM,世界变化真快啊

google docs 的访问

一、为什么不加密反而能访问?

1、Google Docs经常用来传播非法信息

Google Docs一直是不和谐信息的传播工具,因为它提供了https的访问方式,信息加密传输,第三者无法简单地窃听。Twitter上经常流传着一些使用Google Docs来传播的非法文档。

前段时间网上流传着一份上海某大学的硕士论文,该论文揭示了非法软件FreeGate如何获取最新的代理列表,其中最为重要的一个渠道就是Google Docs,由于GDocs在中国大陆能被正常访问,FreeGate能实时更新DNS和代理列表,从而逃过封锁。FreeGate获取Google Docs里的文件信息同样使用https方式来访问。

2、新型的拦截手段

类似于Google Docs这样的,https无法访问、http方式却可以访问的屏蔽方式以往很少见。之所以采用这样的方式,原因有3:

(1)Google Docs是一个常用的服务,不能完全屏蔽

(2)Google有众多的IP,几乎不能完全屏蔽,如果完全屏蔽,则会影响Google的正常使用

(3)必须要屏蔽Google Docs里的非法信息

这3个原因推动了新的拦截手段的发展。根据猜测,这种手段是这样进行的:当客户端发出加密的DNS解析请求时,DNS监视端一旦发现这个请求是Google Docs的,立即发出一个重置信号。而对于一般的非加密DNS请求,DNS监视端则不工作,剩下的监视工作交由正常的审查系统来进行。

3、新型拦截手段的好处

(1)有效地阻止了Google Docs上非法信息的传播,又能让Google Docs正常使用

(2)较为根本地封杀了FreeGate等非法软件

(3)当用户放弃使用https方式而改用http方式来访问时,信息都是以明文传输,所有内容全部都进入到审查系统审查,非法信息又不能传播。

二、解决方法一:OpenDNS

既然https访问被重置是发生在向DNS发出请求的时候,一个能很容易就想到的解决方案是换一个不会审查DNS请求的DNS。OpenDNS是较为普遍的选择。使用方法很简单,将电脑的DNS设置为:

208.67.222.222

208.67.220.220



如果你需要经常切换不同的DNS,可以使用“8个提高windows效率的免费软件”里介绍的NetSetman来进行DNS切换。

但是,OpenDNS是位于国外的DNS,连接速度有点慢,我们不妨考虑另一种解决方案。

三、解决方法二:自定义hosts

在hosts里添加Google Docs的解析IP直接绕过DNS查询,就能正常使用https的Google Docs了。

hosts文件的位置:

1、windows:C:\Windows\System32\drivers\etc\hosts

2、Linux:/etc/hosts

用记事本打开hosts文件,下面这些内容添加到hosts文件的顶部:

209.85.225.101 docs.google.com

74.125.127.100 writely.google.com

74.125.127.139 spreadsheets.google.com

保存hosts,重启浏览器后,https方式的Google Docs就能正常访问了。

万一Gmail也遭遇到Google Docs的情况怎么办?用同样的方法,在hosts文件里加入Gmail的IP即可,为方便使用,我将提供有https方式的Google服务及其的IP列表如下:

209.85.147.109 pop.gmail.com

209.85.147.109 smtp.gmail.com

66.102.7.19 mail.google.com

209.85.225.101 docs.google.com

209.85.225.102 groups.google.com

74.125.127.139 spreadsheets.google.com

74.125.127.100 services.google.com

74.125.127.100 writely.google.com

74.125.127.100 sites.google.com

209.85.225.104 reader.google.com

74.125.127.101 calendar.google.com