01

How to run mod file that is loaded into HEAP


05-15-2008, 11:20 PM
Brewin
Registered User Join Date: Mar 2006
Posts: 152
Rep Power: 4

How to run file that is loaded in the

——————————————————————————–

Hi everyone,
How can I run a MOD file that is loaded into the HEAP???? Any idea’s…

__________________
Thanks everyone for the info they share here..
Ramki@TTSL
VALUE HAS A VALUE ONLY IF ITS VALUE IS VALUED

——————————————————————————–
Last edited by Brewin : 05-15-2008 at 11:27 PM.

Brewin
View Public Profile
Send a private message to Brewin
Send email to Brewin
Find all posts by Brewin
Add Brewin to Your Buddy List

#2 06-04-2008, 07:36 PM
ArdyFalls
Registered User Join Date: Apr 2007
Posts: 23
Rep Power: 0

Steps for loading a mod into the heap

——————————————————————————–

1) malloc memory on the heap that is the size of the mode file + 4 in bytes.
2) Set the initial 4 btyes to point to the AEE struct thing that has all the AEEStdlib funcitons.
3) Set the processors program counter (PC register) to address 0
Please note, I could be kinda off, look at the code for AEE_ModLoad, it is always at address zero. It will tell you the arguments that you need to pass to it before setting the pc register to it. Remember, the first four arguments of any function are passed in registers r0 -r4.

I hope this helps

__________________
Ardavon Falls
Senior Software Engineer
MobiTV Inc

ArdyFalls
View Public Profile
Send a private message to ArdyFalls
Find all posts by ArdyFalls
Add ArdyFalls to Your Buddy List

#3 07-28-2008, 10:45 PM
Brewin
Registered User Join Date: Mar 2006
Posts: 152
Rep Power: 4

Loading and running a compressed mod file…

——————————————————————————–

Hi All,
To run a compressed mod file in you need to create a mod loader(Approxmately 700+ bytes, atleast mine).

For 2.x brew devices, your mod loader file name should be same as of your app name.
Ex: myapp.mif, myapp.mod(your mod loader), filename.gz(your compressed myapp.mod file, you can name this file as filename.bar so that you don’t have any problems when user disables your app).

For 3.x brew devices on which we can read a mod file by setting the required permissions in MIF can add this mod loader file content at the start of your compressed mod file or you can use the same as that used for 2.x which don’t required any permissions or settings in MIF.
Ex: myapp.mif, myapp.mod(your mod loader + filename.gz).

To create a mod loader, you have every information you need in 2 threads.

First read only the first post by user “ajiva” in the following thread. Then return to this thread for additional info you need.

Quote:

http://brewforums.qualcomm.com/showthread.php?t=11637

A call to AEEMod_Load that you have seen in the first thread will set the params in the registers.

Quote:
Note 1: Don’t release the buffer that contains the uncompressed content of your actual mod file in your mod loader. Once the actual app is closed, it will released by BREW system.
Note2: Release all other allocated buffers and interfaces you created in mod loader before making a call to AEEMod_Load.

Thanks for ajiva and Ardy Falls for the valuable info they provided.

__________________
Thanks everyone for the info they share here..
Ramki@TTSL
VALUE HAS A VALUE ONLY IF ITS VALUE IS VALUED

——————————————————————————–
Last edited by Brewin : 08-06-2008 at 12:59 AM.

Brewin
View Public Profile
Send a private message to Brewin
Send email to Brewin
Find all posts by Brewin
Add Brewin to Your Buddy List

#4 07-29-2008, 12:36 AM
Rajni
Registered User Join Date: Apr 2005
Posts: 32
Rep Power: 0

Really usefull

——————————————————————————–

Hi Ramki,
Really very useful information.

Rajni
View Public Profile
Send a private message to Rajni
Find all posts by Rajni
Add Rajni to Your Buddy List

#5 08-06-2008, 12:57 AM
Brewin
Registered User Join Date: Mar 2006
Posts: 152
Rep Power: 4

Loading and running a compressed extension mod file…

——————————————————————————–

Hi all,
The above procedure is not working in case if the compressed mod file is an extension. Applet compressed mod file is running fine. The decompressed file of the extension mod is Identical with the original extension mod file, but device is getting crashed when AEEMod_Load of the extension mod is executed.

if both an applet and extensions loads the same way then
why is this difference..

If I use normal extension mod everything goes well.

Do anyone has any idea about this.

Quote:
The extension I used is xmlparser, I will write my own extension and check does it make any difference using debug info.

__________________
Thanks everyone for the info they share here..
Ramki@TTSL
VALUE HAS A VALUE ONLY IF ITS VALUE IS VALUED

——————————————————————————–
Last edited by Brewin : 08-06-2008 at 01:02 AM.

Brewin
View Public Profile
Send a private message to Brewin
Send email to Brewin
Find all posts by Brewin
Add Brewin to Your Buddy List

#6 08-06-2008, 06:15 AM
Brewin
Registered User Join Date: Mar 2006
Posts: 152
Rep Power: 4

Loading a compressed module(Application/Extension)

——————————————————————————–

