我的进阶曲线之一



在Linux中文件名前加上.表示是一个隐藏文件。


U-Boot可支持的主要功能列表:
* 系统引导;
* 支持NFS挂载、RAMDISK(压缩或非压缩)形式的根文件系统;
* 支持NFS挂载、从FLASH中引导压缩或非压缩系统内核;
* 基本辅助功能 强大的操作系统接口功能;可灵活设置、传递多个关键参数给操作系统,适合系统在不同开发阶段的调试要求与产品发布,尤对Linux支持最为强劲;
* 支持目标板环境参数多种存储方式,如FLASH、NVRAM、EEPROM;
* CRC32校验,可校验FLASH中内核、RAMDISK镜像文件是否完好;
* 设备驱动 串口、SDRAM、FLASH、以太网、LCD、NVRAM、EEPROM、键盘、USB、PCMCIA、PCI、RTC等驱动支持;
* 上电自检功能 SDRAM、FLASH大小自动检测;SDRAM故障检测;CPU型号;
* 特殊功能 XIP内核引导;
4工作模式
U-Boot的工作模式有启动加载模式和下载模式。启动加载模式是Bootloader的正常工作模式,
嵌入式产品发布时,Bootloader必须工作在这种模式下,Bootloader将嵌入式操作系统从FLASH中加载到SDRAM中运行,整个过程是自动的。
下载模式就是Bootloader通过某些通信手段将内核映像或根文件系统映像等从PC机中下载到目标板的FLASH中。用户可以利用Bootloader提供的一些命令接口来完成自己想要的操作。


x86架构的指令说明:
esp:寄存器存放当前线程的栈顶指针
ebp:寄存器存放当前线程的栈底指针
eip:寄存器存放下一个CPU指令存放的内存地址,当CPU执行完当前的指令后,从EIP寄存器中读取下一条指令的内存地址,然后继续执行。


常见场景:
push ebp ; 保存当前ebp
mov ebp,esp ; EBP设为当前堆栈指针
sub esp, xxx ; 预留xxx字节给函数临时变量




arm架构的指令说明:


常见场景:
my_function_name
        MOV     ip, sp
        STMFD   sp!, {fp, ip, lr, pc}
        SUB     fp, ip, #4

总之,不管x86还是arm,在新的一个栈帧创建的起始位置(4*4个字节) 都会保存前一个栈帧的起始地址。这样就保证了可回溯。




ANR log:
//依次是:线程组名称、suspendCount、debugSuspendCount、线程的Java对象地址、线程的Native对象地址
| group="main" sCount=1 dsCount=0 obj=0x4025b1b8 self=0xce68


page cache:
例如内存管理的slab缓存是一个内存到内存的缓存,其目地不是加速对低速设备的操作,而是对现有资源进行更简单、更高效的使用。文件系统的Dentry缓存也用于减少对低速块设备的访问


4G = 0X100000000


Init进程一起来就根据init.rc和init.xxx.rc脚本文件建立了几个基本的服务:
 servicemanamger
 zygote
 
 
ActivityManagerService服务(简称是AMS服务)是管理android概念空间中的四大组件,包括Activity,Service,等的管理,生命周期的管理,状态维护等工作,
注意,它是管理所有手机中所有应用程序的组件,并不是单独管理一个程序。
WindowManagerService服务(简称是WMS服务)主要是管理Activity中窗口的管理,是管理手机中所有程序所有activity中的所有窗口,并不单间是管理一个程序中的窗口,


用tar打包必须设定是gzip打包还是bz,若gzip则tar zcf。
tar -czvf /mnt/hgfs/shared/aKK.tar.gz a4.4/ ---------- compress/inflate
解压到指定的目录 tar -zxvf /home/images.tar.gz -C /specific dir


NEGATIVE 消极


WakeLock是一种锁机制,只要有人拿着这把锁,系统就无法进入休眠阶段。既然要保持应用程序一直在后台运行,那自然要获得这把锁才可以保证程序始终在后台运行。之前我做过一个需求是要在后台跑一个Service执行轮询,但发现一段时间以后,轮询就中断了(我测试是二十分钟后请求停止),但重新解锁屏幕后,轮询请求又开始了


GC并不能防止Memory Leaks,所谓Memory Leaks就是引用到了已经没用的对象从而让这些对象避免了被GC回收,跟C/C++中的概念并不一样。


class BpServiceManager : public BpInterface<IServiceManager>
//这种继承方式,表示同时继承BpInterface和IServiceManager,这样IServiceManger的
addService必然在这个类中实现


那我怎么和ServiceManager通讯呢?恩,利用BpServiceManager。所以嘛,我调用了BpServiceManager的addService函数---就是说,和ServiceManager的交互,仍然采用binder机制。


