A. python可以寫軟體么怎麼寫
22點24分准時推送,第一時間送達
編輯:技術君 | 來源:youerning
上一篇:
正文
前言
用 Python 寫安卓 APP 肯定不是最好的選擇,目前用Java和 kotlin 寫的居多,但是肯定也是一個很偷懶的選擇,而且實在不想學習 Java,再者,就編程而言已經會的就 Python與Golang(註:Python,Golang水平都一般),那麼久Google了一下Python 寫安卓的 APP 的可能性,還真行。
既然要寫個APP,那麼總得要有個想法吧。其實想做兩個APP來著,一個是自己寫著好玩的,一個是關於運維的。關於運維的APP,設計應該如下
可能長這樣
然後設計應該是這樣。
如果覺得可行的話,評論留言一下你覺得應該寫進這個APP的運維常用命令吧^_^,筆者暫時想到的是top,free -m,df –h,uptime,iftop,iotop,如果有什麼好的想法就狠狠的砸過來吧,筆者到時應該也會把這個寫成一個項目放到github上,大家一起用嘛,開源才是王道,哈哈。
開發安卓APP
我們使用kivy開發安卓APP,Kivy是一套專門用於跨平台快速應用開發的開源框架,使用Python和Cython編寫,對於多點觸控有著非常良好的支持,不僅能讓開發者快速完成簡潔的交互原型設計,還支持代碼重用和部署,絕對是一款頗讓人驚艷的NUI框架。
因為跨平台的,所以只寫一遍代碼,就可以同時生成安卓及IOS的APP,很酷吧。
本文會帶大家寫一個Hello world並瞧一瞧 Python 版的2048的代碼
kivy安裝
環境說明:筆者在用的是Python2.7.10
這里僅介紹windows平台安裝
所有平台參考: https://kivy.org/#download
更新pip,setuptools
python -m pip install --upgrade pip wheel setuptools
然後是安裝所需要的依賴
python -m pip install docutils pygmentspypiwin32 kivy.deps.sdl2 kivy.deps.glew
kivy.deps.gstreamer --extra-index-url https://kivy.org/downloads/packages/simple/
值得注意的是,上面的安卓需要訪問Google,所以請自備梯子,而且kivy.deps.gstreamer這個包比較大(95MB),可以單獨本地安裝,http://pan..com/s/1o7mlxNk
然後就是安裝kivy了
python -m pip install kivy
至此,安裝就已經完畢了,值得注意的是64位系統沒有開啟虛擬化支持,在導入kivy的時候會報錯,如果是64位系統就設置一下機器的BIOS,開啟虛擬化支持吧。
註:這里只是kivy的運行環境,這樣我就能直接在windows機器上直接調試了,怎麼將代碼編譯成APK文件我們會在後面講到。
如果kivy在python中應該就能導入了。
按照世界慣例,我們」hello」一下吧。
新建一個.py文件
from kivy.app import Appfrom kivy.uix.button importButton
class TestApp(App):
def build(self):
return Button(text='Hello,kivy')
TestApp().run()
運行
然後會彈出一個框,大概如下,點擊」hello,kivy」會變顏色
點擊窗口並按「F1」會這個窗口的一些屬性
然後我們回過頭看一看代碼。
##導入App,然後讓TestApp這個類繼承
from kivy.app import App##導入一個Button,運維有這個button,當你點擊的時候才會有所反應
from kivy.uix.button
importButton
###定義類,名字必須是xxxAppclass TestApp(App):
###build一個Button
def build(self):
###返回一個Button,文字內容是「Hello,kivy」
return Button(text='Hello,kivy')
##運行,因為繼承了App,所以才有的run這個方法TestApp().run()
上面就是我們的Hello了
在windows上運行當然沒有什麼太大的意義,怎麼在安卓手機上運行才是我們想要的,
這時我們需要一個編譯環境。
官方說明的環境,如下:
You』ll need:
A linux computer or a virtual machine
Java
Python 2.7 (not 2.6.)
Jinja2 (python mole)
Apache ant
android SDK
雖然官方提供了一個似乎還不錯的虛擬機鏡像,但是還是有很多內容需要翻出去,所以筆者在這里提供相對而言更加完善的鏡像
下載地址:http://pan..com/s/1geyAY7x
注:virtualbox,vmware需自行下載
root密碼:kivy
默認使用賬戶kivy,密碼:kivy123
當然你也可以下載官方鏡像,因為第一次編譯需要去國外下一大堆東西,所以請自行去下載。
Virtual Machine
A Virtual Machine with Android SDK and NDK and all otherpre-requisites pre installed to ease apk generation:
Kivy Buildozer VM
Or select the Torrent
在筆者提供的鏡像里,桌面上有一個dev_and,只要將上面寫的代碼,放入這個文件夾即可(當然也可以在其他目錄,後面會講到)。
在公眾號Python人工智慧技術後台回復「面試」,獲取騰訊Python面試題和答案。
cd Desktop/dev_and/
初始化會在當前目錄生成一個buildozer.spec文件 用於配置生成的apk相關信息
buildozer init
###修改buildozer.spec文件
vi buildozer.spec
至少修改下面三項
# (str) Title of your applicationtitle = helloworld
# (str) Package namepackage.name = helloapp
# (str) Package domain (needed for android/ios packaging)package.domain = youer.com
然後注釋
# (str) Application versioning (method 1)#version.regex = __version__ = ['"](.*)['"]#version.filename = %(source.dir)s/main.py
下面這行改為非注釋
version = 1.2.0
最後我們生成我們需要的apk文件
buildozer -v android debug
buildozer.spec更詳細的相關參數配置參考:
http://buildozer.readthedocs.org/en/latest/specifications.html
buildozer命令會在當前文件夾創建一個bin,該文件夾裡面有我們想要的apk文件
helloapp-1.2.0-debug.apk
helloapp-1.2.0-debug.apk
安裝以後是這樣:
話說在編譯的時候可能出現空間不足的情況,根據虛擬機的不同(vmware或virtualbox)自行擴容吧。
最後我們來瞧瞧簡易版Python開發的2048這個游戲的源代碼。
代碼:
https://github.com/mvasilkov/kb/tree/master/6_2048
先看效果圖:
試玩了一下,還是蠻流暢的,有興趣的可以下載玩一下
下載地址:http://pan..com/s/1eQZACDW
這個游戲代碼雖然不長,但是還是蠻占篇幅的,所以簡要的說明一下流程。
主要由三部分組成,一是素材,圖片音頻之類的文件,二是Python代碼,三是kv文件,這個kv文件有點像 html 中的css。
Python代碼的文件名一般命名為 main.py
然後一定有一個叫做 XXXApp 的類,並繼承 App。
比如該類叫做GameApp,那麼該目錄下的kv文件則必須為Game,如上圖所示,如果不是,那麼kv文件中的一些設定就不會生效。
比如設定一個標簽
Label:
id: time
text: 'xxxx'
font_size: 60
id為time,text文本內容為'xxxx',然後字體為60
好吧,點到為止吧,不過似乎什麼都沒點到~~~
你還有什麼想要補充的嗎?
你在看嗎?一起成長
B. linux系統拷貝windows電腦共享的文件,用python怎麼實現
裝個samba 一般來說,安裝samba後,有一個smb.conf(配置文件)的例子,修改一下就好了。 WINDOWS下的網上鄰居使用是NetBIOS協議,LINUX下使用功能強大的SAMBA可以實現與WINDOWS機子共享。下面具體就我的理解具體說一下。 首先當然是你必須安裝了SAMBA #apt-get install samba samba-common smbclient smbfs 其實使用SAMBA分成兩個方面,一個是linux機子上的資源給WINDOWS機子瀏覽,再一個是使用LINUX 機子瀏覽WINDOWS 的網上鄰居。現在假設使用WINDOWS的機子的IP是10.0.0.10,共享目錄是music,用戶名是:share,密碼是:yeah;使用 LINUX機子的IP是:10.0.0.20 一 . 從LINUX上獲取WINDOWS文件的基本方法(有3種方法) 1. smbmount---普通用戶就可以使用的命令 掛載文件 #smbmount //10.0.0.10/music /home/user/music -o "username=share,password=yeah" 主意與下面的mount不一樣的是-o後面一定要引號 卸載已經掛載的文件 #smbumount /home/user/music 2. mount---超級用戶才有的許可權,但效果與上面一樣 掛載文件 #mount -t smbfs -o username=share,password=yeah //10.0.0.10/music /home/user/music 卸載文件 #umount /home/user/music 註:以上兩個命令掛載要想顯示中文,必須添加如下參數 codepage=cp936,iocharset=utf8(與linux機的本地環境一致,如是gb2312,這兒也要寫成:iocharset=gb2312 ;codepage要與遠程一致,是指定源代碼文件的代碼頁---一個內>部表,操作系統用它將符號(字母、數字和標點)映射為字元編號。如932 代表日本漢字,950代表繁體中文字元集,說明一下就是codepage是cp936,而不是936,否則在有時顯示漢字還是亂碼。 3. 使用smbclient訪問Windows資源 它是一個類似於ftp操作方式,通過遠程操作的方式進行文件傳遞的軟體。為了獲得網路上可以訪問的計算機列表,首先需要使用 smbclient來獲得一個Windows計算機共享出來的資源,這需要使用-L參數訪問IPC #smbclient -L 192.168.1.150 -N 或者機器名 #smbclient -L hit -N 如果不清楚一個Windows計算機的NetBIOS名字,可以使用nmblookup先來解析NetBIOS名字 #nmblookup hit (若瀏覽網上鄰居用:#nmblookup -T "*") 當上面查到資源後,就可以用smbclient登陸了 #smbclient \\hit\music yeah -U share (其中yeah是密碼,share是用戶名) 執行smbclient命令成功後,進入smbclient環境,出現提示符:smb: >,然後就可以執行和ftp命令中相似的命令:cd, lcd, get ,mget ,put ,mput等,用法就跟FTP一樣了。 註:要想使用smbclient來訪問windows時,也需要使用UNC來標識Windows資源的位置。此時就需要了解 WindowsUNC在Unix>下進行表示的不同之處。不同之處在於Unix的shell下反斜線為特殊字元,它被定義為轉義恢復字元,表示將一些轉義字元恢復為其本身字元的意義。因此必須使用兩個反斜線才能等同於一個反斜線。因此一個UNC實際使用時應使用雙倍的反斜線。 若想使用基於圖形的客戶端:感覺比較好用的是tksmb和smb4k(KDE) 若只是以上使用不用配置/etc/samba/smb.conf,也不用啟動 samba 服務,甚至可以不裝samba程序 二. WINDOWS機子訪問在LINUX上的資源 需要使用兩個進程:nmbd smbd, 前者nmbd是提供WINDOWS瀏覽,後者smbd是針對WINDOWS瀏覽後的登陸等服務。 首先需要說明的是,當samba 還沒有添加用戶時,WINDOWS機子是登陸不上來的,所以第一步就是添加用戶: # smbpasswd -a myfirst 需要說明的是這個用戶必須是系統用戶,否則回提示 Failed to initialise SAM_ACCOUNT for user myfirst. Does this user exist in the UNIX password database ? Failed to modify password entry for user myfirst 當然可以對用戶進行映射,見後面說明。 接著就簡單了,就是配置/etc/samba/smb.conf,見下面一個配置以及相應說明,拷貝後您只需要稍稍修改一些你自己的信息就可以使用了(參考了前人的說明) /etc/samba/smb.conf文件 ## /etc/samba/smb.conf配置文件有三個重要的節:[global],[homes],[public] #Global (全局)參數,該部分設置整個系統的規則,定義了一些公共變數。 [global] netbios >#定義Windows系統「網上鄰居」中所見的機器名。 workgroup = workgroup #定義主機所在網路上所屬的NT域名或者工作組名稱 server string = FunField #對主機的說明信息,預設是:Samba Server hosts allow = 192.168.1. 192.168.3. #它允許設置哪些機器可以訪問samba伺服器 guest account = nobody invalid users = root #定義smb用戶名稱。 security = user #定義訪問許可權。訪問許可權由低到高有三種:share、user和server。其中share安全級別最低,user模式要求連接時輸入用戶名和口令 encrypt passwords = true #設置是否需要加密口令。因為Windows系列默認採用加密口令傳輸,而Linux默認採用非加密口令傳輸,為保證smb網路用戶的正常登錄,在user安全級下設置為加密,在share 安全級下可不設。 smb passwd file = /etc/samba/smbpasswd #由命令cat /etc/passwd mksmbpasswd.sh > /etc/samba/smbpasswd產生。 interfaces = 192.168.1.50/24 #配置smb服務所使用的網卡IP以及子網掩碼,如果有兩個以上網卡,要全部列出。 name resolve order = host dns bcast #設定smb服務時,從機器netbios名稱到IP地址的解析方式,默認順序為host lmhosts wins bcast。如果區域網內有DNS,可設置為host dns bcast。 wins support = no #設置是否有wins支持。 public = yes #為yes時,「網上鄰居」中可見該資源,否則不可見。 browseable = yes #為yes時,「網上鄰居」中可見該資源,否則不可見。 #printing = bsd # 指定Linux使用哪個列印機守護進程(bsd、sysv、hpux、aix、qnx、plp),同時向samba說明命令lpr和lpq的預設值。 #printcap ># 定義了列印配置文件所處的位置。 load printers = no # 表明是否載入printcap 定義的所有列印機以供瀏覽。 log file = /var/log/samba/log.%m # 定義日誌文件 max log 'size' = 1000 #日誌文件最大1000k (單位是KB) username map = /etc/samba/smbuser #允許管理員指定一個映射文件,該文件包含了在客戶機和伺服器之間進行用戶映射的信息。 用戶映射經常在windows 和linux 主機間進行。 兩個系統擁有不同的用戶賬號,用戶映射的目的是將不同的用戶映射成為一個用戶,便於共享文件。 #*********************************************************************# [homes] #該部分通常定義了Linux機器上共享的目錄資源,其名字可以由用戶確定。段中的設置控制了每一個用戶目錄的共享許可權。 comment = Home Directories #設定在瀏覽本機資源時,出現在指定資源旁邊的字元串。 browseable = yes #控制一項服務是否能夠出現在網上鄰居中,no意味著這個目錄將在瀏覽時顯示為要驗證的用戶名稱,yes則顯示 homes 和要驗證的用戶名稱的共享目錄。 writable = yes #控制是否允許通過驗證的用戶對主目錄有寫入的許可權,但最終取決於該目錄的 Unix 許可權。無論 Unix 的許可權怎樣, 設置 writable = no 後, 主目錄只能是只讀的。 create mask = 0700 directory mask = 0700 #若上面是可寫的,則設置寫文件和目錄時的屬性 #******************************************************************# [public] #用來指定某一特定用戶組或者用戶擁有訪問許可權的目錄配置分,配置共享目錄部分 comment = Public Stuff # 說明部分 path = /home/samba #共享的Linux目錄 writable = no #寫許可權 printable = no #列印許可權 用於用戶映射的文件/etc/samba/smbuser # smb.conf中全局參數 「username map」 指定的映射文件 root = admin administrator #Map Windows admin to root hawk = girl #Map the member of girl to hawk snake = boy # 等號左邊是單獨的Linux賬號,等號右邊是要映射的賬號列表。伺服器逐行分析映射文件,如果提供的賬號和某行有右側列表中的賬號匹配,就把它替換為等號左邊的賬號。
C. 利用python寫一段讀取電腦配置信息的程序
主要利用python的wmi模塊,提供非常多的信息。
importwmi
defsys_version():
c=wmi.WMI()
#操作系統版本,版本號,32位/64位
print(' OS:')
sys=c.Win32_OperatingSystem()[0]
print(sys.Caption,sys.BuildNumber,sys.OSArchitecture)
#CPU類型CPU內存
print(' CPU:')
processor=c.Win32_Processor()[0]
print(processor.Name.strip())
Memory=c.Win32_PhysicalMemory()[0]
print(int(Memory.Capacity)//1048576,'M')
#硬碟名稱,硬碟剩餘空間,硬碟總大小
print(' DISK:')
fordiskinc.Win32_LogicalDisk(DriveType=3):
print(disk.Caption,'free:',int(disk.FreeSpace)//1048576,'M ','All:',int(disk.Size)//1048576,'M')
#獲取MAC和IP地址
print(' IP:')
forinterfaceinc.Win32_NetworkAdapterConfiguration(IPEnabled=1):
print("MAC:%s"%interface.MACAddress)
forip_addressininterface.IPAddress:
print(" IP:%s"%ip_address)
#BIOS版本生產廠家釋放日期
print(' BIOS:')
bios=c.Win32_BIOS()[0]
print(bios.Version)
print(bios.Manufacturer)
print(bios.ReleaseDate)
sys_version()
顯示:
OS:
MicrosoftWindows10專業版1713464位
CPU:
Intel(R)Core(TM)[email protected]
8192M
DISK:
C:free:34165M All:120825M
D:free:265648M All:390777M
E:free:35669M All:204796M
F:free:5814M All:28163M
G:free:328650M All:329999M
IP:
MAC:00:50:56:C0:00:01
IP:192.168.182.1
IP:fe80::e0fb:efd8:ecb0:77f4
MAC:00:50:56:C0:00:08
IP:192.168.213.1
IP:fe80::8da1:ce76:dae:bd48
MAC:54:E1:AD:77:57:AB
IP:192.168.199.105
IP:fe80::aca8:4e6f:46e7:ef4a
BIOS:
LENOVO-1
LENOVO
20170518000000.000000+000
D. python可以改寫MBR嗎
肯定是可以的,你可以嘗試使用python的c擴展
一, 實驗內容
改寫bootsect.s和setup.s, 完成如下主要功能:
1, bootsect.s能夠在屏幕上列印一段提示信息"XXX is booting...", 其中XXX是你給自己的操作系統起的名字,例如LZJos、Sunix等.
2, bootsect.s能夠完成setup.s的載入, 並跳轉到setup.s開始地址執行.
3, setup.s能夠像屏幕輸出一行信息 "Now we are in SETUP"
4, setup.s能獲取至少一個基本的硬體參數(如內存參數、顯卡參數、硬碟參數等),將其存放在內存的特定地址,並輸出到屏幕上。
setup.s不再載入linux內核, 保持上述信息顯示到屏幕上即可
二, 實驗步驟
1, 完成bootsect的屏幕輸出功能
由於不需要載入linux內核,所以就不需要原始的linux代碼那麼復雜,比如: 將bootsect自身移動到0x90000處等操作,可以忽略的。
要顯示字元串,那麼字元串顯示到屏幕的哪裡呢?當然是當前游標的位置了!所以第一步就要先讀取游標的位置,這可以利用10號中斷的3號子程序來完成。要顯示字元串,可以利用10號功能的13號子程序來完成,需要注意的是一定要邊顯示字元邊移動游標,最終的游標要移動到字元串的末尾處。最後要注意用0xAA55來標記引導扇區。代碼如下:
! 文件:bootsect.s
entry _start
_start:
! 首先利用10號中斷的3號功能來讀取游標位置
mov ah,#0x03
xor bh,bh
int 0x10
! 再利用10號中斷的13號功能顯示字元串
mov cx,#50 ! 加上回車和換行,字元串一共包含50個字元,所以設置cx為50
mov bx,#0x0007
mov bp,#msg1
mov ax,#0x07c0
mov es,ax ! es:bp=顯示字元串的地址
mov ax,#0x1301
int 0x10
Inf_loop:
jmp Inf_loop ! 無限循環
! msg1處放置要顯示的字元串
msg1:
.byte 13,10 ! 換行+回車
.ascii "AXF OS is booting, my name is Aixiangfei ..."
.byte 13,10,13,10 ! 兩對換行+回車
! 下面是啟動盤具有有效引導扇區的標志. 僅供BIOS中的程序載入扇區時識別使用。
! 它必須位於引導扇區的最後兩個位元組中.
.org 510
boot_flag:
.word 0xAA55 ! 引導扇區的標記就是0XAA55
編譯和運行: 進入~/oslab/linux-0.11/boot/目錄,編譯並連接:
as86 -0 -a -o bootsect.o bootsect.s
ld86 -0 -s -o bootsect bootsect.o
參數說明:-0(注意:這是數字0,不是字母O)表示生成8086的16位目標程序,-a表示生成與GNU as和ld部分兼容的代碼,-s告訴鏈接器ld86去除最後生成的可執行文件中的符號信息。
如果這兩個命令沒有任何輸出,說明編譯與鏈接都通過了。需要留意的生成的bootsect的大小是544位元組,而引導程序必須要正好佔用一個磁碟扇區,即512個位元組。造成多了32個位元組的原因是ld86產生的是Minix可執行文件格式,這樣的可執行文件處理文本段、數據段等部分以外,還包括一個Minix可執行文件頭部。所以最後必須要把這多餘的32個位元組刪掉,可以用linux自帶的工具dd來完成:
dd bs=1 if=bootsect of=Image skip=32
去掉這32個位元組後,將生成的文件拷貝到linux-0.11目錄下,並一定要命名為「Image」(注意大小寫)。然後就可以run了
程序有可能需要不斷地修改調試,為了方便,可以將上述的一系列操作寫道一個shell腳本文件 cbootsect.sh 中:
#!/bin/sh
as86 -0 -a -o bootsect.o bootsect.s
ld86 -0 -s -o bootsect bootsect.o
dd bs=1 if=bootsect of=Image skip=32
cp Image ../
../../run
運行結果:
2, setup的載入
首先要確定setup是在磁碟的0磁軌2扇區,linux 0.11中的setup佔了4個扇區,而我們最後要寫的setup顯然沒有那麼復雜,所以可以只用1個扇區就可以了。另外,由於bootsect位於0x7c00處,佔用512個位元組,所以可以將setup載入到0x7e00處。要想從磁碟中載入數據到內存,可以利用BIOS提供的13號中斷輕松完成。最後就直接用jumi指令跳轉到0x7e00處即可。對前面的bootsect.s擴展之後的完整代碼如下:
! 文件:bootsect.s
SETUPLEN = 1
SETUPSEG = 0x07e0
entry _start
_start:
! 首先利用10號中斷的3號功能來讀取游標位置
mov ah,#0x03
xor bh,bh
int 0x10
! 再利用10號中斷的13號功能顯示字元串
mov cx,#50 ! 加上回車和換行,字元串一共包含50個字元,所以設置cx為50
mov bx,#0x0007
mov bp,#msg1
mov ax,#0x07c0
mov es,ax ! es:bp=顯示字元串的地址
mov ax,#0x1301
int 0x10
load_setup:
mov dx,#0x0000 ! 設置驅動器和磁頭(drive 0, head 0): 軟盤0磁頭
mov cx,#0x0002 ! 設置扇區號和磁軌(sector 2, track 0):0磁頭、0磁軌、2扇區
mov bx,#0x0200 ! 設置讀入的內存地址:BOOTSEG+address = 512,偏移512位元組
mov ax,#0x0200+SETUPLEN ! 設置讀入的扇區個數(service 2, nr of sectors),
! SETUPLEN是讀入的扇區個數,Linux 0.11設置的是4,
! 我們不需要那麼多,我們設置為1
int 0x13 ! 應用0x13號BIOS中斷讀入1個setup.s扇區
jnc ok_load_setup ! 讀入成功,跳轉到ok_load_setup: ok - continue
mov dx,#0x0000 ! 軟碟機、軟盤有問題才會執行到這里
mov ax,#0x0000 ! 否則復位軟碟機
int 0x13
j load_setup ! 重新循環,再次嘗試讀取
ok_load_setup:
jmpi 0,SETUPSEG
! msg1處放置要顯示的字元串
msg1:
.byte 13,10 ! 換行+回車
.ascii "AXF OS is booting, my name is Aixiangfei ..."
.byte 13,10,13,10 ! 兩對換行+回車
! 下面是啟動盤具有有效引導扇區的標志. 僅供BIOS中的程序載入扇區時識別使用。
! 它必須位於引導扇區的最後兩個位元組中.
.org 510
boot_flag:
.word 0xAA55 ! 引導扇區的標記就是0XAA55
3, 完成setup的屏幕輸出功能
這個很簡單,跟bootsect是一樣的。代碼如下:
! 文件:setup.s
entry _start
_start:
! 首先利用10號中斷的3號功能來讀取游標位置
mov ah,#0x03
xor bh,bh
int 0x10
! 再利用10號中斷的13號功能顯示字元串
mov cx,#26
mov bx,#0x0007
mov bp,#msg
mov ax,cs
mov es,ax
mov ax,#0x1301
int 0x10
Inf_loop:
jmp Inf_loop ! 無限循環
msg:
.byte 13,10
.ascii "Now we are in SETUP."
.byte 13,10,13,10
.org 510
boot_flag:
.word 0xAA55
編譯和與運行:現在有兩個文件都要編譯、鏈接。一個個手工編譯,效率低下,所以藉助Makefile是最佳方式。linux 0.11中Makefile文件已經幫我們把這件事做好了。進入liux-0.11目錄後,使用命令:
$ make BootImage
但是我們發現竟然出現了錯誤:
原因:這是因為make根據Makefile的指引執行了tools/build.c,它是為生成整個內核的鏡像文件而設計的,沒考慮我們只需要bootsect.s和setup.s的情況。build.c從命令行參數得到bootsect、setup和system內核的文件名,將三者做簡單的整理後一起寫入Image。其中system是第三個參數(argv[3])。當「make all」或者「makeall」的時候,這個參數傳過來的是正確的文件名,build.c會打開它,將內容寫入Image。而「make BootImage」時,傳過來的是字元串"none"。所以,修改build.c的思路就是當argv[3]是"none"的時候,只寫bootsect和setup,忽略所有與system有關的工作,或者在該寫system的位置都寫上「0」。
修改build.c文件很簡單,只需要把第178到183這幾行代碼刪除即可!
// if ((id=open(argv[3],O_RDONLY,0))<0)
// die("Unable to open 'system'");
// if (read(id,buf,GCC_HEADER) != GCC_HEADER)
// die("Unable to read header of 'system'");
// if (((long *) buf)[5] != 0)
// die("Non-GCC header of 'system'");
run
4, 讀取硬體參數
這個部分是最復雜的了。需要列印的硬體信息有:游標位置,內存大小,磁碟的柱面數,磁頭數,每磁軌的扇區數。在這個實驗中,這些參數的信息可以保存在內存中的任意位置,在linux 0.11中,這些參數信息是被保存到了0x90000處,所以不妨跟linux 0.11一樣。
(1)獲取硬體參數
獲得游標位置信息,這個很簡單,只需要調用13號中斷的3號子程序就可以得到,前面已經用過了的。
獲得內存大小,可以調用用15號中斷的88號子程序得到,也很簡單。
與磁碟相關的信息稍微復雜一點,這些信息被保存在0x0000:0x0104地址處的16個位元組的中,這16個位元組的信息叫做「磁碟參數表」。所以獲得磁碟信息的方法就是復制數據。
(2)數字轉字元
現在已經將這些硬體參數取出來放在了0x90000處,接下來的工作是將這些參數顯示在屏幕上。這些參數都是一些無符號整數,所以需要做的主要工作是用匯編程序在屏幕上將這些整數用16進制的形式顯示出來。
因為十六進制與二進制有很好的對應關系(每4位二進制數和1位十六進制數存在一一對應關系),顯示時只需將原二進制數每4位劃成一組,按組求對應的ASCII碼送顯示器即可。ASCII碼與十六進制數字的對應關系為:0x30~0x39對應數字0~9,0x41~0x46對應數字a~f。從數字9到a,其ASCII碼間隔了7h,這一點在轉換時要特別注意。為使一個十六進制數能按高位到低位依次顯示,實際編程中,需對bx中的數每次循環左移一組(4位二進制),然後屏蔽掉當前高12位,對當前餘下的4位(即1位十六進制數)求其ASCII碼,要判斷它是0~9還是a~f,是前者則加0x30得對應的ASCII碼,後者則要加0x37才行,最後送顯示器輸出。以上步驟重復4次,就可以完成bx中數以4位十六進制的形式顯示出來。
因為在輸出的時候需要調用多次,所以最好把這個功能寫成一個函數print_bx,方便使用。既然要用到函數,故一定要先設置好棧。為了方便,還可以寫一個函數print_nl實現換行的功能。
INITSEG = 0x9000
entry _start
_start:
! 在顯示字元串之前必須先獲取當前游標的位置,這樣就可以把字元串顯示到當前游標處了
mov ah,#0x03
xor bh,bh
int 0x10
! 利用10號中斷的13號功能列印字元串"Now we are in SETUP."
mov cx,#26
mov bx,#0x0007
mov bp,#msg1
mov ax,cs
mov es,ax
mov ax,#0x1301
int 0x10
! 下面開始讀取一些硬體參數
! 讀入游標位置信息,保存到0x90000處
mov ax,#INITSEG
mov ds,ax
mov ah,#0x03
xor bh,bh
int 0x10
mov [0],ds
! 讀入內存大小位置信息,保存到0x90002處
mov ah,#0x88
int 0x15
mov [2],ax
! 從0x41處拷貝16個位元組(磁碟參數表)到0x90004處
mov ax,#0x0000
mov ds,ax
lds si,[4*0x41]
mov ax,#INITSEG
mov es,ax
mov di,#0x0004
mov cx,#0x10
rep ! 重復16次
movsb
! 先列印游標位置
! 列印字元串之前要先讀取游標位置,將字元串列印到當前游標處
mov ah,#0x03
xor bh,bh
int 0x10
! 列印字元串 "Cursor POS:"
mov cx,#11
mov bx,#0x0007
mov ax,cs
mov es,ax
mov bp,#msg2
mov ax,#0x1301
int 0x10
! 調用列印函數,列印游標位置
mov ax,#0x9000
mov ds,ax
mov dx,0x0
call print_hex
call print_nl
! 列印內存大小
! 列印字元串"Memory SIZE:"
mov ah,#0x03
xor bh,bh
int 0x10 ! 讀取游標位置
mov cx,#12
mov bx,#0x0007
mov ax,cs
mov es,ax
mov bp,#msg3
mov ax,#0x1301
int 0x10
! 調用列印函數,列印內存大小信息
mov ax,#0x9000
mov ds,ax
mov dx,0x2
call print_hex
! 列印字元串"KB"
mov ah,#0x03
xor bh,bh
int 0x10 ! 讀取游標位置
mov cx,#2
mov bx,#0x0007
mov ax,cs
mov es,ax
mov bp,#msg4
mov ax,#0x1301
int 0x10
call print_nl
!列印柱面數
! 列印字元串"Cyls"
mov ah,#0x03
xor bh,bh
int 0x10 ! 讀取游標位置
mov cx,#5
mov bx,#0x0007
mov ax,cs
mov es,ax
mov bp,#msg5
mov ax,#0x1301
int 0x10
! 調用列印函數列印磁碟柱面數
mov ax,#0x9000
mov ds,ax
mov dx,0x4
call print_hex
call print_nl
! 列印磁頭數
! 列印字元串"Heads:"
mov ah,#0x03
xor bh,bh
int 0x10 ! 讀取游標位置
mov cx,#6
mov bx,#0x0007
mov ax,cs
mov es,ax
mov bp,#msg6
mov ax,#0x1301
int 0x10
! 調用列印函數列印磁碟磁頭數
mov ax,#0x9000
mov ds,ax
mov dx,0x6
call print_hex
call print_nl
! 列印每磁軌扇區數
! 列印字元串"sectors"
mov ah,#0x03
xor bh,bh
int 0x10 ! 讀取游標位置
mov cx,#8
mov bx,#0x0007
mov ax,cs
mov es,ax
mov bp,#msg7
mov ax,#0x1301
int 0x10
! 調用列印函數列印扇區數
mov ax,#0x9000
mov ds,ax
mov dx,0x12
call print_hex
call print_nl
Inf_loop:
jmp Inf_loop ! 無限循環
! print_hex函數:將一個數字轉換為ascii碼字元,並列印到屏幕上
! 參數值:dx
! 返回值:無
print_hex:
mov cx,#4 ! 要列印4個十六進制數字,故循環4次
print_digit:
rol dx,#4 ! 循環以使低4比特用上 !! 取dx的高4比特移到低4比特處
mov ax,#0xe0f ! ah = 請求的功能值,al = 半位元組(4個比特)掩碼
and al,dl ! 取dl的低4比特值
add al,#0x30 ! 給al數字加上十六進制0x30
cmp al,#0x3a
jl outp ! 如果是一個不大於十的數字
add al,#0x07 ! 如果是a~f,要多加7
outp:
int 0x10
loop print_digit ! 用loop重復4次
ret
! 列印回車換行
print_nl:
mov ax,#0xe0d
int 0x10
mov al,#0xa
int 0x10
ret
msg1:
.byte 13,10
.ascii "Now we are in SETUP."
.byte 13,10,13,10
msg2:
.ascii "Cursor POS:"
msg3:
.ascii "Memory SIZE:"
msg4:
.ascii "KB"
msg5:
.ascii "Cyls:"
msg6:
.ascii "Heads:"
msg7:
.ascii "Sectors:"
.org 510
boot_flag:
.word 0xAA55
運行結果:
E. 怎樣查看python安裝路徑
方法如下:
一、linux查看python安裝位置。
有時我們需要查看python的安裝位置,好安裝第三方庫,linux可以先python進入python cmd,然後輸入【import sys】【print sys.path】,即可列印所有python路徑。
二、想要查看ubuntu中安裝的python路徑。
方法一:whereis python
方法二:which python
五、sys.executable是當前Python解釋器(或者其他Python實現)的路徑去掉後面一個路徑分隔符(Windows下是'')後的部分即可>>> import sys>>> path = sys.executable>>> print pathC:Python25pythonw.exe>>> folder = path[ 0 : path.rfind( os.sep ) ]>>> print folderC:Python25>>>。