顯示具有 linux(ubuntu) 標籤的文章。 顯示所有文章
顯示具有 linux(ubuntu) 標籤的文章。 顯示所有文章

2025年8月6日 星期三

Linux kernel minor upgrade

 今天嘗試把 kernel v4.19.98 作微升級,要升級到 v4.19.325,因為我們原本的 kernel 並不是原生最乾淨的 Linux kernel v4.19.98(是拿MTK平台的 SDK),先講我打上了這兩個版本中間的 patch,但最終編譯,卻有一堆error,解不完

 但我認為,作這件事情,中間的過程,是值得作個記錄的,因此寫了這篇文章,來記錄中間所做的步驟。

1. 下載 Linux 的 branch,使用指令如下:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git

2. 每個版本都有打上tag,因此我們可以先 checkout 到 v4.19.325
git checkout v4.19.325

3. git log 確認一下 v4.19.325 與 v4.19.98 分別的 commit hash 號碼是多少










4. 使用指令,把 98 ~ 325 這中間的 commit 都作成 patch 檔,指令如下:
git format-patch d183c8e2647a7d45202c14a33631f6c09020f8ac..a67e7cdde7cc7984ae24c3c81a70dc1aa34424b1 -o patch/

5. 可以看到,目前目錄底下,會產出資料夾 patch/ ,裡面有 19xxx個patch 檔,依序都做好了編號

6. 接著我們準備要來打 patch,先說明一下,我目前的目錄環境是這樣,
apps/src/kernel/linux/4.19/,我目前專案的 repository 是在 apps底下,也就是我可以在 apps底下執行 git log,可以看到以往的 commit 資訊,而目前是要把 linux patch 打到   apps/src/kernel/linux/4.19/ 底下