I hope I got the resolution,
Quote:
Originally Posted by Brewin
Hi all,
The above procedure is not working in case if the compressed mod file is an extension. Applet compressed mod file is running fine. The decompressed file of the extension mod is Identical with the original extension mod file, but device is getting crashed when AEEMod_Load of the extension mod is executed.

if both an applet and extensions loads the same way then
why is this difference..

If I use normal extension mod everything goes well.

Do anyone has any idea about this.

If the module irrespective of Application or Extension, is complied with standard AEEModGen.C then the MOD compression will work else the behavior is unknown.

Hope this helps, Please correct me if I am wrong.
But since all module will have the same entry point why this happens…

__________________
Thanks everyone for the info they share here..
Ramki@TTSL
VALUE HAS A VALUE ONLY IF ITS VALUE IS VALUED

——————————————————————————–
Last edited by Brewin : 08-06-2008 at 06:17 AM.

Brewin
View Public Profile
Send a private message to Brewin
Send email to Brewin
Find all posts by Brewin
Add Brewin to Your Buddy List

#7 08-07-2008, 12:32 PM
TG1e
Registered User Join Date: May 2008
Posts: 3
Rep Power: 0

Reference code please [if possible]

——————————————————————————–

Addressed to all who are working (or have worked) on this topic of loading a mod from heap mem…
Will it be possible for you to post some reference code?

Also, for clarity…

Do we only have to call AEEMod_Load?
Or do we have to call the other functions as well….How does the AEE come to know that we have loaded the compressed (and now decompressed) mod? How will the AEE send events to this newly loaded mod?

Awaiting your response(s)…

——————————————————————————–
Last edited by TG1e : 08-07-2008 at 12:34 PM.

TG1e
View Public Profile
Send a private message to TG1e
Find all posts by TG1e
Add TG1e to Your Buddy List

#8 08-23-2008, 06:51 AM
Brewin
Registered User Join Date: Mar 2006
Posts: 152
Rep Power: 4

Loading compressed mod file..Step by Step

——————————————————————————–

Quote:
Originally Posted by TG1e
Addressed to all who are working (or have worked) on this topic of loading a mod from heap mem…
Will it be possible for you to post some reference code?

What code you need, first compress you MOD file with gzip(if 7zip is used then you need to supply you own decompressor code in the mod loader or bootloader)
Example: You have an application with myapp.mod, myapp.bar, myapp.mif
After compressing MOD, your files are myapp.zip, myapp.bar,myapp.mif.
Now write a bootloader which will load myapp.zip into memory and uncompress..

1. Create a project with name ex: .

2. copy AEEModGen.C and AEEModGen.H into your project and add the following header files
AEE.h, AEEShell.h, AEEUnzipStream.h, AEEFile.h, AEEHeap.h, AEEStdLib.h.

3. Delete everything not related to AEEMod_Load and AEEStaticMod_New in both files and add the below line

Quote:
For AEEMod_Load typecast…..
typedef int (*RunLoadMod)(IShell *ps, void * ph, IModule ** pMod);

2. Delete every thing inside the AEEStaticMod_New function.

3. Now inside the AEEStaticMod_New function declare pointers to IUnzipAStream, IFileMgr and IFile interfaces.

4. Create an Instance of IFileMgr and IUnzipStream(if compressed with gzip). else
provide your own decompress function here.

5.Now allocate some memory and copy the “ph” variable which is the pointer to AEEHelper Functions into the first four bytes of allocated memory.

6. Open myapp.zip and Set it for uncompressing using
” IUNZIPASTREAM_SetStream “.

7. Now read the uncompressed stream using ” IUNZIPASTREAM_Read ” and copy the contents from 5th byte onwards into the same buffer using MEMCPY, REALLOC as per requirements.
( Now your buffer contains pointer to AEEHelper functions + uncompressed myapp.zip, now buffer size will be a minimum of 4+sizeof(myapp.mod) ).

8. Once your buffer is ready with the above you are done. Release the IFileMgr, Ifile and IUnzipStream interface pointers.

9. Now type cast the 5th byte of the buffer to AEEMod_Load with a return statement like

Quote:
return (RunLoadMod)(buffer+4)(pIShell,ph,ppMod);
to execute the actual mod file….

Note: Don’t release the buffer, once the app exits this memory will be released by AEE.

You modloader is ready now.
Compile and create the mod file and rename the mod file as myapp.mod.

Now you app contains, myapp.mif, myapp.mod, myapp.zip, myapp.bar.

Quote:
Also, for clarity…
Do we only have to call AEEMod_Load?
Or do we have to call the other functions as well….How does the AEE come to know that we have loaded the compressed (and now decompressed) mod? How will the AEE send events to this newly loaded mod?

When you click on your app, AEE loads the mod file associated with the app name in this case it is myapp.mod(mod loader) and executes the first address i.e AEEMod_load which will feed the actual mod to the AEE, it’s not the AEE that load your actual MOD file.

