當前位置:首頁 » 操作系統 » 乾瞪眼源碼

乾瞪眼源碼

發布時間: 2022-08-05 23:37:34

① 如何從boot.img提取ramdisk文件

首先你要有一個用戶解鎖fastboot的手機,這樣才能允許你刷入第三方ROM
其次你要能找到當前版本所對應的boot.img或sec_boot.img(帶簽名),通常能拿到的也就是刷機包裡面解出來的sec_boot.img,通過cat mtd出來的不知道行不行=。=

工具:
split_bootimg.pl
mkbootfs和mkbootimg

1)sec_boot.img是經過簽名的,需要把文件前0x1000個位元組刪除,也就是ANDROID! 8個字元前面所有位元組刪除,保存為boot.img

2) 運行perl split_bootimg.pl boot.img解出kernel和ramdisk文件,同時記下運行結果中的「Command line: vmalloc=384M mem=2044m@0x200000。。。。」一長串字元備用

3)運行指令把ramdisk的文件解出來
mkdir ramdisk
cd ramdisk
gzip -dc ../boot.img-ramdisk.gz | cpio -i
cd ..

4)修改其中的文件,例如我覺得default.prop裡面的persist.sys.usb.config=manufacture,adb不太爽,想改成=adb,修改保存。如果你想adb有root許可權的話,就去改ro.secure和ro.debuggable

5)重新打包
mkbootfs ./ramdisk | gzip > ramdisk-new.gz
當然如果你自己編譯的mkbootfs也沒有加到path里,就把編譯完的程序考到當前目錄,運行./mkbootfs...
生成boot-new.img
mkbootimg --cmdline '單引號裡面這一段拷貝剛才記下的Command line冒號後面的一長串' --kernel boot.img-kernel --ramdisk ramdisk-new.gz -o boot-new.img

6) 現在如果把生成的boot-new.img直接刷進去,手機就起不來了,問題在於kernel,ramdisk,second stage,tags的地址,
自己編譯的mkbootimg查看一下.c文件就知道base=0x10000000,生成的boot-new.img是按照這個規則來的:
kernel地址=base + 0x00008000,ramdisk地址=base + 0x01000000,
second stage地址=base + 0x00f00000,tags地址=base + 0x00000100。
這跟原始sec_boot.img裡面的地址是不一樣的,本想找到正確的base值,但原始img的幾個地址並非此規律,拿不到源碼只能乾瞪眼嘍,
最簡單的辦法就是用16進制編輯器將boot-new.img對應的4個地址修改為原始值,如圖:

7)保存後就可以fastboot刷入這個boot了,然後就是驗證一下能否啟動啦^_^,啟動不了也不至於變磚,因為咱recovery和fastboot沒刷,可以利用這兩種方法恢復

linux下的PID,PIDD是什麼他們之間的關系以及應用是什麼

在 Linux 底下執行一個指令時,系統會給予這個動作一個 ID, 我們稱為 PID,而根據啟用這個指令的使用者與相關的指令功能,而給予這個特定 PID 一組許可權, 該指令可以進行的行為則與這個 PID 的許可權有關。

linux進程簡介
Linux是一個多任務的操作系統,也就是說,在同一個時間內,可以有多個進程同時執行。如果讀者對計算機硬體體系有一定了解的話,會知道我們大家常用的單CPU計算機實際上在一個時間片斷內只能執行一條指令,那麼Linux是如何實現多進程同時執行的呢?原來Linux使用了一種稱為"進程調度(process scheling)"的手段,首先,為每個進程指派一定的運行時間,這個時間通常很短,短到以毫秒為單位,然後依照某種規則,從眾多進程中挑選一個投入運行,其他的進程暫時等待,當正在運行的那個進程時間耗盡,或執行完畢退出,或因某種原因暫停,Linux就會重新進行調度,挑選下一個進程投入運行。因為每個進程佔用的時間片都很短,在我們使用者的角度來看,就好像多個進程同時運行一樣了。

在Linux中,每個進程在創建時都會被分配一個數據結構,稱為進程式控制制塊(Process Control Block,簡稱PCB)。PCB中包含了很多重要的信息,供系統調度和進程本身執行使用,其中最重要的莫過於進程ID(process ID)了,進程ID也被稱作進程標識符,是一個非負的整數,在Linux操作系統中唯一地標志一個進程,在我們最常使用的I386架構(即PC使用的架構)上,一個非負的整數的變化范圍是0-32767,這也是我們所有可能取到的進程ID。其實從進程ID的名字就可以看出,它就是進程的身份證號碼,每個人的身份證號碼都不會相同,每個進程的進程ID也不會相同。

