# Portability
Portable Operating Systems
* Assembly is kept to a minimum
* and interfaces and features are sufficiently general and abstract so that they work on a wide range of architectures
* optimal code is traded for portable code
Linux
* much fast-path and low-level code is architecture-dependent and often written in assembly
* This approach enables Linux to remain portable without foregoing optimizations
example



# History of Portability in Linux


# Word Size and Data Types
一個word是machine一個單位時間能執行的data量
當你說一個machine是"n-bits"的時候,通常就在講這個machine's word size.
* 32bits
* 4bytes (word size)
* 64bits
* 8bytes (word size)
> The size of a processor’s general-purpose registers (GPRs) is equal to its word size
>
> The widths of the components in a given architecture—for example, the memory bus—are usually at least as wide as the word size
>
> Typically, at least in the architectures that Linux supports, the virtual memory address space is equal to the word size
>
* the size of a pointer is equal to the word size
* the size of the C type long is equal to the word size
* whereas the size of the int type is sometimes less than that of the word size




# Opaque Types (不透明的types)
* pid_t
* atomic_t
* dev_t
* gid_t
* uid_t

# Special Types


# Explicitly Sized Types





# Signedness of Chars
不要心中有預設char是 signed or unsigned
不同架構default不一樣
ARM: unsigned

# Data Alignment
定義

有些architectures有比較嚴格的定義,在有些RISC based的機器上,loading一個unaligned data可能會導致processor trap(a handled error). 不然也會導致performance degradation.
# Avoiding Alignment Issues
The compiler generally prevents alignment issues by naturally aligning all data types
所以所有的變數型態default都是alignment的
* Accessing an aligned address with a recast pointer of a larger-aligned address causes an alignment issue

這個例子把 pointer to char casting成一個 unsigned long. 會導致32 or 64bits unsigned long變數被loading進來cpu,但不是4 or 8的倍數
# Alignment of Nonstandard Types

# Structure Padding





ANSI C有規定compiler永遠不能改變structure members的先後順序.所以妳自己要決定順序。
實際上也不能改,一改就會崩潰,因為在計算function裡面的variables的位置都是用base address + offsets去算的

gcc -Wpadded可以警告你那些structure有被加上padding
# Byte Order
Byte ordering is the order of bytes within a word
* Big-endian
* little-endian


* X86: little-endian
* others: big-endian
Consider the number 1027


測試系統是哪種endian

architecture in linux要define兩者其中之一
in <asm/byteorder.h>
* __BIG_ENDIAN
* __LITTLE_ENDIAN
還可以互相轉換

# Time
The measurement of time is another kernel concept that can differ between architectures
or even kernel revisions.
不要亂猜,這些kernel版本不同都有可能不同
* the frequency of the timer interrupt
* number of jiffies per second
always use HZ to scale your units of time correctly
For example
* 2.6之後x86 : HZ is 100
* the timer interrupt occurs 100 times per second
* or every 10 milliseconds
* 2.6之前x86 : HZ is 1000
* Alpha: HZ is 1024
* ARM: HZ is 100

# Page Size
永遠不要亂猜page size是多少
x86-32的programmers常常會亂猜page size = 4KB
x86上的確是這樣,但其他architectures有不同大小,很多architectures支援 multiple page sizes!

所以請用macro
* PAGE_SIZE = the size of a page in bytes
* PAGE_SHIFT = number of bits to left-shift an address to derive its page number.
EX:
on X86-32 with 4KB pages
* PAGE_SIZE is 4096
* PAGE_SHIFT is 12
# Processor Ordering
善用 barrier


# SMP, Kernel Preemption, and High Memory
永遠預設這三種情況下去coding

Conclusion

要寫portable code需要注意這些
* wordsize
* data type size
* alignment
* padding
* byte order
* signedness
* endianness
* page size
* processor load/sotre ordering
* 永遠要注意你用的data types是不是最正確的