There is no applet related to modloader, when AEE encounter the last statement in the AEEStaticMod_New of the modloader AEE just jumps to the address where we have kept the actual MOD file and exectues from there in the process whatever is created and registered(IModuleVtbl, Applet, Applet_HandleEvent) are all belongs to the actual application mod file and AEE will send events to the registered handleEvent of the top visible applet which is nothing but your application handle Event.

__________________
Thanks everyone for the info they share here..
Ramki@TTSL
VALUE HAS A VALUE ONLY IF ITS VALUE IS VALUED

——————————————————————————–
Last edited by Brewin : 08-23-2008 at 06:59 AM.

Brewin
View Public Profile
Send a private message to Brewin
Send email to Brewin
Find all posts by Brewin
Add Brewin to Your Buddy List

#9 01-13-2009, 07:55 AM
ed_est
Registered User Join Date: Jan 2009
Posts: 3
Rep Power: 0

Hi Brewin,
I am interested in the functionality that you have described in this topic and I have tried to create a modloader by myself according the steps you have provided, but unfortunately my device just reboots when I am trying to execute the loaded into memory .mod file. I have tried my code on different devices with different BREW version and on all of them I had device reboot.
Here is my code in AEEStaticMod_New function ( I have simplified it because I don’t use compression for .MOD file, also I have removed all checks):

ISHELL_CreateInstance(pIShell, AEECLSID_FILEMGR, (void**) &piFileMgr);
piFile = IFILEMGR_OpenFile(piFileMgr, “realmod.bin”, _OFM_READ);
IFILE_GetInfo(piFile, &iFileInfo);
filesize = iFileInfo.dwSize;
pBuf = (byte*) MALLOC (filesize + 4);
MEMCPY(pBuf, ph, 4);
pBuf2 = pBuf + 4;
pFunc = (RunLoadMod)pBuf2;
bytesread = IFILE_Read(piFile, pBuf2, filesize);
IFILE_Release(piFile);
IFILEMGR_Release(piFileMgr);
return pFunc(pIShell,ph,ppMod);

Can you help me to understand why I can’t start .MOD file I have loaded by modloader? I am doing all needed steps that you provided in your post and everything seems correct for me, but maybe you will find that I am doing something wrong.

Thanks in advance.

ed_est
View Public Profile
Send a private message to ed_est
Send email to ed_est
Find all posts by ed_est
Add ed_est to Your Buddy List

#10 01-13-2009, 08:44 PM
Brewin
Registered User Join Date: Mar 2006
Posts: 152
Rep Power: 4

Helper functions Entry point problem…..

——————————————————————————–

Quote:
Originally Posted by ed_est
MEMCPY(pBuf, ph, 4); *********
pBuf2 = pBuf + 4;
((RunLoadMod)pBuf2)(pIShell,ph,ppMod);

You problem is here. It not properly copying the ph pointer(Helper functions Entry point).
MEMCPY(pBuf, ph, 4);

__________________
Thanks everyone for the info they share here..
Ramki@TTSL
VALUE HAS A VALUE ONLY IF ITS VALUE IS VALUED

Brewin
View Public Profile
Send a private message to Brewin
Send email to Brewin
Find all posts by Brewin
Add Brewin to Your Buddy List

#11 01-14-2009, 06:17 AM
ed_est
Registered User Join Date: Jan 2009
Posts: 3
Rep Power: 0

Brewin,
Thank you very match for your help.
I have fixed the this part of code and now it works.

0

在BREW程序中调用另一个mod的分析


近日读到这样一段程序。可以在程序运行时调用另一个mod文件并执行。这样可以做到应用自升级,压缩程序文件等实用的功能。

 

 要想理解这点,先看一下正常的BREW程序加载过程。

 BREW程序的入口,即相当于c程序的main,是位于AEEModGen.c中的AEEMod_Load函数。这可以从mak文件的连接选项中看出来。

 

LINK_ORDER = -first AEEMod_Load

 

 这个选项使得链接程序将该函数放在程序文件的0地址处。函数的定义如下:

 

int AEEMod_Load(IShell *pIShell, void *ph, IModule **ppMod)

{

   // Invoke helper function to do the actual loading.

   return AEEStaticMod_New(sizeof(AEEMod),pIShell,ph,ppMod,NULL,NULL);

}

  

  BREW底层调用这个函数,需要提供三个参数。pIShell是ISHELL接口的指针,有了它就可以创建和访问其它接口。ph是helper function类函数的函数列表指针,有了它就可以调用MALLOC等函数。ppMod是用于返回给BREW底层的地址,存储生成的module的信息。

  AEEMod_Load函数调用了AEEStaticMod_New函数。在这个函数中初始化了module数据结构,ppMod就是指向它的。函数结束后返回BREW底层。

  BREW底层稍后通过存储在module数据结构中的函数指针,调用同样位于AEEModGen.c中的AEEMod_CreateInstance函数,生成该Module的某一个Applet实例。在这个函数中会调用到我们所编写的AEEClsCreateInstance函数。在我们这个函数中注册了HandleEvent函数和FreeAppDate函数。这些信息同样通过一个applet数据结构指针返回给BREW底层。这之后,BREW会通过给HandleEvent发各种Event,来驱动程序运行。

 

  通过这整个过程,可以总结出BREW程序运行的必要条件。

  程序必须得到IShell指针,Helper Function指针,这样程序中对BREW底层各种函数的调用才能进行。BREW底层必须知道两个地址,通过它们,可以将Event传递给程序,调用FreeAppDate函数。

  因此,想在程序中调用另外一个mod,只需要想办法把程序里的IShell指针,Helper Function指针传递给mod,同时得到mod中的HandleEvent函数,FreeAppDate函数的地址就可以了。

  剩下的问题就是,程序怎样和mod文件交互呢,mod文件的格式是怎样的?

 

  生成mod的mak文件最后一般有这样两句话,

 

