http://lpn.rnbhq.org/tools/xemacs/emacs_ref.html
Wednesday, August 22, 2012
Monday, August 20, 2012
COSCUP 2012 心得文
今年 COSCUP 跟去年不一樣,沒有參與到跟鄉民一起 DDOS 搶票
一進到會場,一個頭髮長長的怪人突然跟我說好久不見,原來是去年認識的新朋友 penk! 隔了一年還記得我真是令人害羞
而且早上只有 tea break,只有 tea 的 break Orz 說好的早餐呢QAQ
接下來的兩場是由隔壁匪校清大資工兩位學長的 talk
R1 ARMvisor:ARM架構上系統虛擬機的實作 Peter Chang
R1 PQEMU: A Parallel System Emulator Based on QEMU Aquila
R1 Code: 改變未來的力量 Sam Ding (丁俊宏)
這個把 bash 寫成詭異的 Python 感覺很特別,不過覺得應該還是 just for fun 而已吧,沒多大實用性
拿的是 BlueT 老大給的 VIP code ,說是幫忙擺攤,其實也是在 Ubuntu-TW 攤位上跟朋友一起聊天、分享而已 lol
COSCUP,台灣開源人年會,身為 open source 的熱血愛好者,當然是不能缺席啦
不像去年高中剛畢業時,什麼都不懂,今年感覺比較不同的是在大一這一年對於 open source 的社群參與,不論是做翻譯、在活動上分享,還是實際去寫 code 送 patch ,確確實實的參與感
今年各大 conf 議程的趨勢給人的感覺是,前端和行動裝置的東西愈來愈多,包括 php 和 JavaScript 的開發者都能獨立出來各開一的 conference ,代表這些領域的社群也愈來愈活躍熱絡了
雖然我對前端和 mobile 的東西比較沒興趣,今年 COSCUP 還是有很多議程吸引我的眼球
https://gist.github.com/3326200 今年還特地提早研究一下議程
另外也許是 cloud 的 issue 愈講愈多吧,virtualization 的主題也愈顯重要,而這也是我有興趣的地方
第一天的點心真的有點糟,完全搶不到,好在第二天的點心量有比較多,彌補了一點賭爛的心情
一進到會場,一個頭髮長長的怪人突然跟我說好久不見,原來是去年認識的新朋友 penk! 隔了一年還記得我真是令人害羞
一早的 keynote 是 ericsk 上官大大所講的 Azure 如何擁抱社群,其實我覺得跟 PyCON.tw 的那場有點相似 而且 Live DEMO 好像失敗了
而且早上只有 tea break,只有 tea 的 break Orz 說好的早餐呢QAQ
接下來的兩場是由隔壁
R1 ARMvisor:ARM架構上系統虛擬機的實作 Peter Chang
R1 PQEMU: A Parallel System Emulator Based on QEMU Aquila
因為跟 jserv 那邊打工的東西相關,整個人聽到都燃起來了!
不過這個 talk 的內容也有些難度,不熟悉 qemu 的工作機制和 OS 相關知識的人聽起來可能會比較吃力一點
第一個是把原生不支援虛擬化的 ARM 上面如何做出 hypervisor
另一個 talk 是如何在 qemu 上面做出真。平行運算,原來原本的 qmeu 是用 single threading 做的假平行XD
R1 How to write a SNES emulator in Javascript 魏澤人
再來是最酷的超任模擬器,由魏澤人教授做的,上次在 PyCON 提過的主題延續
不過這個 talk 的內容也有些難度,不熟悉 qemu 的工作機制和 OS 相關知識的人聽起來可能會比較吃力一點
第一個是把原生不支援虛擬化的 ARM 上面如何做出 hypervisor
另一個 talk 是如何在 qemu 上面做出真。平行運算,原來原本的 qmeu 是用 single threading 做的假平行XD
R1 How to write a SNES emulator in Javascript 魏澤人
再來是最酷的超任模擬器,由魏澤人教授做的,上次在 PyCON 提過的主題延續
demo 超酷的,有 256 色的瑪力歐!!!!
R1 Code: 改變未來的力量 Sam Ding (丁俊宏)
這場的 talk 倒是走溫馨路線,講說他對於 open source 的一些想法和行動,組織了一個社群
沒有吃到早上的點心的關係,突然覺得中午的雞腿便當特別好吃(欸
是說,小 P 月湖和小趴三隻苦力怕還真是吸引大家阿
接來跑到社群攤位玩耍,跟 Python.tw 的 yyc 聊天和 Ubuntu 攤位聊
R1 開源程式語言授權之旅:Perl/Python/ PHP/Ruby/ Scala/Node.js 的智財權挑戰 ant
後來這場也是非常特別,講了一般人不太會去注意的議題,在引入/編譯 lib 時要特別的去看有沒有授權衝突的情況,也學到 Perl5 和 Perl6 的授權的差別和何謂 "藝術家條款"
另外 Ruby 的用戶可能比較吃虧,他的一些授權有些一律的地方,在使用上也是沒辦法直接 rvm 弄個 gem 下來,不然會悲劇XD
R0 How to write a bash script like python? 黃宇新
這個把 bash 寫成詭異的 Python 感覺很特別,不過覺得應該還是 just for fun 而已吧,沒多大實用性
閃電秀時間依舊是小 B 學長的風格,今年沒有 Ben 很可惜QQ
晚上的 BoF 到處跑,跑去 Ubuntu-TW、拉拉學長開的 NCTUCS 同學會、imacat 那邊的 Ruby 戰士解題 小趴都不會寫QQ ,另外也跟一些人認識,真相到 Nani 學妹,順便跑去 get 某君君的工作人員名牌(?)
結束後跑去看電影,鄉民的正義XD
太多好笑的點可以吐嘈了,Enter 根本就是直接無差別地圖兵器阿!
另外主角的名字跟 Jeffxx 學長一樣實在是太好笑了
Keynote: Open Up the Cloud Ted Chang
這感覺是廣達的廣告時間... 有點囧
MCLinker – an LLVM Linker for Mobile Computing 陳柏聿
連 @jserv 前輩都稱讚的網襪正妹講者!介紹了 Linker 的相關概念,也是要對 compiler 比較有概念的人比較有感覺,超級夯的議程
正妹講者給人的感覺跟 jsliang 學姊很像 >////<
技術含量很高的 talk
Emacs - 程式開發神兵利器 陳侃如
這場議程認識到一些 emacs 相關的基礎概念,對於忠實的 vim user 而言,也算是認識到另一個 editor,雖然用起來沒有像是 vim 那麼順手,卻也不失為一樣 "神兵利器"
希望能有機會跟 letoh 和 superbil 等朋友繼續學習相關用法
之後又跑去 Ubuntu-TW 攤位逛逛,差點騙到一個便當(?)
第一次自幹作業系統核心就上手 Jserv
下午的 keynote 是 jserv 再次表演神技,雖然是跟 PCMan 相撞,但是霸氣四射的直接打開 "群群" 模式
透過 vim macro 錄影 live coding,現場在 15 分鐘之內自幹出一個 OS
另外主角的名字跟 Jeffxx 學長一樣實在是太好笑了
Keynote: Open Up the Cloud Ted Chang
這感覺是廣達的廣告時間... 有點囧
MCLinker – an LLVM Linker for Mobile Computing 陳柏聿
連 @jserv 前輩都稱讚的網襪正妹講者!介紹了 Linker 的相關概念,也是要對 compiler 比較有概念的人比較有感覺,超級夯的議程
正妹講者給人的感覺跟 jsliang 學姊很像 >////<
技術含量很高的 talk
Emacs - 程式開發神兵利器 陳侃如
這場議程認識到一些 emacs 相關的基礎概念,對於忠實的 vim user 而言,也算是認識到另一個 editor,雖然用起來沒有像是 vim 那麼順手,卻也不失為一樣 "神兵利器"
希望能有機會跟 letoh 和 superbil 等朋友繼續學習相關用法
之後又跑去 Ubuntu-TW 攤位逛逛,差點騙到一個便當(?)
第一次自幹作業系統核心就上手 Jserv
下午的 keynote 是 jserv 再次表演神技,雖然是跟 PCMan 相撞,但是霸氣四射的直接打開 "群群" 模式
jserv: 台大學生覺得 OS 很難怎麼辦,只好幹出一個給他了 ˊ_>ˋ
再來是 clkao 前輩的 talk
LiveScript - duty-free javaScript /免稅 JavaScript clkao
LiveScript 是類似 coffeescript 一樣可以 compile 成 JavaScript 的新語言,主要講解這個新語言的特色,我覺得感覺像是融入了各家 (Perl, Ruby, Haskell 等) 語言的特性,設計出一套非常乾淨簡潔的 syntax sugar 來避免語言本身(JavaScript) 的語法 "抽稅"
第二天點心比昨天好多了,怒吃了六盤!!!
迎接 retina 大航海時代來臨,來談一下 SVG 鄭鴻旗
retina 螢幕時代下,SVG 這種可以自由伸展大小的格式脫穎而出,學到了一些 SVG 的相關知識,原來簡單的動畫也可以用 SVG 來做,講者表示:你寫的 svg code 很髒,我不想用!!!!XDD
SVG 原來可以玩很多花樣不只拿來做 wargame 題目
在RepRap架構下開發擴充-傾斜式生成平台 Kamm (闞凱宇)
這台 3D printer 印象中在去年 COSCUP 也有看過,透過傾斜的方式產生比較精緻的模型,不知道這些研究在台灣那時候才會開始變得熱絡普及起來
(新)酷音輸入法 12 年發展回顧 Jserv
原本說好要 30min 的 QA 時間,結果也還是剩下講講歷史,輸入法的故事很令人感動,大眼同學, DrKen 學長的作品也被拿出來介紹,希望有更多人可以對這塊有興趣,投入更多相關的研究並開放出來給整個中文使用者社群
(很可惜我自己興趣也不再這邊QAQ)
LT 太多爭議就算了吧... 沒有香港朋友 Ben 真的挺可惜的
COSCUP 還是一樣,40% 學東西,60% 交朋友然後幹瓶可樂回家
再來是 clkao 前輩的 talk
LiveScript - duty-free javaScript /免稅 JavaScript clkao
LiveScript 是類似 coffeescript 一樣可以 compile 成 JavaScript 的新語言,主要講解這個新語言的特色,我覺得感覺像是融入了各家 (Perl, Ruby, Haskell 等) 語言的特性,設計出一套非常乾淨簡潔的 syntax sugar 來避免語言本身(JavaScript) 的語法 "抽稅"
第二天點心比昨天好多了,怒吃了六盤!!!
迎接 retina 大航海時代來臨,來談一下 SVG 鄭鴻旗
retina 螢幕時代下,SVG 這種可以自由伸展大小的格式脫穎而出,學到了一些 SVG 的相關知識,原來簡單的動畫也可以用 SVG 來做,講者表示:你寫的 svg code 很髒,我不想用!!!!XDD
SVG 原來可以玩很多花樣
在RepRap架構下開發擴充-傾斜式生成平台 Kamm (闞凱宇)
這台 3D printer 印象中在去年 COSCUP 也有看過,透過傾斜的方式產生比較精緻的模型,不知道這些研究在台灣那時候才會開始變得熱絡普及起來
(新)酷音輸入法 12 年發展回顧 Jserv
原本說好要 30min 的 QA 時間,結果也還是剩下講講歷史,輸入法的故事很令人感動,大眼同學, DrKen 學長的作品也被拿出來介紹,希望有更多人可以對這塊有興趣,投入更多相關的研究並開放出來給整個中文使用者社群
(很可惜我自己興趣也不再這邊QAQ)
LT 太多爭議就算了吧... 沒有香港朋友 Ben 真的挺可惜的
COSCUP 還是一樣,40% 學東西,60% 交朋友
Saturday, August 11, 2012
using Fackbook via command line
身為一個 geek ,當然是 CLI 最高阿!
繼之前玩過 turses twitter client 後,另一個有趣的 cmd tool
最初是在 @RJking 的噗浪上 看到
http://www.webupd8.org/2012/08/use-facebook-from-command-line-with.html
安裝方法裏面有
測試了 post 跟 comment
看來是很成功XDrz
繼之前玩過 turses twitter client 後,另一個有趣的 cmd tool
最初是在 @RJking 的噗浪上 看到
http://www.webupd8.org/2012/08/use-facebook-from-command-line-with.html
安裝方法裏面有
測試了 post 跟 comment
看來是很成功XDrz
官方 wiki => http://fbcmd.dtompkins.com/
語氣非常無耐阿 lol
Design
Why did you write it in PHP? (yuck).
It was written in PHP because originally the only API that Facebook officially supported was PHP. It wasn't my first choice either, and I had to learn PHP. However, in retrospect, It's turned out to be a wise decision. The code is reasonably clean and very portable. Sure, it might be a bit of a pain to install PHP if it's not already there, but compared to the ordeal of getting code that will compile easily on any platform (including Windows) it's pretty painless.
Tuesday, August 7, 2012
create ramdisk on Ubuntu
很簡單,只要兩步驟而已
mkdir -p /tmp/ram sudo mount -t tmpfs -o size=512M tmpfs /tmp/ram/
當然,也可以直接把他寫進去 /etc/fstab
要把 google-chrome 的 cache 放進去 ramdisk 的話,可以用 soft link
rm -r ~/.cache/google-chrome ln -s /tmp/ram/ ~/.cache/google-chrome
拿來掛 megnet link 做實驗,速度可以衝到每秒 7M... 超爽
Reference:
http://ubuntublog.org/how-to-create-ramdisk-linux.htm
http://www.linuxscrew.com/2010/03/24/fastest-way-to-create-ramdisk-in-ubuntulinux/
http://ubuntuforums.org/showthread.php?t=1772492
Monday, July 23, 2012
HIT2012 解題心得
首先感謝強者我朋友 rsggg 大大備份!
http://rsghost.org/backup/wargame.hitcon.org/
Web 1
研究了很久,大概知道是要透過傳 get 繞過 php script 的過濾把東西放到
yourfiles 底下,不過最後還是要撞豆腐惹QQ
Web 2
Orange: 漏洞利用的思路是很重要的! 其實防禦的思路也很重要(?
這題我沒有 try 出來,不過公佈 hint 時有給 phpMyAdmin 的 id / password
我一拿到 password 後就馬上改掉了XD 別人都衝不進去 phpMyAdmin ,類似搶旗
的暗黑玩法
Web 3
不會,不過也有想出防禦模式,透過 Web 2 phpMyAdmin 可以進去看 sqln00b 的 db
,可以去把 php code 裏面的 sqln00b 的密碼改掉,這樣整關就不用打了(?
Misc 1
Hacks in Taiwan !!
Misc 2
找到官網最底下的吐嘈圖,svg 解開後有一筆 k 的標籤,再解 base64
<hitcon2012 k="U2NhbGFibGUgVmVjdG9yIEdyYXBoaWNz" />
echo "U2NhbGFibGUgVmVjdG9yIEdyYXBoaWNz" | base64 -d
=> Scalable Vector Graphics
Misc 3
給出一張圖,原本以為是要去找小角落或是把顏色反相後去看,結果是實體 Key XD
路邊可以撿到印有 key 的指示圖www
Misc 4
寫 code 硬炸 CRC32,每個 file 2 byte 去解,這題 BlueT 跟魏藥有把東西解開,
不過弄到一筆 md5,傳過來我這邊 crack 了一個晚上沒東西XD 結果 md5 就直接是 key!
Misc 5
就在影片裡囉XDDD
Forensics 1
魏藥發現 BIOS 錯誤輸入三次的 error code 丟 google 可以找到到 key
Binary 3
單打獨鬥是打不過的,我 VM 直接去改 system 時間就噴 key 了XDDDD
不過正規的作法好像是要把 single threading 改成 multithreading 去跑
Binary 6
這題去把 doc 改成 zip 之後解出來,media 底下的圖片很可疑,Hexdump 後
有找到一段加密過的東西,可是最後想不出來是哪種加密法
好像 PLUSX 也卡在這裡
Binary 7
晚上睡不著用 IDA pro 去看 t100.exe ,把出現 key.txt 附近的 string 拼起來
就是 key 了!
雖然我為我們 Team 貢獻的 500 分都是 Binary 的題目,不過我覺得我應該就只是剛好
運氣好吧XD 這次的 wargame 是我第一次在 HIT 玩,關主們出的題目真的很有水準,玩
的非常開心!其他的部份也是完全靠強者隊友罩 BlueT,魏藥,TW1943
大家都辛苦了 m(_ _)m
這次的題目讓我深刻的知道我對各項技術不熟的地方,不會 web 跟 sql 根本哭哭阿QQ
binary 的部份也希望明年可以再加油,今年完全是神運氣XD
總之,雖然打的很累,不過真的玩的很開心!明年再加油!
Wednesday, July 11, 2012
some fun command line tools
從這篇文章上看到,挑部份有趣的來講XD
http://coolshell.cn/articles/7829.html
原文
http://kkovacs.eu/cool-but-obscure-unix-tools
tpp, 一個很 geek 的簡報工具
http://www.ngolde.de/tpp.html
cowsay, Perl 小玩具,讓牛來講話,也支援很多動物 (也有 xcowsay 可以玩XD)
http://en.wikipedia.org/wiki/Cowsay
線上體驗版(?)
http://www.flamingtext.com/tools/cowsay/
fortune | xcowsay 也可以這樣玩XD
sl (Steam Locomotive ), 歡樂小火車,有 -a -l -F 三種玩法
linuxlogo, 毫無反應,就是印出各種 distro 的 logo XD http://packages.debian.org/search?keywords=linuxlogo
http://coolshell.cn/articles/7829.html
原文
http://kkovacs.eu/cool-but-obscure-unix-tools
tpp, 一個很 geek 的簡報工具
http://www.ngolde.de/tpp.html
cowsay, Perl 小玩具,讓牛來講話,也支援很多動物 (也有 xcowsay 可以玩XD)
http://en.wikipedia.org/wiki/Cowsay
< This APT has Super Cow Powers. > -------------------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
線上體驗版(?)
http://www.flamingtext.com/tools/cowsay/
fortune | xcowsay 也可以這樣玩XD
sl (Steam Locomotive ), 歡樂小火車,有 -a -l -F 三種玩法
linuxlogo, 毫無反應,就是印出各種 distro 的 logo XD http://packages.debian.org/search?keywords=linuxlogo
Tuesday, July 10, 2012
emesene 2.12.3 password hacking
閒來無事逛了一下 exploit-db (謎:怎麼這麼閒)
看到這篇頗有趣的
http://www.exploit-db.com/exploits/19517/
把 emesene (Linux 上的一個 MSN client)user password 弄出來的小 Perl script
就想說也來檢查一下我的 emesene
一看之下才發現真歡樂,
emesene 的 ~/.config/emeseme2/config 裏面 passwd 只是簡單的 base64 XD
而且他是 -rw-rw-r--
看到這篇頗有趣的
http://www.exploit-db.com/exploits/19517/
把 emesene (Linux 上的一個 MSN client)user password 弄出來的小 Perl script
就想說也來檢查一下我的 emesene
一看之下才發現真歡樂,
emesene 的 ~/.config/emeseme2/config 裏面 passwd 只是簡單的 base64 XD
而且他是 -rw-rw-r--
Tuesday, July 3, 2012
things about STM32L-discovery
這邊筆記跟 @jserv 前輩學習 STM32 小玩具的一些小心得
暑假前應該這篇文章會一直更新(?)
============================================
首先準備 tool chains
到這裡去找 arm-none-eabi 的工具
http://www.mentor.com/embedded-software/sourcery-tools/sourcery-codebench/editions/lite-edition/request?id=e023fac2-e611-476b-a702-90eabb2aeca8&returnURL=https%3A%2F%2Fsourcery%2Ementor%2Ecom%2FGNUToolchain%2Frelease830%3Flite%3Darm%26cmpid%3D7108%26downloadlite%3Dscblite2012&downloadlite=scblite2012&fmpath=/embedded-software/sourcery-tools/sourcery-codebench/editions/lite-edition/form
很該死的註冊完後應該可以抓到 arm-2012.03-56-arm-none-eabi-i686-pc-linux-gnu.tar.bz2
解壓後放在一個跟 project 相關的資料夾之後把路徑加到現在的 bash shell 上
export PATH=$PATH:/home/xatierlike/stlink/arm-2012.03/bin
然後到 github.com 上面去把 texane/stlink clone 下來
git clone https://github.com/texane/stlink.git
然後想辦法去找個可以玩耍的 demo code 下來...
昨天跟 jserv 找可以用的 code 找到快哭了QQ 幾乎沒一個能用的 OTZ
最後找到這邊去把他的 blinky.zip 弄下來
http://gostm32.blogspot.tw/2010/09/blinky-ii.html
這裡還需要用 vim 改一下 Makefile,%s/elf/none-eabi/g
原本的 blinky 是用 arm-elf-* tools 工作的,而我用的是 arm-none-eabi-* tools
會後把 make 出來的 blinky.bin 燒進去 STM32 的 flash 就可以囉
今天晚上跟 jserv 研究他那邊弄過來的 qemu code
不知道為什麼我這邊就是跑不起來 ><
於是先去吃宵夜了XD
吃完宵夜後回來改 code 把中間改掉... 神奇的可以動了
但是當下我不知道為什麼,明明 socket.gethostname 得到的也是我機器的 hostname ...
根據 http://docs.python.org/library/socket.html#socket.gethostname
Return a string containing the hostname of the machine where the Python interpreter is currently executing.
我在我本機工作, gethostname 要到的理論上是跟在 shell 上打 hostname 一樣的結果
後來 方括號拉拉學長 提出了令我念頭一轉的問題點
問題是你hostname如果和我一樣在/etc/hosts查不到,你就不能直接用"localhost"去bind, 要用127.0.0.1
我馬上 ...
幹~~~~~~ 單純我 /etc/hosts 不知道哪時候被我腦殘動到 OTZ
============================================
原本聽 jserv 的去找 github 上面的 Qemu git
不斷的 make 失敗...
結果後來才發現東西是太舊的..囧
真。Qemu git
http://git.qemu.org/qemu.git
arm instruction
it instruction, condition (cbz / cnbz)
============================================
basic computer organization
http://goo.gl/jW6A0
Intro to Git for the Perl Hacker
http://marklodato.github.com/visual-git-guide/index-en.html
git labs
http://gitimmersion-apputu.rhcloud.com/
http://gitimmersion-apputu.rhcloud.com/lab_42.html
arn instructions
http://simplemachines.it/doc/arm_inst.pdf
arm-none-eabi-gcc -static -fno-common -Os -mcpu=cortex-a9 -mthumb test.c
arm-none-eabi-objdump -d a.out
git rebase => http://codepad.org/hehastWp
Harvard vs Von Nuemann Architecture
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka11516.html
http://www.pictutorials.com/Harvard_vs_Von_Nuemann_Architecture.htm
http://embeddedbasics.wordpress.com/2009/12/18/von_neumann_architecture_vs_harvard_architecture/
http://89c51.blogspot.tw/2007/11/von-neumann-architecture-and-harvard.html
Harvard architecture impossible to self-modified code (data:RW, code:RO)
ijsung: 不過現在的harvard architecture只是說指令跟資料有各自的L1 cache,出了L1之後還是共用的。要self-modified code是可行的,只是要flush L1 caches
好比說ARM7是Princeton arch, 到了ARM9是Harvard arch, 但是仍然可以self-modify只是多了一步flush L1 I/D cache
way Harvard arch 適合 DSP =>資料大小的關係
ijsung:
因為同一個clock cycle內可以同時從instruction cache跟data cache各抓出指令跟資料
DSP的working set通常遠大於register file能裝的大小,所以能夠每個clock cycle都能從data memory抓東西進來的harvard arch樂勝。
大部分的DSP都有玄妙的指令集可以在同一個cycle內1)抓下個指令所需的資料 2)用上個週期抓進來的資料計算
若是Princeton arch的話這是不可能的。要抓data的話instruction fetch就得暫停。
http://sestevenson.wordpress.com/2009/10/01/implementation-of-fir-filtering-in-c-part-1/
qemu-devel mailling list archive
http://lists.gnu.org/archive/html/qemu-devel/
大概猜出 make 失敗的原因,cpu_register_* 這組 API 好像有被換過了
docs/memory 裏面有寫
MMIO Operations
---------------
MMIO regions are provided with ->read() and ->write() callbacks; in addition
various constraints can be supplied to control how these callbacks are called:
- .valid.min_access_size, .valid.max_access_size define the access sizes
(in bytes) which the device accepts; accesses outside this range will
have device and bus specific behaviour (ignored, or machine check)
- .valid.aligned specifies that the device only accepts naturally aligned
accesses. Unaligned accesses invoke device and bus specific behaviour.
- .impl.min_access_size, .impl.max_access_size define the access sizes
(in bytes) supported by the *implementation*; other access sizes will be
emulated using the ones available. For example a 4-byte write will be
emulated using four 1-byte writes, if .impl.max_access_size = 1.
- .impl.valid specifies that the *implementation* only supports unaligned
accesses; unaligned accesses will be emulated by two aligned accesses.
- .old_portio and .old_mmio can be used to ease porting from code using
cpu_register_io_memory() and register_ioport(). They should not be used
in new code.
git blame -L 160,170 docs/memory.txt 看一下,應該是這個 commit 有動到(? 明天研究
9d3a4736 (Avi Kivity
2011-07-26 14:26:00 +0300 170 差不多是去年這個時候 lol
7/26 早上跟 jserv 整理了一下大概有動到的東西
SysBusDevieceInfo
memory regi
cpu_register_io_memory
qdev_init_chardev
macro
目前 led / button 好像修好了,來嘗試 GPIO 的 porting
qemu/docs/tracing.txts
http://www.pcmech.com/forum/computer-hardware/153070-guide-dual-core-smp.html
L2 cache, SMP dual core
Symmetric Multi-Processing (SMP)
mmio
interrupt VS trap system call
I2C / I2S
============================================
8/7 update
gdb
run <參數> # run the program
bt # backtrace
c # continue
list
# read a elf file
readelf -a main_qemu.elf | less
# dynamic link program needs a interpreter
/lib/ld-linux.so.2 # interpreter
# 飛上天的方法 (平行化處理 make)
make -j2
# 思考
can dynamic linker run alone?
# 蹦床,很多關於 stack 的操過跟這個有關
http://en.wikipedia.org/wiki/Trampoline_(computing)
.eh_frame_hdr
# 本周要完成的進度
修好 UI
refactoring
產生 format-patch
# 相關的 git commands
git git format-patch -1
git am 0001-try-to-fix-core-dump.patch -s
git stash
git rebase
git blame
git apply
============================================
8/8 update
今日主要修改,猜出(?) momory region 需要的大小
hw/stm32.c 最上面
#define GPIO_A 0 //0x4002 0000 - 0x4002 03FF
#define GPIO_B 1 //0x4002 0400 - 0x4002 07FF
#define GPIO_C 2 //0x4002 0800 - 0x4002 0BFF
#define GPIO_D 3 //0x4002 0C00 - 0x4002 0FFF
#define GPIO_E 4 //0x4002 1000 - 0x4002 13FF
#define GPIO_H 5 //0x4002 1400 - 0x4002 17FF
就猜他應該會用 0x17FF 這麼多,於是把 hw/stm32_gpio.c 裏面上次卡關的 size 換掉
memory_region_init_io(&s->iomem, &gpio_ops, s, "gpio", 0x17FF);
另外 LED 也找出來應該是用錯 API 了
- s->chr = qemu_char_get_next_serial();
+ s->chr = qemu_chr_find(id);
換掉後就成功跟 UI 連結了,看到燈在閃的那瞬間感動的快哭出來了 QQ
順手重購了一下,法國人寫的 code 有點亂 :3
至於 assert 造成 core dump 的原因還要再找找
============================================
8/10 update
實在是太開心了
這兩天自己研究了很久還是沒想出解法,gdb 挖了半天沒有想法
去找了一些相關於 stellaris 的 mailing list,也是很多人有遇到相關的議題
http://lists.gnu.org/archive/html/qemu-devel/2012-07/msg03040.html
https://bugs.launchpad.net/qemu/+bug/1028260
最後找到這個 patch
http://patchwork.ozlabs.org/patch/172820/
apply 後好像就能動了,耶~
============================================
8/15 update
=======================================
8/20 update
把我的 code 放上 github: https://github.com/xatier/qemu
以後改完 code 要先XD
git push qemu-github summer-work
另外 rebase origin 要記得先 pull 下來... merge,不然會失敗XD
暑假前應該這篇文章會一直更新(?)
============================================
首先準備 tool chains
到這裡去找 arm-none-eabi 的工具
http://www.mentor.com/embedded-software/sourcery-tools/sourcery-codebench/editions/lite-edition/request?id=e023fac2-e611-476b-a702-90eabb2aeca8&returnURL=https%3A%2F%2Fsourcery%2Ementor%2Ecom%2FGNUToolchain%2Frelease830%3Flite%3Darm%26cmpid%3D7108%26downloadlite%3Dscblite2012&downloadlite=scblite2012&fmpath=/embedded-software/sourcery-tools/sourcery-codebench/editions/lite-edition/form
很該死的註冊完後應該可以抓到 arm-2012.03-56-arm-none-eabi-i686-pc-linux-gnu.tar.bz2
解壓後放在一個跟 project 相關的資料夾之後把路徑加到現在的 bash shell 上
export PATH=$PATH:/home/xatierlike/stlink/arm-2012.03/bin
然後到 github.com 上面去把 texane/stlink clone 下來
git clone https://github.com/texane/stlink.git
然後想辦法去找個可以玩耍的 demo code 下來...
昨天跟 jserv 找可以用的 code 找到快哭了QQ 幾乎沒一個能用的 OTZ
最後找到這邊去把他的 blinky.zip 弄下來
http://gostm32.blogspot.tw/2010/09/blinky-ii.html
這裡還需要用 vim 改一下 Makefile,%s/elf/none-eabi/g
原本的 blinky 是用 arm-elf-* tools 工作的,而我用的是 arm-none-eabi-* tools
會後把 make 出來的 blinky.bin 燒進去 STM32 的 flash 就可以囉
./st-flash write ../blinky/blinky.bin 0x8000000
./st-util 搭配 gdb target remote 可以拿來 debug ,不過我還沒玩熟
============================================
又研究了一下下,成功用 gdb 跟小板子玩耍了 XD
vim Makefile
CFLAGS = -I./ -c -fno-common -Os -mcpu=cortex-m3 -mthumb -g
打開 compiler 的 debug flag
make clean; make
重新燒進去
./st-flash write ../blinky/blinky.bin 0x8000000
聽一下 :4242 port
./st-util
arm-none-eabi-gdb blinky.none-eabi
可以開始想辦法看懂 code 惹QQ
============================================又研究了一下下,成功用 gdb 跟小板子玩耍了 XD
vim Makefile
CFLAGS = -I./ -c -fno-common -Os -mcpu=cortex-m3 -mthumb -g
打開 compiler 的 debug flag
make clean; make
重新燒進去
./st-flash write ../blinky/blinky.bin 0x8000000
聽一下 :4242 port
./st-util
arm-none-eabi-gdb blinky.none-eabi
(gdb) target remote :4242 Remote debugging using :4242 main () at blinky.c:37 37 RCC->APB2ENR |= 0x10 | 0x04; /* Enable the GPIOA (bit 2) and GPIOC (bit 8) */ (gdb) n 33 int main(void){ (gdb) n 37 RCC->APB2ENR |= 0x10 | 0x04; /* Enable the GPIOA (bit 2) and GPIOC (bit 8) */ (gdb) list 32 33 int main(void){ 34 int n = 0; 35 int button; 36 37 RCC->APB2ENR |= 0x10 | 0x04; /* Enable the GPIOA (bit 2) and GPIOC (bit 8) */ 38 GPIOC->CRH = 0x11; /* Set GPIOC Pin 8 and Pin 9 to outputs */ 39 GPIOA->CRL = 0x04; /* Set GPIOA Pin 0 to input floating */ 40 41 while(1) (gdb)
可以開始想辦法看懂 code 惹QQ
今天晚上跟 jserv 研究他那邊弄過來的 qemu code
不知道為什麼我這邊就是跑不起來 ><
於是先去吃宵夜了XD
吃完宵夜後回來改 code 把中間改掉... 神奇的可以動了
serversocket.bind((socket.gethostname(), port)) serversocket.bind(("localhost", port))
但是當下我不知道為什麼,明明 socket.gethostname 得到的也是我機器的 hostname ...
根據 http://docs.python.org/library/socket.html#socket.gethostname
Return a string containing the hostname of the machine where the Python interpreter is currently executing.
我在我本機工作, gethostname 要到的理論上是跟在 shell 上打 hostname 一樣的結果
後來 方括號拉拉學長 提出了令我念頭一轉的問題點
問題是你hostname如果和我一樣在/etc/hosts查不到,你就不能直接用"localhost"去bind, 要用127.0.0.1
我馬上 ...
cat /etc/hosts 127.0.0.1 localhost 127.0.1.1 xatierlike-NB
幹~~~~~~ 單純我 /etc/hosts 不知道哪時候被我腦殘動到 OTZ
============================================
原本聽 jserv 的去找 github 上面的 Qemu git
不斷的 make 失敗...
結果後來才發現東西是太舊的..囧
真。Qemu git
http://git.qemu.org/qemu.git
arm instruction
it instruction, condition (cbz / cnbz)
============================================
basic computer organization
http://goo.gl/jW6A0
Intro to Git for the Perl Hacker
http://marklodato.github.com/visual-git-guide/index-en.html
git labs
http://gitimmersion-apputu.rhcloud.com/
http://gitimmersion-apputu.rhcloud.com/lab_42.html
arn instructions
http://simplemachines.it/doc/arm_inst.pdf
arm-none-eabi-gcc -static -fno-common -Os -mcpu=cortex-a9 -mthumb test.c
arm-none-eabi-objdump -d a.out
git rebase => http://codepad.org/hehastWp
2252 git diff 2253 cd .. 2254 ls 2255 git diff 2256 git diff > p.diff 2257 git reset --hard HEAD 2258 git log 2259 git branch 2260 git branch summer-work 2261 git checkout summer-work 2262 tig 2263 sudo apt-get install tig 2264 tig 2265 git apply p.diff 2266 git diff 2267 git commit -a 2268 export EDITOR=vim 2269 git commit -a 2270 git commit --amend 2271 vi README 2272 git add README 2273 git commit --amend 2274 tig 2275 git format-patch -1 2276 vi 0001-Attempt-to-build-STM32-related-files.patch 2277 git rebase --help 2278 git branch -r 2279 git fetch origin 2280 tig 2281 git log 2282 git log origin/master 2283 git rebase origin/master 2284 tig 2285 git checkout master 2286 git pull
Harvard vs Von Nuemann Architecture
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka11516.html
http://www.pictutorials.com/Harvard_vs_Von_Nuemann_Architecture.htm
http://embeddedbasics.wordpress.com/2009/12/18/von_neumann_architecture_vs_harvard_architecture/
http://89c51.blogspot.tw/2007/11/von-neumann-architecture-and-harvard.html
Harvard architecture impossible to self-modified code (data:RW, code:RO)
ijsung: 不過現在的harvard architecture只是說指令跟資料有各自的L1 cache,出了L1之後還是共用的。要self-modified code是可行的,只是要flush L1 caches
好比說ARM7是Princeton arch, 到了ARM9是Harvard arch, 但是仍然可以self-modify只是多了一步flush L1 I/D cache
way Harvard arch 適合 DSP =>資料大小的關係
ijsung:
因為同一個clock cycle內可以同時從instruction cache跟data cache各抓出指令跟資料
DSP的working set通常遠大於register file能裝的大小,所以能夠每個clock cycle都能從data memory抓東西進來的harvard arch樂勝。
大部分的DSP都有玄妙的指令集可以在同一個cycle內1)抓下個指令所需的資料 2)用上個週期抓進來的資料計算
若是Princeton arch的話這是不可能的。要抓data的話instruction fetch就得暫停。
http://sestevenson.wordpress.com/2009/10/01/implementation-of-fir-filtering-in-c-part-1/
qemu-devel mailling list archive
http://lists.gnu.org/archive/html/qemu-devel/
大概猜出 make 失敗的原因,cpu_register_* 這組 API 好像有被換過了
docs/memory 裏面有寫
MMIO Operations
---------------
MMIO regions are provided with ->read() and ->write() callbacks; in addition
various constraints can be supplied to control how these callbacks are called:
- .valid.min_access_size, .valid.max_access_size define the access sizes
(in bytes) which the device accepts; accesses outside this range will
have device and bus specific behaviour (ignored, or machine check)
- .valid.aligned specifies that the device only accepts naturally aligned
accesses. Unaligned accesses invoke device and bus specific behaviour.
- .impl.min_access_size, .impl.max_access_size define the access sizes
(in bytes) supported by the *implementation*; other access sizes will be
emulated using the ones available. For example a 4-byte write will be
emulated using four 1-byte writes, if .impl.max_access_size = 1.
- .impl.valid specifies that the *implementation* only supports unaligned
accesses; unaligned accesses will be emulated by two aligned accesses.
- .old_portio and .old_mmio can be used to ease porting from code using
cpu_register_io_memory() and register_ioport(). They should not be used
in new code.
git blame -L 160,170 docs/memory.txt 看一下,應該是這個 commit 有動到(? 明天研究
9d3a4736 (Avi Kivity
2011-07-26 14:26:00 +0300 170 差不多是去年這個時候 lol
7/26 早上跟 jserv 整理了一下大概有動到的東西
SysBusDevieceInfo
memory regi
cpu_register_io_memory
qdev_init_chardev
macro
目前 led / button 好像修好了,來嘗試 GPIO 的 porting
qemu/docs/tracing.txts
http://www.pcmech.com/forum/computer-hardware/153070-guide-dual-core-smp.html
L2 cache, SMP dual core
Symmetric Multi-Processing (SMP)
mmio
interrupt VS trap system call
I2C / I2S
============================================
8/7 update
gdb
run <參數> # run the program
bt # backtrace
c # continue
list
# read a elf file
readelf -a main_qemu.elf | less
# dynamic link program needs a interpreter
/lib/ld-linux.so.2 # interpreter
# 飛上天的方法 (平行化處理 make)
make -j2
# 思考
can dynamic linker run alone?
# 蹦床,很多關於 stack 的操過跟這個有關
http://en.wikipedia.org/wiki/Trampoline_(computing)
.eh_frame_hdr
# 本周要完成的進度
修好 UI
refactoring
產生 format-patch
# 相關的 git commands
git git format-patch -1
git am 0001-try-to-fix-core-dump.patch -s
git stash
git rebase
git blame
git apply
============================================
8/8 update
今日主要修改,猜出(?) momory region 需要的大小
hw/stm32.c 最上面
#define GPIO_A 0 //0x4002 0000 - 0x4002 03FF
#define GPIO_B 1 //0x4002 0400 - 0x4002 07FF
#define GPIO_C 2 //0x4002 0800 - 0x4002 0BFF
#define GPIO_D 3 //0x4002 0C00 - 0x4002 0FFF
#define GPIO_E 4 //0x4002 1000 - 0x4002 13FF
#define GPIO_H 5 //0x4002 1400 - 0x4002 17FF
就猜他應該會用 0x17FF 這麼多,於是把 hw/stm32_gpio.c 裏面上次卡關的 size 換掉
memory_region_init_io(&s->iomem, &gpio_ops, s, "gpio", 0x17FF);
另外 LED 也找出來應該是用錯 API 了
- s->chr = qemu_char_get_next_serial();
+ s->chr = qemu_chr_find(id);
換掉後就成功跟 UI 連結了,看到燈在閃的那瞬間感動的快哭出來了 QQ
順手重購了一下,法國人寫的 code 有點亂 :3
至於 assert 造成 core dump 的原因還要再找找
============================================
8/10 update
實在是太開心了
這兩天自己研究了很久還是沒想出解法,gdb 挖了半天沒有想法
去找了一些相關於 stellaris 的 mailing list,也是很多人有遇到相關的議題
http://lists.gnu.org/archive/html/qemu-devel/2012-07/msg03040.html
https://bugs.launchpad.net/qemu/+bug/1028260
最後找到這個 patch
http://patchwork.ozlabs.org/patch/172820/
apply 後好像就能動了,耶~
============================================
8/15 update
整理完 code,fetch 一下 master
順便 fetch 一下 qemu 的 master 打算來製作 format patch
上次那個找到的 fix coredump 的 patch 在昨天下午有被到 master
感謝 Anthony Liguori <aliguori@us.ibm.com> !
我嘗試 rebase 後就 Makefile 噴衝突了,感覺像是有人把架構又切開了
(這部份還要追 log)
手動 merge (不知道有沒有出問題XD)
目前先另外開一個 branch 製作 patch
底下是我用 git format-patch -2 生出來的 patch
From 808d1135a501fe0c524c7572fd82ca904d1d5900 Mon Sep 17 00:00:00 2001 From: xatier <xatierlike@gmail.com> Date: Tue, 14 Aug 2012 14:37:46 +0800 Subject: [PATCH 1/2] try to support stm32l152rbt6 board --- hw/arm/Makefile.objs | 1 + hw/stm32.c | 189 ++++++++++++++++++++++++++++ hw/stm32_gpio.c | 331 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 521 insertions(+) create mode 100644 hw/stm32.c create mode 100644 hw/stm32_gpio.c diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 2b39fb3..15aff03 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -9,6 +9,7 @@ obj-y += exynos4210_pmu.o exynos4210_mct.o exynos4210_fimd.o obj-y += exynos4210_rtc.o exynos4210_i2c.o obj-y += arm_mptimer.o a15mpcore.o obj-y += armv7m.o armv7m_nvic.o stellaris.o stellaris_enet.o +obj-y += stm32.o stm32_gpio.o obj-y += highbank.o obj-y += pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o obj-y += pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o diff --git a/hw/stm32.c b/hw/stm32.c new file mode 100644 index 0000000..a57d384 --- /dev/null +++ b/hw/stm32.c @@ -0,0 +1,189 @@ + +#include "sysbus.h" +#include "exec-memory.h" +#include "arm-misc.h" +#include "boards.h" +#include "devices.h" + +#define NB_NVIC_IRQ 5 +#define NB_GPIO 6 + +#define GPIO_A 0 // 0x4002 0000 - 0x4002 03FF +#define GPIO_B 1 // 0x4002 0400 - 0x4002 07FF +#define GPIO_C 2 // 0x4002 0800 - 0x4002 0BFF +#define GPIO_D 3 // 0x4002 0C00 - 0x4002 0FFF +#define GPIO_E 4 // 0x4002 1000 - 0x4002 13FF +#define GPIO_H 5 // 0x4002 1400 - 0x4002 17FF + +typedef const struct { + const char *name; + uint16_t f_size; +} stm32_board_info; + + + +static stm32_board_info stm32_board = { + "stm32l152rbt6", + 0x0080, // 128kb flash +}; + + + +typedef struct { + uint32_t int_status; + uint32_t int_mask; + MemoryRegion iomem; + qemu_irq irq; + stm32_board_info* board; +} ssys_state; + + + +static void ssys_reset(void *opaque) { + // unimplemtmented +} + + + +static uint64_t ssys_read(void *opaque, target_phys_addr_t offset, + unsigned size) +{ + // nothing to do + return 0; +} + + + +static void ssys_write(void *opaque, target_phys_addr_t offset, uint64_t value, + unsigned size) +{ + // unimplemtmented +} + + + +static const MemoryRegionOps ssys_ops = { + .read = ssys_read, + .write = ssys_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + + + +static int stm32_sys_post_load(void *opaque, int version_id) +{ + //Nothing to do + return 0; +} + + + +static const VMStateDescription vmstate_stm32_sys = { + .name = "stm32_sys", + .version_id = 2, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .post_load = stm32_sys_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINT32(int_mask, ssys_state), + VMSTATE_UINT32(int_status, ssys_state), + VMSTATE_END_OF_LIST() + } +}; + + + +static int stm32l_sys_init(uint32_t base, qemu_irq irq, + stm32_board_info * board) +{ + ssys_state *s; + + s = (ssys_state *)g_malloc0(sizeof(ssys_state)); + s->irq = irq; + s->board = board; + + memory_region_init_io(&s->iomem, &ssys_ops, s, "ssys", 0x00010000); + memory_region_add_subregion(get_system_memory(), base, &s->iomem); + + ssys_reset(s); + vmstate_register(NULL, -1, &vmstate_stm32_sys, s); + + return 0; +} + + + +static void stm32l152rbt6_init(ram_addr_t ram_size, const char *boot_device, + const char *kernel_filename, const char *kernel_cmdline, + const char *initrd_filename, const char *cpu_model) +{ + + // prepare the memory + MemoryRegion *address_space_mem = get_system_memory(); + uint16_t flash_size = stm32_board.f_size; // 128KBits + uint16_t sram_size = 0x0010; // 16 KBits + + + // initial the processor (+ memory) + qemu_irq* pic = armv7m_init(address_space_mem, flash_size, sram_size, + kernel_filename, cpu_model); + stm32l_sys_init(0x1FF00000, pic[28], &stm32_board); + + // structures GPIO + static const uint32_t gpio_addr[NB_GPIO] = { + 0x40020000, // GPIO_A + 0x40020400, // GPIO_B + 0x40020800, // GPIO_C + 0x40020C00, // GPIO_D + 0x40021000, // GPIO_E + 0x40021400 // GPIO_H + }; + + DeviceState* gpio_dev[NB_GPIO]; + + //create the botton + DeviceState* button = sysbus_create_simple("stm32_button", -1, NULL); + + //create the LEDs + DeviceState* led_dev6 = sysbus_create_simple("stm32_led_blue" , -1, NULL); + DeviceState* led_dev7 = sysbus_create_simple("stm32_led_green", -1, NULL); + + + //initial GPIO_A + gpio_dev[GPIO_A] = sysbus_create_varargs("stm32_gpio_A", gpio_addr[GPIO_A], + NULL); + qemu_irq entreeBouton = qdev_get_gpio_in(gpio_dev[GPIO_A], 1); + + qdev_connect_gpio_out(button, 0, entreeBouton); + + //initial GPIO_B + gpio_dev[GPIO_B] = sysbus_create_varargs("stm32_gpio_B", gpio_addr[GPIO_B], + NULL); + + qemu_irq entreeLED6 = qdev_get_gpio_in(led_dev6, 0); + qdev_connect_gpio_out(gpio_dev[GPIO_B], 6, entreeLED6); + qemu_irq entreeLED7 = qdev_get_gpio_in(led_dev7, 0); + qdev_connect_gpio_out(gpio_dev[GPIO_B], 7, entreeLED7); + +} + +static QEMUMachine stm32l152rbt6_machine = { + .name = "stm32l152rbt6", + .desc = "STM32L Discovery", + .init = stm32l152rbt6_init, + // user manual page 105 + // STM32 = ARM-based 32-bit microcontroller + // L = Low power + // 152: Devices with LCD + // R = 64 pins + // B = 128 Kbytes of Flash memory + // T = LQFP + // 6 = Industrial temperature range, –40 to 85 °C +}; + +static void stm32l_machine_init(void) { + qemu_register_machine(&stm32l152rbt6_machine); +} + +machine_init(stm32l_machine_init); + diff --git a/hw/stm32_gpio.c b/hw/stm32_gpio.c new file mode 100644 index 0000000..0ac3535 --- /dev/null +++ b/hw/stm32_gpio.c @@ -0,0 +1,331 @@ +#include "sysbus.h" +#include "exec-memory.h" + +#define NB_PIN 64 + +typedef struct { + SysBusDevice busdev; + + /* Registres GPIO (Reference Manual p119 */ + uint32_t mode; /* Mode */ + uint16_t otype; /* Output type */ + uint32_t ospeed; /* Output speed */ + uint32_t pupd; /* Pull-up/Pull-down */ + uint16_t ind; /* Input data */ + uint16_t outd; /* Output data register */ + uint16_t outd_old; /* Output data register */ + uint32_t bsr; /* Bit set/reset */ + uint32_t lck; /* Lock */ + uint32_t afrl; /* Alternate function low */ + uint32_t afrh; /* Alternate function high */ + + qemu_irq irq_out[NB_PIN]; + unsigned char id; + MemoryRegion iomem; +} stm32_gpio_state; + + +static const VMStateDescription vmstate_stm32_gpio = { + .name = "stm32_gpio", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) + { + VMSTATE_UINT32(mode, stm32_gpio_state), + VMSTATE_UINT16(otype, stm32_gpio_state), + VMSTATE_UINT32(ospeed, stm32_gpio_state), + VMSTATE_UINT32(pupd, stm32_gpio_state), + VMSTATE_UINT16(ind, stm32_gpio_state), + VMSTATE_UINT16(outd, stm32_gpio_state), + VMSTATE_UINT16(outd_old, stm32_gpio_state), + VMSTATE_UINT32(bsr, stm32_gpio_state), + VMSTATE_UINT32(lck, stm32_gpio_state), + VMSTATE_UINT32(afrl, stm32_gpio_state), + VMSTATE_UINT32(afrh, stm32_gpio_state), + VMSTATE_END_OF_LIST() + } +}; + + +static void stm32_gpio_update(stm32_gpio_state *s) +{ + uint16_t changed; + uint16_t mask; + int i; + + changed = s->outd_old ^ s->outd; //XOR: Tous les bits à 1 seront les bits changés + if (!changed) + return; + + s->outd_old = s->outd; + for (i = 0; i < 8; i++) { + mask = 1 << i; + if (changed & mask) { + //Conditions de changement + //--Mode register != 00 + uint32_t modeMask = (1 << (i*2)) | (1 << ((i*2) + 1)); + if((s->mode & modeMask) != 0) { + // send an IRQ to the device connected to the GPIO pin + //FIXME: the transmition to the pin is direct when it should occur at the next tick of the RCC + qemu_set_irq(s->irq_out[i], (s->outd & mask) != 0); + } + } + } +} + + +static uint64_t stm32_gpio_read(void *opaque, target_phys_addr_t offset, unsigned size) +{ + stm32_gpio_state *s = (stm32_gpio_state *) opaque; + + switch (offset) { + case 0x00: /* Mode */ + return s->mode; + case 0x04: /* oType */ + return s->otype; + case 0x08: /* oSpeed */ + return s->ospeed; + case 0x0C: /* Pull-up / Pull-down */ + return s->pupd; + case 0x10: /* Input data register */ + return s->ind; + case 0x14: /* Output data */ + return s->outd; + case 0x18: /* BSR */ + return 0x0; //Write only + case 0x1C: /* lock */ + return 0x0; //Non implémenté + case 0x20: /* AFRL */ + return s->afrl; + case 0x24: /* AFRH */ + return s->afrh; + default: + hw_error("stm32_gpio_read: Bad offset %x\n", (int) offset); + return 0; + } +} + + +static void stm32_gpio_write(void *opaque, target_phys_addr_t offset, + uint64_t value, unsigned size) +{ + stm32_gpio_state *s = (stm32_gpio_state *) opaque; + int i; + uint16_t low = (uint16_t)value; + uint16_t high = (uint16_t)value >> 16; + + switch (offset) { + case 0x00: /* Mode */ + s->mode = value; + break; + case 0x04: /* oType */ + s->otype = value; + break; + case 0x08: /* oSpeed */ + s->ospeed = value; + break; + case 0x0C: /* Pull-up / Pull-down */ + s->pupd = value; + break; + case 0x10: /* Input data register */ + //Read only + break; + case 0x14: /* Output data */ + s->outd = value; + stm32_gpio_update(s); + break; + + case 0x18: /* BSR */ + //set = low + //reset = high + for(i=0; i<16; i++) { + int mask = 1 << i; + if((high & mask) != 0) { //Si bit reset[i] + s->outd &= ~(1 << i); //Mise à 0 + } + if((low & mask) != 0) { //Si bit reset[i] + s->outd |= (1 << i); //Mise à 1 + } + } + stm32_gpio_update(s); + break; + + case 0x1C: /* lock */ + //FIXME: Non implémenté + break; + case 0x20: /* AFRL */ + s->afrl = value; + break; + case 0x24: /* AFRH */ + s->afrh = value; + break; + default: + hw_error("stm32_gpio_write: Bad offset %x\n", (int) offset); + } +} + + + +static void stm32_gpio_reset(stm32_gpio_state *s) +{ + switch (s->id) { + case 'A': + s->mode = 0xA8000000; + s->pupd = 0x64000000; + s->ospeed = 0x00000000; + break; + case 'B': + s->mode = 0x00000280; + s->pupd = 0x00000100; + s->ospeed = 0x000000C0; + break; + default: + s->mode = 0x00000000; + s->pupd = 0x00000000; + s->ospeed = 0x00000000; + } + + //Valeur commune + s->ind = 0x00000000; + s->otype = 0x00000000; + s->outd = 0x00000000; + s->outd_old = s->outd; + s->bsr = 0x00000000; + s->lck = 0x00000000; + s->afrh = 0x00000000; + s->afrl = 0x00000000; + +} + +/* + * Appelé quand une entrée de GPIO reçois une IT + * called when an input GPIO receive an IT + */ +static void stm32_gpio_in_recv(void * opaque, int numPin, int level) +{ + assert(numPin>=0 && numPin<NB_PIN); + stm32_gpio_state *s = (stm32_gpio_state *) opaque; + + + uint32_t mask = (1 << (numPin*2)) | (1 << ((numPin*2) + 1)); + //check if the pin is confihured as input + //--Pull-up Pull-Down -> must be different trom 00 + if((s->pupd & mask) == 0) {return;} + //--Mode register -> 00 + if((s->mode & mask) != 0) {return;} + + //Writing to the register input data register + printf("GPIO_in[%d]->%d\n", numPin, level); + if(level) { + s->ind |= (1 << numPin); // last => 1 + } else { + s->ind &= ~(1 << numPin); //Mise à 0 + } +} + + + +static const MemoryRegionOps gpio_ops = { + .read = stm32_gpio_read, + .write = stm32_gpio_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + + + +static int stm32_gpio_init(SysBusDevice *dev, const unsigned char id) +{ + stm32_gpio_state *s = FROM_SYSBUS(stm32_gpio_state, dev); + s->id = id; + + // initialisation of the memory range + memory_region_init_io(&s->iomem, &gpio_ops, s, "gpio", 0x17FF); + sysbus_init_mmio(dev, &s->iomem); + + // initial the pins + qdev_init_gpio_in(&dev->qdev, stm32_gpio_in_recv, NB_PIN); + qdev_init_gpio_out(&dev->qdev, s->irq_out, NB_PIN); + + stm32_gpio_reset(s); + vmstate_register(&dev->qdev, -1, &vmstate_stm32_gpio, s); + + return 0; +} + + + +static int stm32_gpio_init_A(SysBusDevice *dev) +{ + return stm32_gpio_init(dev, 'A'); +} + + + +static int stm32_gpio_init_B(SysBusDevice *dev) +{ + return stm32_gpio_init(dev, 'B'); +} + + + +static Property stm32_gpio_sysbus_properties[] = { + //XXX: DEFINE_PROP_CHR("chardev", NULL, chr), + DEFINE_PROP_END_OF_LIST(), +}; + + + +static void stm32_gpio_class_init_A (ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = stm32_gpio_init_A; + dc->desc = "STM32 GPIO A"; + dc->vmsd = &vmstate_stm32_gpio; + dc->props = stm32_gpio_sysbus_properties; + +} + + + +static void stm32_gpio_class_init_B (ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = stm32_gpio_init_B; + dc->desc = "STM32 GPIO B"; + dc->vmsd = &vmstate_stm32_gpio; + dc->props = stm32_gpio_sysbus_properties; + +} + + + +static TypeInfo stm32_gpioA_info = { + .name = "stm32_gpio_A", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof (stm32_gpio_state), + .class_init = stm32_gpio_class_init_A, +}; + + + +static TypeInfo stm32_gpioB_info = { + .name = "stm32_gpio_B", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof (stm32_gpio_state), + .class_init = stm32_gpio_class_init_B, +}; + + + +static void stm32_gpio_register_devices(void) { + type_register_static(&stm32_gpioA_info); + type_register_static(&stm32_gpioB_info); +} + + + +type_init(stm32_gpio_register_devices) -- 1.7.9.5
From 59ec269e532d85be4af08ab993ecf748513f4311 Mon Sep 17 00:00:00 2001 From: xatier <xatierlike@gmail.com> Date: Tue, 14 Aug 2012 14:53:20 +0800 Subject: [PATCH 2/2] add button and leds for stm32 --- hw/arm/Makefile.objs | 2 +- hw/stm32_button.c | 125 ++++++++++++++++++++++++++++++++++++++++++ hw/stm32_led.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 hw/stm32_button.c create mode 100644 hw/stm32_led.c diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 15aff03..58f2894 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -9,7 +9,7 @@ obj-y += exynos4210_pmu.o exynos4210_mct.o exynos4210_fimd.o obj-y += exynos4210_rtc.o exynos4210_i2c.o obj-y += arm_mptimer.o a15mpcore.o obj-y += armv7m.o armv7m_nvic.o stellaris.o stellaris_enet.o -obj-y += stm32.o stm32_gpio.o +obj-y += stm32.o stm32_gpio.o stm32_button.o stm32_led.o obj-y += highbank.o obj-y += pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o obj-y += pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o diff --git a/hw/stm32_button.c b/hw/stm32_button.c new file mode 100644 index 0000000..33df31b --- /dev/null +++ b/hw/stm32_button.c @@ -0,0 +1,125 @@ + +#include "sysbus.h" + +typedef struct { + SysBusDevice busdev; + uint8_t buttonState; + qemu_irq gpio_out; + CharDriverState* chr; + const char *id; +} stm32_button_state; + + + +static const VMStateDescription vmstate_stm32_button = { + .name = "stm32_button", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) + { + VMSTATE_UINT8(buttonState, stm32_button_state), + VMSTATE_END_OF_LIST() + } +}; + + + +static void stm32_button_reset(stm32_button_state *s) +{ + s->buttonState = 0; +} + + + +static int stm32_can_receive(void *opaque) { return 1; } // always return 1 + + + +static void stm32_receive(void *opaque, const uint8_t* buf, int size) +{ + + stm32_button_state *s = (stm32_button_state *) opaque; + + int i = 0; + for(i = 0; i < size; i++) { + //Leve une IRQ + uint8_t etat = buf[i]; + s->buttonState = etat; + printf("the BUTTON change state->%d\n", (int)etat); + qemu_set_irq(s->gpio_out, (int)etat); + } +} + + + +static void stm32_event(void *opaque, int event) { } // NOT USED + + + +static int stm32_button_init(SysBusDevice *dev, const char* id) +{ + stm32_button_state *s = FROM_SYSBUS(stm32_button_state, dev); + + // initial the output pins + qdev_init_gpio_out(&dev->qdev, &s->gpio_out, 1); + + // inital the char dev + s->chr = qemu_char_get_next_serial(); + s->id = id; + + if (s->chr) { + qemu_chr_add_handlers(s->chr, stm32_can_receive, stm32_receive, stm32_event, s); + } + + stm32_button_reset(s); + vmstate_register(&dev->qdev, -1, &vmstate_stm32_button, s); + + return 0; +} + + + +static int stm32_button_init_(SysBusDevice *dev) +{ + return stm32_button_init(dev, "user0"); +} + + + +static Property stm32_button_sysbus_properties[] = { + //XXX: DEFINE_PROP_CHR("chardev", NULL, chr), + DEFINE_PROP_END_OF_LIST(), +}; + + + +static void stm32_button_class_init (ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = stm32_button_init_; + dc->desc = "STM32 Button"; + dc->vmsd = &vmstate_stm32_button; + dc->props = stm32_button_sysbus_properties; + +} + + + +static TypeInfo stm32_button_info = { + .name = "stm32_button", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof (stm32_button_state), + .class_init = stm32_button_class_init, +}; + + + +static void stm32_button_register_devices(void) { + type_register_static(&stm32_button_info); +} + + + +type_init(stm32_button_register_devices) diff --git a/hw/stm32_led.c b/hw/stm32_led.c new file mode 100644 index 0000000..51f87e7 --- /dev/null +++ b/hw/stm32_led.c @@ -0,0 +1,148 @@ + +#include "sysbus.h" + +typedef struct { + SysBusDevice busdev; + uint8_t ledState; + CharDriverState *chr; + const char *id; +} stm32_led_state; + + + +static const VMStateDescription vmstate_stm32_led = { + .name = "stm32_led", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) + { + VMSTATE_UINT8(ledState, stm32_led_state), + VMSTATE_END_OF_LIST() + } +}; + + + +static void stm32_led_reset(stm32_led_state *s) +{ + s->ledState = 0; +} + +/* + * Appelé quand une entrée de led reçoit une IT + */ +static void stm32_led_recvirq(void * opaque, int numPin, int level) +{ + // the LED change state + printf("The LED change state->%d\n", level); + stm32_led_state *s = (stm32_led_state *) opaque; + + if(s->chr) { + uint8_t buffer = (uint8_t)level; + qemu_chr_fe_write(s->chr, &buffer, 1); + } +} + + + +static int stm32_led_init(SysBusDevice *dev, const char* id) +{ + stm32_led_state *s = FROM_SYSBUS(stm32_led_state, dev); + + + // debug message + // printf("%p, %d\n", &dev->qdev, dev->qdev.num_gpio_out); + + // initial the output pins + qdev_init_gpio_in(&dev->qdev, stm32_led_recvirq, 1); + + // initial the char device + s->chr = qemu_chr_find(id); + s->id = id; + + stm32_led_reset(s); + vmstate_register(&dev->qdev, -1, &vmstate_stm32_led, s); + + return 0; +} + + + +static int stm32_led_init_Blue(SysBusDevice *dev) +{ + return stm32_led_init(dev, "led_blue"); +} + + + +static int stm32_led_init_Green(SysBusDevice *dev) +{ + return stm32_led_init(dev, "led_green"); +} + + + +static Property stm32_led_blue_sysbus_properties[] = { + DEFINE_PROP_END_OF_LIST(), +}; + + + +static Property stm32_led_green_sysbus_properties[] = { + DEFINE_PROP_END_OF_LIST(), +}; + + + +static void stm32_led_blue_class_init (ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = stm32_led_init_Blue; + dc->desc = "STM32 LED Blue"; + dc->vmsd = &vmstate_stm32_led, + dc->props = stm32_led_blue_sysbus_properties; +} + + + +static void stm32_led_green_class_init (ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = stm32_led_init_Green; + dc->desc = "STM32 LED Green"; + dc->vmsd = &vmstate_stm32_led, + dc->props = stm32_led_green_sysbus_properties; +} + + + +static TypeInfo stm32_led_info_blue = { + .name = "stm32_led_blue", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof (stm32_led_state), + .class_init = stm32_led_blue_class_init, +}; + + + +static TypeInfo stm32_led_info_green = { + .name = "stm32_led_green", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof (stm32_led_state), + .class_init = stm32_led_green_class_init, +}; + + + +static void stm32_led_register_devices(void) { + type_register_static(&stm32_led_info_blue); + type_register_static(&stm32_led_info_green); +} + + + +type_init(stm32_led_register_devices) -- 1.7.9.5
很開心的把生出來的 patch 寄給 jserv review,馬上被抓出以下有問題的地方QAQ
看來開發功力還要再練練!!慢慢養成經驗值
注意以下:
(1) 使用 C-style comment 風格
(2) 錯別字,如 "unimplemtmented"
(3) 文法,如 "initial the processor" 應該是 "initialize the processor"
(4) "create the button" 與 "create the LEDs" 應該獨立為其他 patch
(5) ssys_{write,read} 是否需要實做?
=======================================
8/20 update
把我的 code 放上 github: https://github.com/xatier/qemu
以後改完 code 要先XD
git push qemu-github summer-work
另外 rebase origin 要記得先 pull 下來... merge,不然會失敗XD
筆記一下流程
git checkout master
git fetch origin
git pull
git checkout summer-work
git rebase origin/master
git pull qemu-github summer-work
git merge
git push qemu-github summer-work
=======================================
目前的問題是卡在實作 RCC 的部份,參考了 pl031 / stellaris 等機器正在想辦法實作
想辦法加上 RCC tick 的行為,透過 qemu_new_timer_ns 去初始化 tick
另外有這台歪果人做的 STM32 模擬,好像跟我們的很像...
https://github.com/beckus/qemu_stm32/commits/stm32_v1.1.0/
https://github.com/beckus/stm32_p103_demos
不過 beckus 的 code 最近在大改就是 (應該是要 fit 新的 qemu 版本)
=======================================
9/23 update
git checkout master
git fetch origin
git pull
git checkout summer-work
git rebase origin/master
git pull qemu-github summer-work
git merge
git push qemu-github summer-work
=======================================
目前的問題是卡在實作 RCC 的部份,參考了 pl031 / stellaris 等機器正在想辦法實作
想辦法加上 RCC tick 的行為,透過 qemu_new_timer_ns 去初始化 tick
接上 qemu-timer.h 上面的 API
另外有這台歪果人做的 STM32 模擬,好像跟我們的很像...
https://github.com/beckus/qemu_stm32/commits/stm32_v1.1.0/
https://github.com/beckus/stm32_p103_demos
不過 beckus 的 code 最近在大改就是 (應該是要 fit 新的 qemu 版本)
=======================================
9/23 update
後來進開學比較忙,一方面 qemu 的進度比較少,令一方面也沒時間再把這些瑣碎的小進度放上來
接下來的工作是幫忙 jserv 測試 beckus 的作品,我這邊目前應該暫時停止開發了
前端的部份 WeiYao 會幫忙做網頁式的模擬器外觀,任務是要把原本的 Python-TKinter 的部份重新做過,用 HTML5
jserv 在成大的課程也陸續開始了,課程網頁:
作業(使用 gitcafe!):
雖然很可惜最後沒能在暑假前幫 jserv 完成完整的 qemu-STM32 的 modeling ,但是還是很開心,在這期間學到了非常非常多的東西,也感謝 jserv 能給我一個這麼棒的打工經驗!
希望接下來還有機會跟 jserv 一起合作其他相關有趣的專案 :)
開發暫且告一段落囉~
Subscribe to:
Posts (Atom)