一個或多個進程可以合起來構成一個進程組(process group),一個或多個進程組可以合起來構成一個會話(session)。這樣我們就有了對進程進行批量操作的能力,比如通過向某個進程組發送信號來實現向該組中的每個進程發送信號。

最後,讓我們通過ps命令親眼看一看自己的系統中目前有多少進程在運行:

$ps -aux(以下是在我的計算機上的運行結果,你的結果很可能與這不同。)
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.4 1412 520 ? S May15 0:04 init [3]
root 2 0.0 0.0 0 0 ? SW May15 0:00 [keventd]
root 3 0.0 0.0 0 0 ? SW May15 0:00 [kapm-idled]
root 4 0.0 0.0 0 0 ? SWN May15 0:00 [ksoftirqd_CPU0]
root 5 0.0 0.0 0 0 ? SW May15 0:00 [kswapd]
root 6 0.0 0.0 0 0 ? SW May15 0:00 [kreclaimd]
root 7 0.0 0.0 0 0 ? SW May15 0:00 [bdflush]
root 8 0.0 0.0 0 0 ? SW May15 0:00 [kupdated]
root 9 0.0 0.0 0 0 ? SW< May15 0:00 [mdrecoveryd]
root 13 0.0 0.0 0 0 ? SW May15 0:00 [kjournald]
root 132 0.0 0.0 0 0 ? SW May15 0:00 [kjournald]
root 673 0.0 0.4 1472 592 ? S May15 0:00 syslogd -m 0
root 678 0.0 0.8 2084 1116 ? S May15 0:00 klogd -2
rpc 698 0.0 0.4 1552 588 ? S May15 0:00 portmap
rpcuser 726 0.0 0.6 1596 764 ? S May15 0:00 rpc.statd
root 839 0.0 0.4 1396 524 ? S May15 0:00 /usr/sbin/apmd -p
root 908 0.0 0.7 2264 1000 ? S May15 0:00 xinetd -stayalive
root 948 0.0 1.5 5296 1984 ? S May15 0:00 sendmail: accepti
root 967 0.0 0.3 1440 484 ? S May15 0:00 gpm -t ps/2 -m /d
wnn 987 0.0 2.7 4732 3440 ? S May15 0:00 /usr/bin/cserver
root 1005 0.0 0.5 1584 660 ? S May15 0:00 crond
wnn 1025 0.0 1.9 3720 2488 ? S May15 0:00 /usr/bin/tserver
xfs 1079 0.0 2.5 4592 3216 ? S May15 0:00 xfs -droppriv -da
daemon 1115 0.0 0.4 1444 568 ? S May15 0:00 /usr/sbin/atd
root 1130 0.0 0.3 1384 448 tty1 S May15 0:00 /sbin/mingetty tt
root 1131 0.0 0.3 1384 448 tty2 S May15 0:00 /sbin/mingetty tt
root 1132 0.0 0.3 1384 448 tty3 S May15 0:00 /sbin/mingetty tt
root 1133 0.0 0.3 1384 448 tty4 S May15 0:00 /sbin/mingetty tt
root 1134 0.0 0.3 1384 448 tty5 S May15 0:00 /sbin/mingetty tt
root 1135 0.0 0.3 1384 448 tty6 S May15 0:00 /sbin/mingetty tt
root 8769 0.0 0.6 1744 812 ? S 00:08 0:00 in.telnetd: 192.1
root 8770 0.0 0.9 2336 1184 pts/0 S 00:08 0:00 login -- lei
lei 8771 0.1 0.9 2432 1264 pts/0 S 00:08 0:00 -bash
lei 8809 0.0 0.6 2764 808 pts/0 R 00:09 0:00 ps -aux

以上除標題外,每一行都代表一個進程。在各列中,PID一列代表了各進程的進程ID,COMMAND一列代表了進程的名稱或在Shell中調用的命令行,對其他列的具體含義,我就不再作解釋,有興趣的讀者可以去參考相關書籍。

getpid

在2.4.4版內核中,getpid是第20號系統調用,其在Linux函數庫中的原型是:

#include<sys/types.h> /* 提供類型pid_t的定義 */
#include<unistd.h> /* 提供函數的定義 */
pid_t getpid(void);

getpid的作用很簡單,就是返回當前進程的進程ID,請大家看以下的例子:

/* getpid_test.c */
#include<unistd.h>
main()
{
printf("The current process ID is %d
",getpid());
}

細心的讀者可能注意到了,這個程序的定義里並沒有包含頭文件sys/types.h,這是因為我們在程序中沒有用到pid_t類型,pid_t類型即為進程ID的類型。事實上,在i386架構上(就是我們一般PC計算機的架構),pid_t類型是和int類型完全兼容的,我們可以用處理整形數的方法去處理pid_t類型的數據,比如,用"%d"把它列印出來。

編譯並運行程序getpid_test.c:

$gcc getpid_test.c -o getpid_test
$./getpid_test
The current process ID is 1980
(你自己的運行結果很可能與這個數字不一樣,這是很正常的。)

再運行一遍:

$./getpid_test
The current process ID is 1981

正如我們所見,盡管是同一個應用程序,每一次運行的時候,所分配的進程標識符都不相同。

fork

在2.4.4版內核中,fork是第2號系統調用,其在Linux函數庫中的原型是:

#include<sys/types.h> /* 提供類型pid_t的定義 */
#include<unistd.h> /* 提供函數的定義 */
pid_t fork(void);

只看fork的名字,可能難得有幾個人可以猜到它是做什麼用的。fork系統調用的作用是復制一個進程。當一個進程調用它,完成後就出現兩個幾乎一模一樣的進程,我們也由此得到了一個新進程。據說fork的名字就是來源於這個與叉子的形狀頗有幾分相似的工作流程。

在Linux中,創造新進程的方法只有一個,就是我們正在介紹的fork。其他一些庫函數,如system(),看起來似乎它們也能創建新的進程,如果能看一下它們的源碼就會明白,它們實際上也在內部調用了fork。包括我們在命令行下運行應用程序,新的進程也是由shell調用fork製造出來的。fork有一些很有意思的特徵,下面就讓我們通過一個小程序來對它有更多的了解。

/* fork_test.c */
#include<sys/types.h>
#inlcude<unistd.h>
main()
{
pid_t pid;
/*此時僅有一個進程*/
pid=fork();
/*此時已經有兩個進程在同時運行*/
if(pid<0)
printf("error in fork!");
else if(pid==0)
printf("I am the child process, my process ID is %d
",getpid());
else
printf("I am the parent process, my process ID is %d
",getpid());
}

編譯並運行:

$gcc fork_test.c -o fork_test
$./fork_test
I am the parent process, my process ID is 1991
I am the child process, my process ID is 1992

看這個程序的時候,頭腦中必須首先了解一個概念:在語句pid=fork()之前,只有一個進程在執行這段代碼,但在這條語句之後,就變成兩個進程在執行了,這兩個進程的代碼部分完全相同,將要執行的下一條語句都是if(pid==0)......。

兩個進程中,原先就存在的那個被稱作"父進程",新出現的那個被稱作"子進程"。父子進程的區別除了進程標志符(process ID)不同外,變數pid的值也不相同,pid存放的是fork的返回值。fork調用的一個奇妙之處就是它僅僅被調用一次,卻能夠返回兩次,它可能有三種不同的返回值:

在父進程中,fork返回新創建子進程的進程ID;

在子進程中,fork返回0;

如果出現錯誤,fork返回一個負值;

fork出錯可能有兩種原因:

(1)當前的進程數已經達到了系統規定的上限,這時errno的值被設置為EAGAIN。(2)系統內存不足,這時errno的值被設置為ENOMEM。(關於errno的意義,請參考本系列的第一篇文章。)

fork系統調用出錯的可能性很小,而且如果出錯,一般都為第一種錯誤。如果出現第二種錯誤,說明系統已經沒有可分配的內存,正處於崩潰的邊緣,這種情況對Linux來說是很罕見的。

說到這里,聰明的讀者可能已經完全看懂剩下的代碼了,如果pid小於0,說明出現了錯誤;pid==0,就說明fork返回了0,也就說明當前進程是子進程,就去執行printf("I am the child!"),否則(else),當前進程就是父進程,執行printf("I am the parent!")。完美主義者會覺得這很冗餘,因為兩個進程里都各有一條它們永遠執行不到的語句。不必過於為此耿耿於懷,畢竟很多年以前,UNIX的鼻祖們在當時內存小得無法想像的計算機上就是這樣寫程序的,以我們如今的"海量"內存,完全可以把這幾個位元組的顧慮拋到九霄雲外。

說到這里,可能有些讀者還有疑問:如果fork後子進程和父進程幾乎完全一樣,而系統中產生新進程唯一的方法就是fork,那豈不是系統中所有的進程都要一模一樣嗎?那我們要執行新的應用程序時候怎麼辦呢?從對Linux系統的經驗中,我們知道這種問題並不存在。至於採用了什麼方法,我們把這個問題留到後面具體討論。

exit

在2.4.4版內核中,exit是第1號調用,其在Linux函數庫中的原型是:

#include<stdlib.h>
void exit(int status);

不像fork那麼難理解,從exit的名字就能看出,這個系統調用是用來終止一個進程的。無論在程序中的什麼位置,只要執行到exit系統調用,進程就會停止剩下的所有操作,清除包括PCB在內的各種數據結構,並終止本進程的運行。請看下面的程序:

/* exit_test1.c */
#include<stdlib.h>
main()
{
printf("this process will exit!
");
exit(0);
printf("never be displayed!
");
}

編譯後運行:

$gcc exit_test1.c -o exit_test1
$./exit_test1
this process will exit!

我們可以看到,程序並沒有列印後面的"never be displayed! ",因為在此之前,在執行到exit(0)時,進程就已經終止了。

exit系統調用帶有一個整數類型的參數status,我們可以利用這個參數傳遞進程結束時的狀態,比如說,該進程是正常結束的,還是出現某種意外而結束的,一般來說,0表示沒有意外的正常結束;其他的數值表示出現了錯誤,進程非正常結束。我們在實際編程時,可以用wait系統調用接收子進程的返回值,從而針對不同的情況進行不同的處理。關於wait的詳細情況,我們將在以後的篇幅中進行介紹。

exit和_exit

作為系統調用而言,_exit和exit是一對孿生兄弟,它們究竟相似到什麼程度,我們可以從Linux的源碼中找到答案:

#define __NR__exit __NR_exit /* 摘自文件include/asm-i386/unistd.h第334行 */

"__NR_"是在Linux的源碼中為每個系統調用加上的前綴,請注意第一個exit前有2條下劃線,第二個exit前只有1條下劃線。

這時隨便一個懂得C語言並且頭腦清醒的人都會說,_exit和exit沒有任何區別,但我們還要講一下這兩者之間的區別,這種區別主要體現在它們在函數庫中的定義。_exit在Linux函數庫中的原型是:

#include<unistd.h>
void _exit(int status);

和exit比較一下,exit()函數定義在stdlib.h中,而_exit()定義在unistd.h中,從名字上看,stdlib.h似乎比unistd.h高級一點,那麼,它們之間到底有什麼區別呢?讓我們先來看流程圖,通過下圖,我們會對這兩個系統調用的執行過程產生一個較為直觀的認識。

從圖中可以看出,_exit()函數的作用最為簡單:直接使進程停止運行,清除其使用的內存空間,並銷毀其在內核中的各種數據結構;exit()函數則在這些基礎上作了一些包裝,在執行退出之前加了若幹道工序,也是因為這個原因,有些人認為exit已經不能算是純粹的系統調用。

exit()函數與_exit()函數最大的區別就在於exit()函數在調用exit系統調用之前要檢查文件的打開情況,把文件緩沖區中的內容寫迴文件,就是圖中的"清理I/O緩沖"一項。

在Linux的標准函數庫中,有一套稱作"高級I/O"的函數,我們熟知的printf()、fopen()、fread()、fwrite()都在此列,它們也被稱作"緩沖I/O(buffered I/O)",其特徵是對應每一個打開的文件,在內存中都有一片緩沖區,每次讀文件時,會多讀出若干條記錄,這樣下次讀文件時就可以直接從內存的緩沖區中讀取,每次寫文件的時候,也僅僅是寫入內存中的緩沖區,等滿足了一定的條件(達到一定數量,或遇到特定字元,如換行符和文件結束符EOF),再將緩沖區中的內容一次性寫入文件,這樣就大大增加了文件讀寫的速度,但也為我們編程帶來了一點點麻煩。如果有一些數據,我們認為已經寫入了文件,實際上因為沒有滿足特定的條件,它們還只是保存在緩沖區內,這時我們用_exit()函數直接將進程關閉,緩沖區中的數據就會丟失,反之,如果想保證數據的完整性,就一定要使用exit()函數。

請看以下常式:

/* exit2.c */
#include<stdlib.h>
main()
{
printf("output begin
");
printf("content in buffer");
exit(0);
}

編譯並運行:

$gcc exit2.c -o exit2
$./exit2
output begin
content in buffer
/* _exit1.c */
#include<unistd.h>
main()
{
printf("output begin
");
printf("content in buffer");
_exit(0);
}

編譯並運行:

$gcc _exit1.c -o _exit1
$./_exit1
output begin

在Linux中,標准輸入和標准輸出都是作為文件處理的,雖然是一類特殊的文件,但從程序員的角度來看,它們和硬碟上存儲數據的普通文件並沒有任何區別。與所有其他文件一樣,它們在打開後也有自己的緩沖區。

請讀者結合前面的敘述,思考一下為什麼這兩個程序會得出不同的結果。相信如果您理解了我前面所講的內容,會很容易的得出結論。

在這篇文章中,我們對Linux的進程管理作了初步的了解,並在此基礎上學習了getpid、fork、exit和_exit四個系統調用。在下一篇文章中,我們將學習與Linux進程管理相關的其他系統調用,並將作一些更深入的探討。

前面的文章中,我們已經了解了父進程和子進程的概念,並已經掌握了系統調用exit的用法,但可能很少有人意識到,在一個進程調用了exit之後,該進程並非馬上就消失掉,而是留下一個稱為僵屍進程(Zombie)的數據結構。在Linux進程的5種狀態中,僵屍進程是非常特殊的一種,它已經放棄了幾乎所有內存空間,沒有任何可執行代碼,也不能被調度,僅僅在進程列表中保留一個位置,記載該進程的退出狀態等信息供其他進程收集,除此之外,僵屍進程不再佔有任何內存空間。從這點來看,僵屍進程雖然有一個很酷的名字,但它的影響力遠遠抵不上那些真正的僵屍兄弟,真正的僵屍總能令人感到恐怖,而僵屍進程卻除了留下一些供人憑吊的信息,對系統毫無作用。

也許讀者們還對這個新概念比較好奇,那就讓我們來看一眼Linux里的僵屍進程究竟長什麼樣子。

當一個進程已退出,但其父進程還沒有調用系統調用wait(稍後介紹)對其進行收集之前的這段時間里,它會一直保持僵屍狀態,利用這個特點,我們來寫一個簡單的小程序:

/* zombie.c */
#include
#include
main()
{
pid_t pid;

pid=fork();

if(pid<0) /* 如果出錯 */
printf("error occurred!n");
else if(pid==0) /* 如果是子進程 */
exit(0);
else /* 如果是父進程 */
sleep(60); /* 休眠60秒,這段時間里,父進程什麼也幹不了 */
wait(NULL); /* 收集僵屍進程 */
}

sleep的作用是讓進程休眠指定的秒數,在這60秒內,子進程已經退出,而父進程正忙著睡覺,不可能對它進行收集,這樣,我們就能保持子進程60秒的僵屍狀態。

編譯這個程序:

$ cc zombie.c -o zombie

後台運行程序,以使我們能夠執行下一條命令:

$ ./zombie &
[1] 1577

列一下系統內的進程:

$ ps -ax
... ...
1177 pts/0 S 0:00 -bash
1577 pts/0 S 0:00 ./zombie
1578 pts/0 Z 0:00 [zombie ]
1579 pts/0 R 0:00 ps -ax

看到中間的"Z"了嗎?那就是僵屍進程的標志,它表示1578號進程現在就是一個僵屍進程。

我們已經學習了系統調用exit,它的作用是使進程退出,但也僅僅限於將一個正常的進程變成一個僵屍進程,並不能將其完全銷毀。僵屍進程雖然對其他進程幾乎沒有什麼影響,不佔用CPU時間,消耗的內存也幾乎可以忽略不計,但有它在那裡呆著,還是讓人覺得心裡很不舒服。而且Linux系統中進程數目是有限制的,在一些特殊的情況下,如果存在太多的僵屍進程,也會影響到新進程的產生。那麼,我們該如何來消滅這些僵屍進程呢?

先來了解一下僵屍進程的來由,我們知道,Linux和UNIX總有著剪不斷理還亂的親緣關系,僵屍進程的概念也是從UNIX上繼承來的,而UNIX的先驅們設計這個東西並非是因為閑來無聊想煩煩其他的程序員。僵屍進程中保存著很多對程序員和系統管理員非常重要的信息,首先,這個進程是怎麼死亡的?是正常退出呢,還是出現了錯誤,還是被其它進程強迫退出的?其次,這個進程佔用的總系統CPU時間和總用戶CPU時間分別是多少?發生頁錯誤的數目和收到信號的數目。這些信息都被存儲在僵屍進程中,試想如果沒有僵屍進程,進程一退出,所有與之相關的信息都立刻歸於無形,而此時程序員或系統管理員需要用到,就只好乾瞪眼了。

那麼,我們如何收集這些信息,並終結這些僵屍進程呢?就要靠我們下面要講到的waitpid調用和wait調用。這兩者的作用都是收集僵屍進程留下的信息,同時使這個進程徹底消失。下面就對這兩個調用分別作詳細介紹。

③ 通達信 arbr指標

AR是人氣意願指標,BR是買賣意願指標比較簡單,就是兩條線AR和BR

1.AR和BR指標的一般身高是70-150,太高了容易折,太低了(50以下)就會有人搶籌碼而拉高它。

2.AR有先知能力,若股價行情正好上漲時而AR開始掉頭向下,我們就要出貨了,反之,就要快快搶籌碼了。

3.若是二者攜手一飛沖天的上漲,我們此時就要減倉了。若是慢悠悠的一起向上,那我們也就慢慢的拿。

4.BR沒有AR是不行的,離開了AR,BR就沒有了生命,所以使用時一定要把BRAR放在一起用。

5.若是BR從高處摔落了1/2,而AR還是在上方乾瞪眼看著,那就買票進場吧,因為後期BR還是會乖乖的回到AR身邊的。

④ 想要用易語言製作輔助需要學習哪些易語言知識,

這些人都瞎吹,
除非拿現成的外掛模塊無腦調用。否則一個0基礎新手一上來就想學做外掛痴人說夢。外掛不僅要學易語言 還要學內存方面的知識 api CE也要學不是單純的搜索浮數點,還要過得了游戲基礎檢測,沒有堅實的編程基礎想都別想。
很多新手下個模塊 源碼東拼西湊改個名就成自己的了 什麼原理怎麼實現根本搞不懂 只是調用別人寫好封裝的子程序 每天就是忙碌在找基址改基址 然後 游戲商換個檢測思路 就只能乾瞪眼到處求人。很多人就是想學做外掛賺錢,你不懂基本原理怎麼實現全是拿別人的成品復制粘貼 做出成品又怎樣 一發出去 別人分分鍾給你破了限制 還會怕你套飄零網路驗證?。
我建議你還是從最基層學起,先學個進度條怎麼實現 把那些組件屬性搞清楚怎麼用 循序漸進 多動手 。別想那些離你很遠的東西。

java閱讀源碼,大量英文注釋閱讀不方便,求集成idea裡面的翻譯java注釋由英文翻譯為中文的工具。

學會在idea(eclipse)中閱讀、調試源碼,是java程序員必不可少的一項技能。


在idea中配完環境後,默認其實也是能夠對jdk的源碼進行debug調試的。但是無法在源碼中添加自己的注釋,無法添加自己的理解。如果乾瞪眼看的話,可能過段時間,就忘記了。下面就介紹下,如何在jdk源碼中為所欲為,像在我們自己的代碼中一樣寫注釋、調代碼:


打開idea,選擇Project->File->Project Structure->SDKs->Sourcepath,初始狀態如下圖 :


這時,再重新打開jdk的源碼類,我們就可以在源java文件中,添加自己的注釋了。

一定注意:添加註釋時,一定不要新加一行寫注釋。最好在一行代碼的後面,使用//進行注釋。否則行號和真正的jre中編譯後的代碼行號對應不上,如果對源碼debug時,會出現代碼運行和行號不匹配的情況

⑥ 如何編輯boot.img裡面的ramdisk

首先你要有一個用戶解鎖fastboot的手機,這樣才能允許你刷入第三方ROM
其次你要能找到當前版本所對應的boot.img或sec_boot.img(帶簽名),通常能拿到的也就是刷機包裡面解出來的sec_boot.img,通過cat mtd出來的不知道行不行=。=
工具:
split_bootimg.pl google一下,很好找
mkbootfs和mkbootimg 可以從網上下,最好是自己直接編譯

1)sec_boot.img是經過簽名的,需要把文件前0x1000個位元組刪除,也就是ANDROID! 8個字元前面所有位元組刪除,保存為boot.img
2) 運行perl split_bootimg.pl boot.img解出kernel和ramdisk文件,同時記下運行結果中的「Command line: vmalloc=384M mem=2044m@0x200000。。。。」一長串字元備用
3)運行指令把ramdisk的文件解出來
mkdir ramdisk
cd ramdisk
gzip -dc ../boot.img-ramdisk.gz | cpio -i
cd ..
4)修改其中的文件,例如我覺得default.prop裡面的persist.sys.usb.config=manufacture,adb不太爽,想改成=adb,修改保存。如果你想adb有root許可權的話,就去改ro.secure和ro.debuggable
5)重新打包
mkbootfs ./ramdisk | gzip > ramdisk-new.gz
當然如果你自己編譯的mkbootfs也沒有加到path里,就把編譯完的程序考到當前目錄,運行./mkbootfs...
生成boot-new.img
mkbootimg --cmdline '單引號裡面這一段拷貝剛才記下的Command line冒號後面的一長串' --kernel boot.img-kernel --ramdisk ramdisk-new.gz -o boot-new.img
6) 現在如果把生成的boot-new.img直接刷進去,手機就起不來了,問題在於kernel,ramdisk,second stage,tags的地址,
自己編譯的mkbootimg查看一下.c文件就知道base=0x10000000,生成的boot-new.img是按照這個規則來的:
kernel地址=base + 0x00008000,ramdisk地址=base + 0x01000000,
second stage地址=base + 0x00f00000,tags地址=base + 0x00000100。
這跟原始sec_boot.img裡面的地址是不一樣的,本想找到正確的base值,但原始img的幾個地址並非此規律,拿不到源碼只能乾瞪眼嘍,
最簡單的辦法就是用16進制編輯器將boot-new.img對應的4個地址修改為原始值,如圖:

⑦ 易語言 怎麼樣一按信息框的確定還20秒後自動關閉窗口

.版本2

.程序集窗口程序集1

.程序集變數i,整數型

.子程序__啟動窗口_創建完畢

i=20

.子程序_按鈕1_被單擊

信息框(「窗口將在20秒後關閉!」,0,)

時鍾1.時鍾周期=1000

.子程序_時鍾1_周期事件

.如果真(i≠0)

標簽1.標題=「還剩」+到文本(i)+「秒,窗口將自動關閉!」

i=i-1

返回()

.如果真結束

結束()

.子程序_按鈕2_被單擊

信息框(「窗口將在20秒後關閉!」,0,)

延時(20000)

結束()

『---------------------------------

這兩種方法是有區別的,

方法一:用時鍾控制項那個,算是軟關閉,在這20秒內,用戶可以進行其他操作,也可以取消關閉,

方法二:這個就屬於硬關閉了,因為用的是延時命令,這20秒內,程序可以說是處在一個假死狀態,用戶無法進行其他操作,只能乾瞪眼的等著程序關閉

希望對你有用

⑧ 《UNIX環境高級編程》這本書怎麼看怎麼學習

W.Richard Stevens 先生所著之書比較適合有經驗的人進一步深入學習

W.Richard Stevens 先生所著的UNIX 環境高級編程、UNIX網路編程、TCP/IP詳解是難得的入門好書,但這里的入門指得是研究生級別的入門。Stevens 先生所著之書多半是為了給研究生上課時用做教材,因此 Stevens 先生假設閱讀這些書的人至少已經接受過了系統的計算機技術本科教育,已經擁有了比較系統的計算機相關基礎理論知識。在書中 Stevens 先生假設讀者擁有了最基礎的操作系統理論,網路技術理論,以及UNIX理論和實踐經驗,並擁有數種業界常用的UNIX系統作為學習環境(在國外的大學里很容易獲得),這樣才能體會書中所述的細節。因此這些書剛接觸時看似通俗易懂,但在閱讀細節上卻對讀者要求甚高,如果沒有足夠的專業理論和系統實踐是很難真正讀進去的。

所以,對於沒有接受過系統的計算機專業教育的愛好者,或者主要以 linux 系統維護,或以linux 桌面應用為主的普通用戶,Stevens 先生的書並不是很合適的閱讀對象。

因此,就我個人的看法,掌握任何一種知識都是需要投入的。我們需要花費金錢去得知識來源(花錢買書,花錢上網,花錢培訓),需要花費寶貴的時間去閱讀(人生匆匆幾十年,沒多少時間可以給我們去浪費),需要花費精力去理解書中的內容(基礎知識越扎實,理解所學內容越快,但累積基礎同樣需要大量時間和精力),需要找到合適的環境(光看不實踐心裡是不會有底的)去驗證自己掌握的東西。因此,如果在決定投入之前,先要摸清楚自己到底想要達到什麼樣的目標,這個目標是否切合自己的實際(相信一個在流水線上辛苦勞作的普通工人,即使學會了計算機編程也是沒有用武之地的,除非他有機會離開流水線)。自己是否有足夠的資源承載自己的理想(如對於溫飽問題尚未解決之人,要他花上千上萬的錢去學MBA顯然是不現實的)。

同時,任何一本書都會對讀者提出一個基本的知識架構和程度上的要求,比方說即使是文學博士,讓他去讀高能物理學方面的書也會要他的命的。因此在選擇所讀之書前,先要對自己的實際能力做一次詳細的評估,看自己目前到了哪種階段,是否有能力去掌握自己想要掌握的東西。千萬不要因為好高騖遠而勉力為之。選擇適合自己當前水平的書去閱讀並理解,遠好過拿著大師所著的神作乾瞪眼。

如果主要希望掌握UNIX下的編程技術,尤其是網路編程技術的話,可以有兩條路走:

1、以實際需要完善知識架構:為自己做一個項目,比方說自己寫個簡單的 Web 伺服器,因為現在 Web 應用非常豐富,既有成熟的客戶端如瀏覽器可以配合,又有足夠全的文檔如 RFC文檔可供參考,再加上最基本的 socket 編程經驗,就可以開始做自己的 Web 伺服器。一步一步的為 Web 伺服器添加流行的功能,如支持後台 FastCGI 介面,支持 WebDAV,支持流媒體等。在這個過程中不斷地學習和掌握相關的理論知識,有時在發覺設計上的不足時甚至需要推翻全盤重新架構。當最終一個完全符合自己心意且足夠實用的 Web 伺服器做成時,就擁有了可以由自己支配和修改的伺服器,同時也掌握了相關的專業理論。這種方式比較適合有一定專業基礎的人使用。優點是直觀,方向明確所以學習效率高。缺點是需求驅動,形成知識架構不容易完整。

2、系統掌握計算機專業理論:最好的書就是大學里的理論教科書,這些書不會去講解過於具體的計算機應用,而是從概念開始講起,力圖使學習者獲得一個完整的知識體系。只要以後碰到的工作和這個知識體系相關,自然就能很快學會。這種方式比較適合沒有基礎,或者希望深入學習的人使用,優點是知識架構會逐漸趨於完整,理論功底扎實,後勁足。缺點是花費時間長,方向不明確所以學習效率低,初期會因缺少實踐而進展緩慢。

熱點內容
詐騙的腳本 發布:2025-01-16 23:51:27 瀏覽:314
電腦配置有點低怎麼玩和平精英 發布:2025-01-16 23:46:14 瀏覽:818
ipfs分布式伺服器是什麼幣種 發布:2025-01-16 23:32:29 瀏覽:991
android動態icon 發布:2025-01-16 23:03:12 瀏覽:605
優酷電腦緩存在哪 發布:2025-01-16 22:58:29 瀏覽:298
進口途銳哪個配置好 發布:2025-01-16 22:35:24 瀏覽:962
骨幹路由器怎麼配置 發布:2025-01-16 22:24:39 瀏覽:244
途安2021款買哪個配置 發布:2025-01-16 22:21:01 瀏覽:329
圖片的壓縮原理 發布:2025-01-16 22:17:15 瀏覽:493
雲伺服器本地電腦 發布:2025-01-16 22:17:04 瀏覽:961