ld *.o a.elf

fromelf –bin a.elf a.

 

  arm链接器ld生成ELF格式,之后用格式转换工具fromelf将ELF文件转换成mod文件。

  ELF文件是带格式的可执行文件,对它的执行要靠操作系统的解析来进行。而通过–bin选项生成的mod文件,格式却是plain binary,即赤裸裸的二进制机器指令,其实是无格式的。只要将mod文件载入内存,跳转到它的0地址处,就可以一条条指令的执行下来。和mod文件交互,也就是要安排好mod文件0地址处的内容,知道mod文件的调用者会传入什么东西,mod文件会返回什么东西。

 

  

  下面来看一种实际的调用方法吧。代码如下:

 

typedef int (*RunLoadMod)(IShell *pIShell, void *ph, IModule **ppMod);

 

pData = MyLoadZip(pIShell);

if( !pData )

return EFAILED;

DBGPRINTF(“to RunLoadMod”);

if( SUCCESS != ((RunLoadMod)pData)(pIShell,ph,&pOrgMod) )

{

DBGPRINTF(“RunLoadMod_Err”);

goto Crt_Err;

}

  

  这段程序将mod文件读入内存,放在pData缓冲区内,用((RunLoadMod)pData)(pIShell,ph,&pOrgMod)一句执行之。RunLoadMod只不过是用typedef定义的一种函数指针类型。这句话的意思相当于是为待调用的mod文件准备好pIShell,ph,pOrgMod三个数据后,直接跳到内存中的mod文件的第一个字节处,将它当做普通机器指令一样执行。这种方法调用的mod文件,应是一个用完整的BREW框架编译后生成的。0地址处放下的是AEEMod_Load函数。Mod文件直接将Applet信息传递给BREW底层,注册HandleEvent函数。实际上是Mod文件取代了调用者的位置。

  

  但是这段程序很可能会运行失败。因为BREW底层除了传参外,还做了其它事情。这在AEEStdlib.h中可以看出。

 

#define GET_HELPER()      (*(((AEEHelperFuncs **)AEEMod_Load) – 1))

#define GET_HELPER_VER()  (*((uint32 *)(((byte *)AEEMod_Load) – sizeof(AEEHelperFuncs *) – sizeof(uint32))))

 

  这两个宏定义可以看成是两个全局常量。第一个是BREW Helper Function的函数指针表,第二个是函数指针表的版本号。上面提到的通过参数传递Helper Function函数指针,是只在模拟器上成立的。手机上其实是通过全局常量形式传递的。为保证mod可以正常运行,也应在缓冲区前保存这两个常量。

 

  这种“冒名顶替”的方式,对于只想压缩一下mod的应用来说是完全可以的。但有时,我们希望新调用的mod只是整个应用的一小部分,调用者继续存在。这就需要调用者充当BREW底层的一部分角色,记住mod返回的各种信息,在适当的时候调用mod中的相应函数。新调用的mod如果想要取得主mod的信息,类似于上面提到的HelperFuncs全局常量指针的方法是个可行的选择。

 

  其实知道了BREW程序的加载过程,就可以比较灵活的达到调用mod的目的,甚至BREW程序架构都是可以改动的。但是改动之后,如何在模拟器上进行调试就又成了一个问题。

 

  程序中调用mod的技巧,在国外几年前就已得到了应用。甚至有家公司专门开发了利用这个技巧压缩mod的工具。

 

http://www.s-cradle.com/english/products/sophiacompress_/index.html

 

参考文章:

 

1.How to build A mod to load B mod?

 

http://brewforums.qualcomm.com/showthread.php?t=11637

 

2.How to run mod file that is loaded in the

 

http://brewforums.qualcomm.com/showthread.php?t=18413&highlight=

 

3.深入BREW模块加载机制

 

http://nicefuture.ycool.com/post.722858.html

 

4.深度剖析BREW实现原理收藏

 

http://blog.csdn.net/Gemsea/archive/2006/09/07/1190206.aspx

01

[转] 实现动态加载VXWORKS .O/.OUT模块


转至:http://www.cnblogs.com/hpunix/articles/355758.html

整个过程为:
创建文件系统–》下载文件–》加载模块–》查找符号地址并执行