64位系统安装后没有默认安装glibc的32位版本,通过简单的执行以下命令即可实现在64位Linux系统上开发运行32位应用程序,而不用重新安装操作系统。


idle就是待机
threshold就是边界,底线
bucket桶
implicitly隐式的(非显式)
eventually终于
bogus假冒的伪造的
deferred递延 latency 
Transact办理
suspicious可疑的
optimization优化
exemption豁免
launder清洗
  
touch命令:
修改一个文件的访问生成时间


diff和patch命令:
diff -uN test0 test1 > test1.patch 生成两个文件的差异补丁文件
patch -p0 < test1.patch 把补丁打到参与比较的前者文件里面 --- 使用时候请自己据此把握比较顺序哦!
patch -RE -p0 < test1.patch 打过补丁后,又恢复前者文件 


zram可以让Linux在需要大量RAM的情况下在内存上进行交换/分页,而提高内存的使用率,显著得减少系统启动时(此时Linux还不能使用外部存储)对内存大小的要求。


内存只有在要被DMA访问的时候才需要物理上连续
vmalloc kmalloc  是用来分配内核空间内存的,malloc是用来分配用户空间的内存的 --- 都是不可重入的(GFP_KERNEL?GFP_ATOMIC?)
Linux2.6支持非统一内存访问(NUMA)模型,在这种模型中,给定CPU对不同内存单元的访问时间可能不一样。
对于用户空间普通的内存分配(堆空间、栈空间),都属于匿名映射。
高端内存的最基本思想:借一段地址空间,建立临时地址映射,用完后释放,达到这段地址空间可以循环使用,访问所有物理内存。
高端内存可以映射整个物理内存。如果是位于非高端内存的页框,因为已经有线性映射,所以直接返回线性地址即可。
大于896M的场景,此时896M和实际物理内存之间的就属于高端内存。
虚拟地址是宝贵资源!页这个概念完全是人为创造的,为了管理页,人们又创造了页框的概念。


the general (academic) definition of footprint includes all kinds of memory/storage aspects.


页框和页,我来画个最简单的图
下面整张表就是页框,以数组形式保存(在最新的内核中开始用链表形式了),默认每页4K大小。
page mem_map[pfn];
pfn就是数组下标,叫做页框号
------------
|页描述符,数据结构page --- 代表了一份4K大小的页哦
------------
|页描述符,数据结构page
------------
|页描述符,数据结构page
------------
|页描述符,数据结构page
------------
|
现在,知道了虚拟地址可以用宏来求对应的virt_to_page(addr)/page_to_pfn(pg)


if (likely(value))等价于if (value)
表示value的值为真的可能性更大。
if (unlikely(value))等价于if (value)
表示value的值为假的可能性更大。


它将1G内核线性地址空间分为2部分,第一部分为1G的前896M,这部分内核线性空间与物理内存的0~896M一一映射,第二部分为1G的后128M的线性空间,拿来动态映射剩下的所有物理内存。 ---x86 方案哦,和arm不一样!
内核线性地址空间的最后128M用来映射高端内存页框,其方式有三种:永久内核映射,临时内核映射,非连续内存分配。
所谓的建立高端内存的映射就是能用一个线性地址来访问高端内存的页。如何理解这句话呢?在开启分页后,我们要访问一个物理内存地址,需要经过MMU的转换,也就是一个32位地址vaddr的高10位用来查找该vaddr所在页目录项,用12-21位来查找页表项,再用0-11位偏移和页的起始物理地址相加得到paddr,再把该paddr放到前端总线上,那么我们就可以访问该vaddr对应的物理内存了。在低端内存中,每一个物理内存页在系统初始化的时候都已经存在这样一个映射了。而高端内存还不存在这样一个映射(页目录项,页表都是空的),所以我们必须要在系统初始化完后,提供一系列的函数来实现这个功能,这就是所谓的高端内存的映射。那么我们为什么不再系统初始化的时候把所有的内存映射都建立好呢?主要原因是,内核线性地址空间不足以容纳所有的物理地址空间(1G的内核线性地址空间和最多可达4G的物理地址空间),所以才需要预留一部分(128M)的线性地址空间来动态的映射所有的物理地址空间,于是就产生了所谓的高端内存映射。


编译64位程序,需要加上-m64编译器参数,默认安装的gcc已经支持该参数 --- x86哦


R13 也被指为 SP, the Stack Pointer.
R14 也被指为 LR, the Link Register.
R15 也被指为 PC, the Program Counter.


当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行。
到目前为止,更需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。


dropbox日志文件的命名有一定的规则,其前缀都是一个特定的tag(标签),
tag由两部分组成,合起来是“进程类型_事件类型”。