7. 因為第6.的關係,我們把 patch/ 移動到 apps底下,我們打patch 的指令會如下:
cd apps/
git am --directory=src/kernel/linux/v4.19 patch/* -3  

(加上 -3(或 --3way)後,如果直接套用失敗,Git 會嘗試用三方合併的方式來解決衝突,這樣有時候可以自動解決一些簡單的衝突)

8. 打patch 的途中,會遇到許多的 conflict,你會需要開啟檔案,去解衝突,但我發現 19xxx筆patch,要解的 conflict 實在太多了,後來遇到 conflict 直接使用以下command,意思是直接幫我把衝突的舊檔案的部分刪除,把新的patch 新增的內容,改到檔案裡面: 
git checkout --theirs $file (file帶入中途的檔案路徑 與 名稱)

9. 途中會遇到一些,甚麼都沒改的 patch,會需要手動執行 git am --skip 來繼續,另外解完 conflict 的檔案,要手動執行 git am --continue 來讓 git am 繼續跑

10. 另外有遇到一個,git am 打patch,我發現有一個限制,就是打到 9999個 patch的時候,你再輸入 git am --continue 會沒辦法繼續,如下圖,這時候你必須要先 git push,把先前打的patch 都git push,然後再繼續從第 10000筆繼續打,我的作法是




   







   a. 在作第4部的時候,也順便把檔案列表資訊,輸出到一個檔案:
git format-patch d183c8e2647a7d45202c14a33631f6c09020f8ac..a67e7cdde7cc7984ae24c3c81a70dc1aa34424b1 -o patch/ > patch_list.txt
   b. 想辦法使用 note 或是 Notepad++ 把這些列表改成
rm 0001-xxxx
rm 0002-xxxx
..
rm 9999-xxxx
   c. 切換到 patch/ 資料夾,把 0001~9999 的patch 檔案都刪除
   d. 在接著使用git am 的命令繼續打剩餘的 patch:
git am --directory=src/kernel/linux/v4.19 patch/* -3  


結論: 
   1. 我在這次的過程中,寫了以下兩隻script,當發生conflict,就使用git checkout --theirs $file 去解conflict,因此可以一直遞迴去處理patch,但遇到 git am --continue 無法繼續的空內容,目前就是手動去下 git am --skip
   2. 其實比較好的做法,應該要是以下步驟
        a. 先 git checkout 到 linux pure v4.19.98
        b. 把vendor最一開始給的 kernel 覆蓋到
 linux pure v4.19.98
        c. git diff 看一下改了那些檔案
        d. 直接把 
linux pure v4.19.98,checkout 到 v4.19.325,然後試著把 前一步驟,git diff 的改回去,但如果真的差異太大,就是一個很大的工程了....

以下分享我的兩個 shell script: (主要就是執行 ./for_loop.sh)

主程式:  for_loop.sh

#!/bin/sh
for i in {1..20000}
do
    ./fail_process.sh
    if [ $? -eq 2 ]; then
        echo "fail_process.sh failed, stopping loop."
        break
    fi
done

副程式:  fail_process.sh

#!/bin/sh

# Get the list of files marked as "both modified" from gg (git status)
files0=$(git status | grep "both modified:" | awk -F: '{print $2}' | xargs)

# For each file, run git add
for file in $files0; do
    echo "Processing $file ..."
    git checkout --theirs $file
    git add $file
done


# Get the list of files marked as "deleted by them:" from gg (git status)
files1=$(git status | grep "deleted by them:" | awk -F: '{print $2}' | xargs)

# For each file, run git add
for file in $files1; do
    echo "Processing $file ..."
    git add $file
done

# Get the list of files marked as "deleted by us:" from gg (git status)
files2=$(git status | grep "deleted by us:" | awk -F: '{print $2}' | xargs)

# For each file, run git add
for file in $files2; do
    echo "Processing $file ..."
    git add $file
done


# Get the list of files marked as "both added" from gg (git status)
files3=$(git status | grep "both added:" | awk -F: '{print $2}' | xargs)

# For each file, run git add
for file in $files3; do
    echo "Processing $file ..."
    git checkout --theirs $file
    git add $file
done

if [ -z "$files0" ] && [ -z "$files1" ] && [ -z "$files2" ] && [ -z "$files3" ]; then
        exit 2
fi

git status
git am --continue



2025年6月20日 星期五

指令,把read-only 的filesystem,remount 成 read/write

使用mount指令,先看一下,目前 / 掛載為 read-only,ext4 的 filesystem
root@:# mount
/dev/mmcblk0p16 on / type ext4 (ro,relatime,norecovery)


把 root folder 重新掛載成可 read/write
 mount -o remount,rw /

再用mount看一次
root@:~# mount
/dev/mmcblk0p16 on / type ext4 (rw,relatime,norecovery)

2025年1月7日 星期二

Linux Tool, taskset 可以用來限制程式,只去使用特定 CPU

 Linux 當中有個Tool,叫做 taskset,可以限制某個Daemon只跑在規定的CPU編號之下,這邊會先簡單介紹 taskset使用方式,不免俗的,最後會附上一個實際操作

首先簡單寫一個 while迴圈,打印test的字樣,但不顯示在螢幕上,這支來當我們的Daemon,並且使用以下command,讓他在背景執行
=> sh loop_test.sh &
======= loop_test.sh 小程式 =========
#!/bin/sh
while [ 1 ]
do
   echo "test" > /dev/null
done



======= 使用方式 =======

首先我們可以用以下的指令,來得知目前設備的 CPU核心數目
=> cat /proc/cpuinfo

查詢目前的 Daemon,所配置的 CPU編號,這有兩種查詢方式
1. 直接列出,此Daemon使用的CPU編號,這邊Daemon的 PID=5622 (ps -aux | grep loop_test.sh)
=>
root:~# taskset -cp 5622
pid 5622's current affinity list: 0,1

2. 以mask方式列出,此Daemon使用的CPU編號,這邊Daemon的 PID=5622
=>
root:~# taskset -p 5622
pid 5622's current affinity mask: 3

這邊的3,為Hex,需要把他換成二進制來解讀,所以為 0x11,表示CPU0,CPU1目前會讓此Daemon使用(如果CPU為8 core,得到的數值為FF(hex),則表示 CPU0~7都會分配)


======= 使用方式 & 實驗 =======
設置目前的 Daemon,只分配CPU1 來做

=>
root:~# taskset -cp 1 5622
pid 5622's current affinity list: 0,1
pid 5622's new affinity list: 1

"top -d 1" 觀察一下cpu 與 process 狀態

=> 可以看到 CPU1 的 idle為0%,loop_test.sh 把整個CPU1用盡了,而CPU0是完全閒置的











這時候,我們再使用指令把 loop_test.sh 平均分配給 CPU0 & CPU1
=>
root@auto2735evb-ivt-vp2:~# taskset -cp 0,1 5622
pid 5622's current affinity list: 1
pid 5622's new affinity list: 0,1

"top -d 1" 觀察一下cpu 與 process 狀態
=> 可以看到 CPU0與CPU1,都有分配給 loop_test.sh使用



2024年12月6日 星期五

在adb shell 執行一個背景程式,如何讓 adb shell中斷後,此背景程式不會被中斷

 今天遇到有客人問一個問題
 他想要用 tcpdump 抓封包,指令如下:
tcpdump -i any -C 100 -W 10 -U -w /tmp/tcpdump.cap &

但因為,我們的device,在拔除usb之後,device可以進入 suspend
他想要在 wakeup的時候,抓到是甚麼樣的封包,

另外他想要透過 adb shell 去執行這個指令,所以當下完上面指令,adb shell 斷線之後
tcpdump 也終止了

查詢與嘗試了一下,可以使用以下指令解決
nohup tcpdump -i any -C 100 -W 10 -U -w /tmp/tcpdump.cap > /tmp/tcpdump.log 2>&1 &

只要確保 /tmp 目錄是可寫的,這樣 tcpdump 的輸出和錯誤信息將被寫入到 /tmp/tcpdump.log 文件中


2021年8月20日 星期五

Linux Terminal 顯示亂碼

 如果再Linux teminal底下,遇到顯示亂碼的問題,可以用下面的指令解決

$ export LANG=zh_CN.UTF-8 

2021年6月8日 星期二

Linux底下該如何切換python版本,使用 update-alternatives 安裝python,以及切換python版本

 安裝python以及切換python版本,在此篇文章中,我們都使用工具 "update-alternatives" 來達到目的

如果Linux底下沒有此工具,請輸入下面指令來安裝:
sudo apt-get install update-alternatives


按照下面指令,可以分別安裝 3.5.3版 以及 2.7.2版 的python

update-alternatives --install /usr/bin/python python /usr/bin/python3.5 3

update-alternatives --install /usr/bin/python python /usr/bin/python2.7 2


我們也可以透過此工具來切換目前想要的python版本:
sudo update-alternatives --config python

會出現如下畫面,請輸入0,1,2來選擇你想要切換的版本


2021年4月12日 星期一

grep最常的使用方法,grep 找關鍵字忽略大小寫的方法,find 找檔案忽略大小寫的方法

 linux底下,最常使用的莫過於 grep與 find這兩個指令,我們可以透過 grep來找尋檔案當中的關鍵字,我們也可以透過 find來找尋目錄底下是否有特定的檔案,這邊文章我們要告訴大家grep與find要如何使用

1. grep 最常的使用方式 ===>    

      EX: 在當下路徑,與當下所有子目錄,以遞迴的方式尋找所有檔案當中有"ab"的關鍵字,並且會列出所在檔案的行數

      Command: # grep -rn "ab" .


2. grep 忽略大小寫的方法 ===> 參數-i

     Command: # grep -rni "ab" .    結果可以找出關鍵字為AB,Ab,aB,ab 並列出在哪個檔案的第幾行


3. find 找當下目錄,特定名稱的檔案的方法  ===>

       EX: 在當下路徑,與當下所有子目錄,以遞迴的方式尋找所有檔案名稱為"ab.txt"的檔案

       Command: # find . -name "ab.txt"


4. find 忽略大小寫的方法 ===> find 本身沒有此功能,我們可以搭配管線與grep來達到

       Command: # find . | grep -i "ab.txt"   結果可以找出AB.txt, Ab.txt, aB.txt, ab.txt 

2020年3月8日 星期日

Linux底下parted工具的使用方式,建立GPT磁碟分割表

Linux底下,切割硬碟使用的工具,最常看到的是fdisk或是parted,而這兩個工具都可以輕鬆完成硬碟分割的工作

當硬碟大於2TB時,磁碟分割表需要建立為GPT時,就必須使用parted工具

parted的操作方式如下所介紹:
=================================================================
首先輸入 sudo parted /dev/sda 就可以針對/dev/sda 進入parted的操作介面 ,如果要操作的為/dev/sdb,則輸入sudo parted /dev/sdb(若是沒有parted,請使用apt-get去安裝)





操作介面:




輸入help可以顯示指令的使用說明





輸入quit則可以離開parted操作環境





輸入print指令,可以列出目前磁碟的分割區資訊



====================================================================

刪除磁碟分割區的指令
=================================================================
首先用print查詢有幾個分割區,再使用rm指令加上分割區編號來做刪除

輸入 rm 1 則刪除第一分割區
輸入 rm 2 則刪除第二分割區





=================================================================

建立磁碟分割區的指令
=================================================================
首先要建立磁碟分割表

建立 msdos(一般MBR): mklabel msdos





硬碟大於2TB,可以使用GPT:mklabel gpt





如果硬碟存在之前的分割表資訊,則會出現如下警告




若確定要重新建立,輸入y

接著建立磁碟分割區: mkpart





接下來依序輸入一些參數

Partition name?   [ ]?     test     <=== 輸入分割區名稱,不想輸入可以直接Enter
File system type?    [ext2]?      <=== 檔案系統格式,預設ext2,按Enter就可以
Start? 1                                     <=== 輸入起始位置
End?  50000                             <=== 輸入結束位置,磁碟大小為50GB

接著離開parted





最後在Linux底下,使用mkfs.ext4格式化剛剛切割好的分割區
mkfs.ext4 /dev/sdb1











2019年9月24日 星期二

dd 檔案合併,詳細使用方法

dd基本的參數描述如下:

*基本輸入輸出
if=FILE:輸入名稱
of=FILE:輸出名稱

*做相對應的轉換conv=[lcase/ucase/nocreat/notrunc/fdatasync]
lcase:大寫字母轉小寫
ucase:小寫字母轉大寫
nocreat:不要建立輸出檔案
notrunc:input小於output時,仍維持output大小
fdatasync:讓資料同步寫入硬碟

*區塊參數,分別有以下四個參數可以調整:
bs=[bytes]:等同於同時設定ibs和obs,一次讀或寫的block size。
ibs=[bytes]:指定每次讀取的block size(default 512 bytes)
obs=[bytes]:指定每次寫入的block size(default 512 bytes)
count=[number]:只處理前[number]輸入區塊,block size要參考ibs。
seek=[number]:輸出檔案跳過前[number]個區塊,block size要參考obs。
skip=[number]:輸入檔案跳過前[number]個區塊,block size要參考ibs。


下面給幾個使用範例:

[example_1] 使用dd產生一個2MB的檔案,其內容皆為0xff
dd if=/dev/zero ibs=1M count=2 | tr "\000" "\377" >rom.bin

[example_2] 使用dd把一個835KB的檔案(flash.bin)放到 2MB的rom.bin檔案的最前面
$ dd if=flash.bin of=rom.bin bs=1K count=835 conv=notrunc

[example_3] 使用dd把一個64KB的檔案(env.bin)放到2MB的rom.bin檔案的960KB位置之後
$ dd if=env.bin of=rom.bin bs=1K count=64 seek=960 conv=notrunc

[example_4] 使用dd把一個1024KB的檔案(jffs2.bin)放到2MB的rom.bin檔案的1024KB之後的位置
$ dd if=image.jffs2 of=rom.bin bs=1K count=1024 seek=1024 conv=notrunc

最終的rom.bin內容如下圖所示:






















*產生空的1MB 的jffs2 image的指令(jffs2_dir為一個空資料夾):
$ mkfs.jffs2 -r jffs2_dir -o image.jffs2 --pad=0x100000
若是沒有mkfs.jff2指令,請先使用apt-get install mtd-util

2019年8月8日 星期四

使用ethtool開啟/關閉 wol功能的指令

使用說明:
開啟Wake on lan ==> ethtool -s [Interface] wol g
關閉Wake on lan ==> ethtool -s [Interface] wol d

# ethtool -s eth0 wol g
# ethtool -s eth0 wol d

最後可以使用ethtool查看WOL是否有開啟


2019年7月11日 星期四

Linux設定IP, BroadCast, netmask的指令

利用ifconfig一行就可以解決,如下指令:

ifconfig eth0 192.168.1.5 broadcast 192.168.1.255 netmask 255.255.255.0

2019年5月2日 星期四

如何修改Ubuntu當中Terminal的hostname

依序完成下面兩個步驟
1. vim /etc/hostname     改成你想要的
2. vim /etc/hosts            把你在Terminal看到的字,改成你想要的

重開機後,就會看到已經被更改了~

2018年9月14日 星期五

Ubuntu設定固定時間重新開機 shedule do something

我們可以透過一個工具 ===> crontab

假設你機器上找不到此工具,請先使用apt-get 取得:
sudo apt-get install cron

--------------- 接下來是設定的方法 -------------
1. 先去編輯crontab,命令如下:
#/ sudo crontab -e
**第一次編輯,會詢問你偏好的編輯器,選nano就可以了


2.可以看到文字檔中的說明如下
m      h    dom        mon   dow       command

minute hour dayOfMonth Month dayOfWeek commandToRun
假設我們現在要讓電腦每天早上4點自行重新啟動,請加入下面這行:

0 4 * * * /sbin/reboot



所以最後檔案編輯會如下圖:
















最後按 Ctrl+x 離開並存檔

2018年8月24日 星期五

在Linux作業系統,使用ethtool來切換網路的速度

假設我們要把eth0從10G速度切換成固定1G(關閉Auto-nego),執行下面指令就可以

1. 關閉Auto-negotiation 同時切換網路速度為 1000Mb/s 並設為全雙工
# ethtool -s eth0 autoneg off speed 1000 duplex full



2018年6月6日 星期三

Ubuntu 16.04 Linux 新增一個automount script,並在開機時自動執行

首先介紹這隻準備加入的Script,automount.sh,其實這隻動作很簡單,我打算在開機的過程中,讓他自動把兩顆HDD分別掛載在 /HDD1 與 /HDD2 資料夾

其內容如下:
============== automount.sh ==============
#!/bin/sh
mount /dev/sda1 /HDD1
mount /dev/sdb1 /HDD2
=======================================

接著該如何讓他在開機過程中就自動執行,先把 automount.sh放在 /etc/init.d/,另外要注意這個script的權限要是可以執行的,我們可以把權限全開
#chmod 777 /etc/init.d/automount.sh

我們可以在/etc/rcS.d/ 底下,新增一個link檔,名為S99automount,建立的指令如下:
# ln -S /etc/init.d/automount.sh /etc/rcS.d/S99automount

因為/etc/init.d/rc 會去掃描/etc/rcS.d/ 裡面的檔案 ,並且依照優先順序把/etc/rcS.d/ 底下的 Script都跑過,S99 就表示優先順序是很後面的

這樣子加完之後,開機後就可以看到sda1, sdb1 都自動被mount起來了~

2018年4月25日 星期三

Ubuntu發行版更換Linux Kernel的方法

首先我們必須到下面的網址去下載想要升級的版本
http://kernel.ubuntu.com/~kernel-ppa/mainline/

以這次的實驗為例子,我們想把 4.10.0的 Kernel版本升級為 4.14.12

我們的電腦,安裝64位元的Ubuntu
因此我們先透過上面的link找到如下圖的檔案:

































下載三個檔案,下載完成後把這三個檔案放在同一個資料夾

  • linux-headers-4.14.12-041412_4.14.12-041412.201801051649_all.deb
  • linux-headers-4.14.12-041412-generic_4.14.12-041412.201801051649_amd64.deb
  • linux-image-4.14.12-041412-generic_4.14.12-041412.201801051649_amd64.deb

接著我們在要安裝的Ubuntu那端,對這三個檔案,執行下面的指令

# sudo dpkg -i *.deb

若是產生 Grub設定檔的部分有Warning訊息,請使用下面指令來更新Grub

# sudo update-grub

安裝完成後,先重新開機,開機後使用 "uname -a" 確認kernel版本應該已經更新到4.14.10

Linux 設定 DNS Server

在Linux底下, 有個設置 DNS 位置的設定文件 ===> /etc/resolv.conf

因此我們只需修改此檔案,來增加我們想要設置的DNS Server

假設我們要增加 168.95.1.1

#vi /etc/resolv.conf
#================= resolv.conf ===============
nameserver 168.95.1.1

#========================================

只需要增加 nameserver那行,這樣就可以了

2018年4月9日 星期一

【Linux cmd】Linux查看資料夾大小的指令

先簡單介紹一下 du 指令的用法:
# du [參數] [檔案/目錄]

可使用的參數列表如下:
============================
-a | 顯示目錄中個別檔案的大小
-b | 以bytes為單位顯示
-c | 顯示個別檔案大小與總和
-D | 顯示符號鏈結的來源檔大小
-h | Human readable
-H | 與-h類似, 但是以1000為k的單位而非1024 bytes為區塊的單位
-l | 重複計算鏈結黨所占空間
-L 符號鏈結 | 指定符號鏈結檔的大小
-m | 以 MB 為顯示單位
-s | 只顯示總和
-S | 顯示目錄內容時, 不包含子目錄大小.
-x | 若目錄中有不同的檔案系統, 不顯示相異的檔案系統
--exclude | 忽略指定的檔案或目錄
--max-depth | 僅搜尋指定的目錄層級
==================================

Example(直接看範例怎麼使用):

要查看某個資料夾總大小,可以使用以下的指令(以KB顯示):
#du -s FolderName

若是想直接以 MB 或是 GB 顯示,可以加入-h的參數,指令如下:
#du -sh FolderName

實際操作如下圖:







若是想找出當下目錄,空間佔據前5大的資料夾或檔案,則我們可以搭配管線指令來找出來:
#du -sh * | sort -rn | head -5

2018年4月2日 星期一

【Linux cmd】在Ubuntu Terminal下,把使用者改成具有admin權限

此範例我們新增一個tester使用者,並讓他有admin權限能使用sudo

1. 首先我們必須要先有一個admin權限的使用者先登入(例如:root)

2. 接著使用下面指令,新增一個使用者,過程中會要求你輸入密碼:
#adduser tester

3. 接著我們使用指令"usermod" 來把tester 加入到 sudo 群組
#usermod -a -G sudo tester


接下來你就可以使用 sudo 來作一些需要權限的事情了~

2018年3月14日 星期三

讓 Ubuntu 可以透過網路 ssh登入

只需要安裝ssh server,安裝指令如下:
#apt-get install openssh-server

之後Ubuntu開機會自己啟動 ssh server ~

安裝完成之後也可以透過netstat 指令來確認 sshd有在port 22啟動
#netstat -tulpn | grep 22