以下为演示该过程的一个简易实现文件,有使用或者引用的话,也
打个招呼,或者给评论一下:
==============START OF THE FILE=============
/*********************************************************
 * 版权所有 NP系统工作室。
 * 
 * 文件名称:    \FilseSystemCreate.c
 * 文件标识:    
 * 内容摘要:    创建文件系统,在系统启动之后保存文件
 * 其它说明: 
 * 当前版本:    S 1.0
 * 作    者:    william
 * 完成日期:    2005-10-12 17:04
 * 当前责任人-1:william
 *
 * 修改记录1:   
 *    修改日期:2006-3-21 12:00
 *    版 本 号:S 1.0
 *    修 改 人:william
 *    修改内容:创建 
 * 修改记录2:
 **********************************************************/

#include <taskLib.h>
#include <.h>
#include <stdio.h>
#include <string.h> 
#include <ioLib.h >
#include <symLib.h >
#include <loadlib.h >

#include “dosFsLib.h”
#include “ramDrv.h”
#include “usrLib.h”

typedef int                       STATUS;
#define ERROR                     -1
#define OK                        0
#define DIAG_RAM_DISK_SIZE        (0×100000*10)  /* 64M */
#define DIAG_RAM_DISK_NAME        “/selfdev/”

STATUS FileSystem_Init()
{
    BLK_DEV     *pBlkDev;
    char        *pFileSysRamDiskBase = NULL;
    
    ramDrv();
    pFileSysRamDiskBase = malloc(DIAG_RAM_DISK_SIZE);
    if(NULL == pFileSysRamDiskBase)
        return ERROR;
        
    bzero(pFileSysRamDiskBase,DIAG_RAM_DISK_SIZE);

    pBlkDev = ramDevCreate( pFileSysRamDiskBase,  
                            /* start address */                
                            512,        
                            /* sector size */                                                  
                            64,     
                            /* sectors per track */                                                      
                            (int)(DIAG_RAM_DISK_SIZE/512),    
                            /* total sectors 64 MBytes */
                            0);                               
                            /* offset */
    if(NULL == pBlkDev)
    {
        free(pFileSysRamDiskBase);
        return ERROR;
    }

    if(NULL == dosFsMkfs (DIAG_RAM_DISK_NAME, pBlkDev))
    {
        free(pFileSysRamDiskBase);
        return ERROR;

    }

    return OK;
}

extern SYMTAB_ID sysSymTbl ;
void runModule()
{
    STATUS status=ERROR;
    int fd;     
    MODULE_ID hModule ;
    FUNCPTR taskEntry = NULL ;
    SYM_TYPE * pType ;

    if ((fd = open(“/selfdev/youown.o”, O_RDONLY, 0)) < 0) 
    {
          printf(“\nCannot open memory device.\n”);
          goto done;
    }
     
    if ((hModule=loadModule(fd,LOAD_ALL_SYMBOLS))==NULL)
    {
        printf(“loadModule error = 0x%x.\n”,errno) ;
        goto done;
    }
   
    status = symFindByName(sysSymTbl,
                           “willian_test”,
                           (char **)&taskEntry,pType ) ;
    if (status==ERROR)
    {
          printf(“symFindByName error=%d\\n”, errno) ;
          goto done;
    }
    else
    {
        printf(“taskEntryr=0x%x, type=%d\n.”,
                    (int)taskEntry,(int)*pType);         
        status = taskSpawn(“test1″,
                           100,
                           0,
                           30000,
                           taskEntry,
                           0,0,0,0,0,0,0,0,0,0) ;
        if (status==ERROR)
        {
            printf(“taskSpawn error=%d\n”,errno) ;
            goto done;
        }
    }
    
done: 
     if (fd >= 0)
       close(fd);    
}

 

int downLoadModules(
    char *hostName,
    char *srcfileName,
    char *destfileName,
    char *usr,
    char *passwd)
{
    ………
    /*实现下载远端PC模块到本地机*/

    return (filesize);
}

STATUS test_dynamic_download()
{
    STATUE status = OK;
    int fileLenth = 0;
    
    status = FileSystem_Init();
    if(status == ERROR)
    {
        printf(“\nerror occured during init file system\n”);
        return ERROK;        
    }
    
    fileLenth = downLoadModules(“winner2″,
                                “youown.o”,
                                “/selfdev/youown.o”,
                                “target”,
                                “target”);
    if(ERROR == fileLenth)
    {
        printf(“\nSome error occured when download files\n”); 
        return ERROK;                 
    }                                
    else
    {
        if(0 == fileLenth)  
        {
            return OK;    
        }
    }
    
    runModule();
}
=============END OF THE FILE==========

几个需要注意的问题:
1:在文件系统初始化中使用的是MALLOC,该部分是使用的实际是
   BSP的空间在实际申请的过程中一定要根据自己可能拷贝的文
   件大小和实际的BSP的空间

2:在创建文件系统之后,可以查看该目录的文件列表,或者执行
   COPY,前提是必须在TORNADO中选择初始化文件系统组件;
   
3:在下载文件的过程中,有的BSP初始化已经可以直接通过COPY
   在远端FTP SERVER直接拷贝文件,比如:
         copy “youown.o”,”/selfdev/youown.o”
   这种情况没有必要再调用downLoadModules,至于如何使能,
   大家关注的话可以在后边对其专门论述。     