真正的改变,都发生在一小时外。


if( setfsuid(503) < 0) perror ("setfsuid error");
FILE * fp = fopen("test.log", "a+"); --- 这两句代码表示,先把用户设置成503,再以503用户去创建/打开这个文件。


pm list packages -f
org.cocos2dx.FishingJoy2


umask(0);--- 表示后续创建文件都要以此来做掩码,就是要和 ~mask 与一下。如下:
        umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);  
        if (creat("bar", RWRWRW) < 0)  mode & (~cmask) = 110 110 110 & 111 001 001 = 110 000 000 所以bar文件的权限为rw------
可以用 setsid() 建立新会话,则该进程会变成新会话的首进程,同时成为一个新进程组的组长进程,该进程没有控制终端。


fastboot flash boot boot.img


使用android.util.Log.wtf() --- 不一定是bug,需要打印callstack的时候都可以用它。
我们可以直接使用android提供的android.util.Log.wtf()系列函数来输出一个日志.在输出日志的同时,它会把此处代码此时的执行路径(调用栈)打印出来。
示例2:
Log.wtf(tag, "this a fake erro");


adb shell dumpsys gfxinfo com.xxxx.xxx
可以使用adb shell dumpsys meminfo -a <process id>/<process name>来查看一个进程的memory。


从/proc/pagetypeinfo看到我们可以得到的最大连续内存为2^7个page,即512KB。


我们知道,对于操作系统来说,一个shell下的每一个程序的堆栈段开始地址都是相同的   


objdump -D vmlinux > vmlinux.dis 对内核镜像进行反汇编 前提是内核不要压缩,make bzImage 这样编译出来内核是压缩的。make vmlinux 表示对生成的内核镜像不压缩。


axf/elf等编译文件也叫符号文件,即在文件中把源码的符号表(函数/变量等)保存下来了,供调试时使用,但里面的符号表只是起定位作用,在调试时还需要有目标源代码,否则只能进行汇编级调试
data.load.elf E:/source/test.elf /PATH E:/source
这里的 /PATH 选项是用来指明源代码的路径,在调试时 TRACE 就可以查找到源代码了。 这里 TRACE 会根据 .elf 文件里包含的目标代码起始地址加载到 RAM 的对应地址上,也可以指定加载到 RAM 的地址,但须和编译时的设置一致,否则程序不能正常运行。


pfn 就是pte表的索引啊骚年!
该如何理解本地binder对象和远程handle对象呢?其实它们都指向同一个对象,不过是从不同的角度来说。举例来说,假如A有个对象X,对于A来说,X就是一个本地的binder对象;如果B想访问A的X对象,这对于B来说,X就是一个handle。因此,从根本上来说handle和binder都指向X。本地对象还可以带有额外的数据,保存在cookie中。


三次握手的本质是:保证数据传输的可靠性!只有三次,才能保证 1 客户端知道服务器收到(客户端发出的)信息。2 服务器端知道了(客户端收到服务器端的确认)信息。


Try pressing Ctrl+Shift+O, Eclipse will automatically add the import statement if missing.


R.S.V.P.
=Répondez s'il vous plait.(法语)
=Reply, if you please.


戴维斯双杀效应 股价较低时候,受到预期的影响明显增大。


/dev/ion,android ion驱动设备。


malloc仅仅用于用户空间。用户空间和内核空间分配方案不一样。


从局部性原理来讲,连续申请分配内存的代码总是 趋向于有共同的生命周期,它们释放的chunk也就有很大的机会合并成一个大的chunk。


干股是指未出资而获得的股份,但其实干股并不是指真正的股份,而应该指假设这个人拥有这么多的股份,并按照相应比例分取红利。干股的概念往往存在于民间,特别是私营企业,在私企的老板们给予干股的时候,有的会签署一些协议,有的没有,但是基本上无论哪种,持有干股的人都不具有对公司的实际控制权(有实际控制权的是“实际控制人”)。所以,这种干股协议不如叫做分红协议更加贴切。


原始股是公司上市之前发行的股票。 在中国证券市场上,“原始股”一向是赢利和发财的代名词。在中国股市初期,在股票一级市场上以发行价向社会公开发行的企业股票,投资者若购得数百股,日后上市,涨至数十元,可发一笔小财,若购得数千股,可发一笔大财,若是资金实力雄厚,购得数万股,数十万股,日后上市,利润便是数以百万计了。这便是中国股市的第一桶金。


oom_adj 越大越容易被杀。


Printk打印进程信息,进程名将会被截短到 15 个字符


chrome://tracing/


VSS 虚拟 RSS 驻留 PSS 比例 USS 独占 内存。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值