4:加载模块的过程可以调用如下代码:
        if ((hModule=loadModule(fd,LOAD_ALL_SYMBOLS))==NULL)
    同样也可以如下实现:
        ld(1,0,”/selfdev/youown.o”);
    至于各个参数什么意思,参考HELP就可以找到结论了!
    
    
5:在    status = symFindByName(sysSymTbl,
                           “willian_test”,
                           (char **)&taskEntry,pType ) ;
   中,有可能实际返回错误,但是通过lkup 是可以实际找到的,
   对于这个问题,我看网上答案比较少,原因是这样的:
   
   假如你在主机运行shell,默认的远端目标机是没有符号表
   (symbol table)的,只有在主机的shell上,你运行LKUP的
   时候,才能找到这个符号,不信你可以这样尝试一下,打开两
   个SHELL,一个通过串口,一个通过TORNADO的网口,你在其中
   一个中能够使用LKUP找到,而在另外一个则不能找到,是不是
   呀??   
       接下来继续解释,我们的symFindByName是在目标机器上
   执行的,所以自然的就返回错误了,也是没有找到了!
       解决方法是这样的:在目标机中包含符号表,同时将其和
   主机保持同步。
   Wind River told us to include all this defines in the 
        config files for the target:
        
       #define INCLUDE_SYM_TBL_SYNC
       #define INCLUDE_LOADER
       /* object module loading */
       #define INCLUDE_NET_SYM_TBL  
       /* load the symbol table by whatever means */
       #define INCLUDE_SHELL 
       /* target-based shell */
       #define INCLUDE_SHOW_ROUTINES 
       /* optional target-based system utilities */
       #define INCLUDE_STAT_SYM_TBL  
       /* optional target error status routines */
       #define INCLUDE_SYM_TBL         
       /* symbol table package */
       #define INCLUDE_UNLOADER        
       /* optional object module unloading */
       #define INCLUDE_WDB

0

[转] 嵌入式单地址空间中实现动态加载的过程


转至:http://blog.csdn.net/pengzhenwanli/archive/2008/04/23/2319412.aspx#875603

之前有一篇文章是关于嵌入式单地址空间实现动态加载的想法,里面描述的是我根据相关资料进行猜测的地方,以及从技术上来说,可能需要的技术,最近难得有空闲时间,我实现了一下动态加载的。目前已经成功实现,下面说一下实现的过程。

先说一下实现此技术需要的平台:

OS

CPU7+cache

BasebandVT3406

ADS1.2

说一下这些东西的来历,Nucleus是实时嵌入式单地址空间操作系统,CPU是介于ARM7ARM9之间的CPUBB芯片是VIA出的,这些东西目前都已经收掉不再使用,我也正好离职,从而有时间去实现一下动态加载的问题。

从理论上来说,动态加载很简单,只需要把当前的PC指针指向下一句执行的语句即可。也就是使用如下的ASM就可以实现:

MOV PC, Address

       这样就可以顺利执行程序,在我实现的时候,考虑如下问题,程序执行如何返回,参数如何传递,程序执行完毕返回到哪里。

       这些问题的解决,看起来比较复杂,其实很简单,程序的返回是放在LR中,这样在上一个函数调用的时候,只要LR的值不变,这样可以在下一个函数调用的时候,同样使用LR,这样就可以顺利返回。关于参数传递,由于ARM中使用r0-r3传递参数,这样只要不更改r0-r3,就可以顺利传递参数。这个地方想明白,我用了好久,特别是返回地址的问题,程序如何执行,应该返回哪里。解决方法如下

       实现DynamicLoader(UINT8 *pAddress)

MOV PC, R0

这个地方一定要用ASM实现,否则无法完成需要的功能。由于在调用此函数时,已经把函数的返回地址放到LR中,具体ASM如下:

MOV r0,address

BL DynamicLoader

       由于DynamicLoaer的实现问题,没有实际的返回,也就是不需要使用

BX lr

       这样来做为函数的返回。这是由于R0所指向的一个函数的开始地址,从DynamicLoader开始,其实执行的是另一个函数,这里的DynamicLoader只是起到了一个跳转的作用。但是又必须使用函数调用的方式来进行,而不能直接跳转,否则函数没有办法返回。由于BL的时候填充了LR,这样在下一个由于实际调用不是使用的B指令,因为并没有设置LR,这样仍旧是在调用DynamicLoader时的LR,因此可以正确返回。

       函数可以正确调用并返回,这是程序很大的一个进步,这样就可以实际构造可以运行的程序了。

       下面说一下ADS编译为二进制可执行文件的问题,使用编译器如果一开始把所有的数据都放好,这样包括全局变量和静态变量,以及函数的执行地址等,都已在LINK的时候根据指定规则确定实际的运行地址,也就是说所有的函数的实际运行地址在LINK的时候已经确定。这样对于动态运行来说是不可行的,因为既然要动态加载,就需要所有地址都是静态的,因为每次对于读入内存的数据,起始地址是不缺定的,因此不能再LINK时把所有的地址固定死。

       解决这个问题有两种方式,一种是在scatter loader中把程序的可执行地址固定好,在LINK时不LINK实际的数据,而在系统启动的时候,把这部分可执行文件拷贝的固定的地址,这样可以作为一个整体运行。但是这种方式由问题,就是应用的大小什么的都是固定死的,不能太灵活,不能根据应用实际调整。

       这里使用另外一种方式,选择程序不在LINK的时候把所有的地址固定死,而是使用相对独立的函数调用方式。如下:

       原来的方式可能使这这样

       BL 0×10008;

       而使用相对的地址程序如下:

       ADD r5,pc,#18

       BL r5

       这样虽然多了一句,但是可以做到函数的运行地址是动态指定的,而不是编译为固定的地址。

       其实ADS提供了把函数编译为独立地址的方式,

       COMPILER使用如下的参数/ropi/rwpi

       LINK使用如下的参数-rwpi –ropi

       就可以把编译的程序做到运行时地址是独立的。

       从上面来开,编译时地址的问题,还有运行时加载的问题,都已经顺利解决。但是这里还有一个问题,就是如何确保动态应用如何每次在使用的时候,都从固定的入口进入的问题。也就是说,虽然有了内存中的运行地址,但是如何保证每次都从固定的函数开始执行呢?如果每次都从编译的可执行文件0地址开始执行,没有办法保证每次调用的是同一个函数。

       这个可以通过LINK来保证每次是同一个函数在0地址,使用如下的参数

-first DyanmicAppEntry

       这样就可以保证DyanmicAppEntry的入口地址为可执行文件的开始了。

       上面的文章解决了动态编译和加载的问题,下面说一下动态应用的问题。如果要使一个应用有价值,比然需要提供本地的功能调用,而且对于手机来说,系统已经基本上实现了大多数的功能,如果在动态应用中再重复实现一些功能,可以说既浪费了空间,又浪费了时间。而且对于硬件相关的功能,必须通过本地调用来进行,这样就需要如何把本地调用传入动态应用中。如上文所说,本地的调用地址都是在LINK的时候确定的没有办法直接在动态应用中使用,这样需要在运行时把本地调用传入动态应用,由于动态应用的入口还有好几个参数可以使用,这样就可以构造一张系统调用的表,在运行的时候传入动态应用,这样可以通过表来调用系统功能,这样就解决了系统本地调用的问题。

       这里要特别说一下安全的问题,由于动态应用是直接更改PC指针运行的,这样,如果应用出错,系统可能就CRASH了,无法再继续运行,而且由于可以调用本地系统调用,可能做许多意想不到的功能,这样就可以在系统调用的时候

增加一个中间层,一些核心功能,必须满足一定的权限在可以调用。

0

[转] 在嵌入式单地址空间OS中实现动态加载的问题


转至:http://blog.csdn.net/pengzhenwanli/archive/2007/02/26/1514689.aspx

本文的的主要想法是来源于手持设备可运行应用程序和如何实现智能机问题的思考。问题的主要来源是关于可扩充应用程序的考虑,目前大部分手机都是非智能机,也就是不能扩充应用程序

1.智能手机与非智能手机
        一般来说,智能手机目前公认三大系统,Windows Mobile,Linux和Symbian,也即是说采用这三种系统的手机,都成为智能机。我认为,从技术上来讲,智能机最主要的特征就是第一可扩充应用程序,也就是说用户可以自行安装需要的程序而不局限于手机自带的,第二就是多用户任务,也就是用户具有同时运行多个应用程序的权力。而非智能手机的操作系统可以说是五花八门,什么都有。但是基本上都有一个核心的特征,就是同时只能运行一个应用程序,而且所有的应用程序都运行在相同的地址空间,而智能机是运行在独立地址空间。一般来说,非智能机也支持多任务,不同的是这些任务共用相同的地址空间。用户操作的UI就是一个单独的任务,用户所能使用的功能基本上就是由UI提供的。
        我原来对于非智能机是非常的不屑,认为没有什么发展前途,但是我最近又弄了一个非智能机的手机用了一下,发现很多功能都非常的人性化,从使用上来讲,并不亚于智能机,由此引发了我对于非智机功能的思考。对于智能机来讲可扩充的应用程序一般来说,都是由第三方开发商开发的,稳定性都有所缺陷,并不如原生的系统应用程序稳定。而且有些比较好的用程序价格不菲,我见过使用智能机的人大部分都是使用破解的应用程序,我本人也是。这个行为是违法的,当市场成熟以后,比如像美国,是不太可能的。

        智能机由于操作系统功能强大,一般要求系统的硬件性能强劲,这样相应的功耗也大,待机时间相应的缩短。非智能机可以运行在性能较差的硬件上,并且获得的UI表现,不弱于智能机。这样就可以在相同的电力消耗的情况下,获得更长的使用时间。
2.非智能机获得智能机功能必须的要求
        如上文所说,只要非智能机实现智能机最主要的两个特征即可获得智能机的功能。一个是用户自行安装应用程序的功能。另一个是同时运行多个应用程序的功能。
3.用户自行安装应用程序的功能
        除了智能机以外,目前有两种技术都实现了用户可自行安装应用程序的功能,一个是BREW另一个是Java ME(J2ME)。下面分别说一下这两种技术,BREW技术由Qualcomm(高通)创建,包括一整套的体系,从运营到分发都有。在本文里只是对于客户端技术的说明,对于BREW技术而言,已经非常符合本文中所提及的技术,本文从另一方面来讲,也可以说是分析了BREW的基本技术。BREW技术高通把持的非常严密,目前而言,并没
有开放源代码而且对于技术内部也是进行严密的封锁,因此目前出现的文章都是猜测技术的实现,但是对于技术来讲,万变不离其宗,要实现某种技术,有些东西是绕不开的,就像使用CDMA技术,无论是WCDMA,CDMA2000,还是TDS-CDMA都无法绕开CDMA的基本专利一样。BREW技术基本达到了本文的技术要求,既能动态加载,也能同时运行多个任务,而且对于系统功能的使用不像JavaME一样有严重的限制,基本上来说,可以使用系统提供的所有功能。而对JavaME,所提供的功能十分有限,就连存取本地文件都不可以。对于系统功能的使用,如果没有附加的支持,基本上不可能,目前应用最得的是游戏,最多有些网络方面的应用。对于提供系统级别的应用,比如说闹钟等,根本无能为力。也许以后能够提供,但是本人不太看好。另外还有一个就是Flash Lite技术,这个技术我并没有接触,就不详细说了。对于BREW和JavaME我都有相当长时间的接触,了解也比较细致,有些问题还是能够说一下的。
        要解决用户可以自行安装应用程序的问题,必须解决以下几个问题,应用程序的加载运行问题,系统API的调用问题。
3.1应用程序加载
        对于嵌入系统来讲,与通常的Windows系统不一样,Windows的所用应用程序都在硬盘上,运行的时候根据需要加载到内存中,在运行,或者是使用虚拟内存技术,直接映射的硬盘也可以执行。而嵌入式系统通常是在ROM中,并不需要加载到内存才能运行,直接就可以运行,因此大部分的嵌入式系统都是统一做好一个系统的Image,然后放到ROM中运行。这样所有的地址都在编译期间确定,要是再动态加载应用程序,将会面临运行时地址确认的问题。一般而言,对于嵌入式系统,ROM使用Flash来代替,Flash中一部分作为ROM,另一部分作为嵌入式的文件系统,具体的系统格式这里不作考虑。要是可加载应用程序的话,一般来说是放在文件系统中。这样要运行可动态加载的应用程序,并不复杂,只要把应用程序调入内存中,运行时设置正确的寄存器就可以了。

这里也就是把可执行的文件加载到内存中,由于是单地址空间的,而不是像Windows一样每个应用程序都是独立的地址空间,这样应用程序可以从任意地址开始执行,这样载入内存以后,把当前的执行指针PC这为此内存地址即可。这也是单地址空间的程序可以执行的关键。

3.2系统API的提供

 要提供可以运行时call的API,在单地址空间可加载应用程序的约束条件下,可以使用的方法也非常的单调。一般来说,单地址空间的应用程序是统一编译和链接的,这样生成可执行文件以后,所有的地址已经固定了,这样如3.1所说,应用程序如果每个都调用相同的系统API,比如memset等,由于应用程序时独立加载的,这样由于在编译过程中已经把所有的地址确定,所以每个应用必须链接独立的lib,这样造成了空间浪费。如果只是单独的应用,不提供这一步,系统已经可以动态加载了。

但是目前是要求在嵌入式单地址空间实现,必须考虑空间的问题。因此必须解决系统库可以动态加载的问题。也就是库的地址不是在链接的时候确定。只要能够解决编译时的链接问题,就可以做到。

关于
4.同时运行多个应用程序的功能

Random Posts Recent Comments

  • 女友糖尿病害我蛀牙 Says:

    汗一个…...

  • Htj06 Says:

    zhenyouchuangyi...

  • 电商圈 Says:

    试图该怎么建立啊,,怎在程序中是吸纳...

  • edward Says:

    看得人心旷神怡,好文,情不自禁的顶一下...

  • Daniel Says:

    我也在处理这个问题,没有找到好的方法。我用了楼上兄弟的方法,还是可以的。不知道您找到好的方法了吗、我暂时楼上兄弟的方法。...

  • 卡,卡 Says:

    弱弱问一句:博主,你博客的模板这样设计pv高吗?...

  • 站长工具 Says:

    博主,兔年快乐!...

  • health Says:

    great post!!I hope I can read more in your website....

  • pdu Says:

    好博文,支持分享...

  • 站长工具 Says:

    博主的文章很不错,我是站长工具-站长精灵的作者,一款专业的SEO工具软件(可以帮您提高博客的流量),想跟您交换个链接,不知可否...

Tag Cloud

arm audio blog brew cache class debug flash google html j2me java javascript Joke linux lua mobile mtk php python ror ruby server shell stream unix web windows 优化 动态加载 女人 女生 平台 开发 手机 技术 流媒体 测试 漫画 生活 男人 男生 缓存 芯片