# Linux Kernel Quick Question
###### tags: `Interview` `linuxKernel` `EMBEDDED_C
1. hello world moudle 怎寫
```clike=
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_fdt.h>
#include <linux/of_platform.h>
MODULE_LICENSE("Dual BSD/GPL");
static int __init device_tree_init(void)
{
/*
a pointer point to a device_node struct
*/
printk(" ---------------------------------\n");
struct device_node *np;
printk("device tree start checking the node\n");
/* Disable SMP boot unless both CPUs are listed in DT and !disabled */
np = of_find_node_by_name(NULL, "uart1");
pr_info("start checking the node with np of ptr\n");
if (np =! NULL){
pr_info("%s find node in dts\n",__func__);
}
else{
pr_err("%s error: cannot find the the node in dts\n",__func__);
}
return 0;
}
static void __exit device_tree_exit(void)
{
printk("end of the module\n");
printk("--------------------------------------------------------------------------\n");
}
/*
* load a Linux driver
*/
module_init(device_tree_init);
/*
* unload the Linux driver
*/
module_exit(device_tree_exit);
```
### 2. Entry Point / Exit Point of the Kernel Module
```clike=
module_init(*_init_module);
module_exit(*_exit_module);
```
* #### What does it mean `__init`?
* #### What does it mean `__exit`?
### 4. character device driverv .read .write 怎寫
* `struct file_opertion`
```clike=
const struct file_operations my_fops = {
.owner = THIS_MODULE,
.open = my_open,
.read = my_read,
.write = my_write,
.release = my_release,
.unlocked_ioctl = my_ioctl
};
```
* Read
```clike=
static int my_read(struct file *file, char __user *user_buffer,
size_t size, loff_t *offset)
{
struct my_device_data *my_data = (struct my_device_data *) file->private_data;
ssize_t len = min(my_data->size - *offset, size);
if (len <= 0)
return 0;
/* read data from my_data->buffer to user buffer */
if (copy_to_user(user_buffer, my_data->buffer + *offset, len))
return -EFAULT;
*offset += len;
return len;
}
```
* Write
```clike=
static int my_read(struct file *file, char __user *user_buffer,
size_t size, loff_t *offset)
{
struct my_device_data *my_data = (struct my_device_data *) file->private_data;
ssize_t len = min(my_data->size - *offset, size);
if (len <= 0)
return 0;
/* read data from my_data->buffer to user buffer */
if (copy_to_user(user_buffer, my_data->buffer + *offset, len))
return -EFAULT;
*offset += len;
return len;
}
```
### 6. kconfig怎加
* `Make Menuconfig`加入後
### 7. config 放哪,如何更改
* `make menuconfig` 生成新的config file
### 8. build完Kernel後會產生幾種類型的檔以及格式的差異-[Refefrence](https://www.cnblogs.com/lemaden/p/10438499.html)
* **`vmlinux`**:
* directory:`/arh/arm/boot/compressed`
* vm代表Virtual Memory,
* File Format(using `file` command to check)
* #### ELF
* statically linked,ELF 32-bit LSB executable
* **`dtb`**:
* directory:`/arch/arm/boot/dts`
* File Format
* imx6ul-panzer.dtb: Device Tree Blob version 17, size=36467, boot CPU=0, string block size=2587, **DT structure** block size=33824
* **`zImage`**:
* directory: `arch/arm/boot/compressed/vmlinux`
* **壓縮過後的vmlinux**,
它是由vmlinux經過objcopy,objcopy實現由vmlinux的elf文件複製成純binary file並由gzip壓縮分解而成
* File Format:
* Linux kernel ARM boot executable zImage (little-endian)
### 9. build完產物放哪
* dtb-> `/arch/arm/boot/dts`
* zImage->
---
### 10. dts怎改
---
### 11. image格式差異 ??
###
### 12. external ko怎build
* Refernece 編譯過得source code
* `Makefile`, `.c`
* `export ARCH = `
* `export Cross_Compile`
* `Make`
* Insert Module
* `modprobe`
* `insertmode`
---
### 13. Makefile怎寫
```script=
obj-m :=smnt_falt.o
KDIR :=/home/paul/Panzer/linux-imx_4_9MYCC =/home/paul/opt/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
# The KDIR must have to assign a ./direction
modules:
$(MAKE) ARCH=arm CROSS_COMPILE=$(MYCC) -C $(KDIR) SUBDIRS=$(shell pwd) modules
clean:
rm -f modules.order Module.symvers *.o *.ko *.mod.c
```
### 語法整理
#### **`:=`**
`:=`注意到,make 會將整個 Makefile 展開後,再決定變數的值。也就是說,變數的值將會是整個 Mackfile 中最後被指定的值。
#### **`?=`**
`?=`是一個簡化的語法:若變數未定義,則替它指定新的值。
否則,採用原有的值。
* e.g:`Foo?=`
#### **`+=`**
若變數未定義,則替它指定新的值。否則,採用原有的值。
* e.g:``
---
### 14. compiler怎指定???
`export ARCH=arm`
`export CROSS_COMPILE=/gcc-arm */bin/arm-none-eabi-`
### 15. kernel版本怎看
* 透過板子
* `uname -a`
* `cat /proc/version`
* 參考Makfile
* Makefile一開始就會寫出
```clike=
# SPDX-License-Identifier: GPL-2.0
VERSION = 4
PATCHLEVEL = 14
SUBLEVEL = 78
EXTRAVERSION =
NAME = Petit Gorille
```
### 16. 反組譯看dump???
### 17. 板子上常用指令
#### **`cat proc interrupt`**
* e.g:
```
CPU0 CPU1 CPU2 CPU3
0: 3710374484 0 0 0 IO-APIC-edge timer
1: 20 0 0 0 IO-APIC-edge i8042
6: 5 0 0 0 IO-APIC-edge floppy
7: 0 0 0 0 IO-APIC-edge parport0
8: 0 0 0 0 IO-APIC-edge rtc
9: 0 0 0 0 IO-APIC-level acpi
12: 240 0 0 0 IO-APIC-edge i8042
14: 11200026 0 0 0 IO-APIC-edge ide0
51: 61281329 0 0 0 IO-APIC-level ioc0
59: 1 0 0 0 IO-APIC-level vmci
67: 19386473 0 0 0 IO-APIC-level eth0
75: 94595340 0 0 0 IO-APIC-level eth1
NMI: 0 0 0 0
LOC: 3737150067 3737142382 3737145101 3737144204
ERR: 0
MIS: 0
```
* IRQ
> IRQ0 — system timer (cannot be changed);
> IRQ1 — keyboard controller (cannot be changed)
> IRQ3 — serial port controller for serial port 2 (shared with serial port 4, if present);
> IRQ 4 — serial port controller for serial port 1 (shared with serial port 3, if present);
> IRQ 5 — parallel port 2 and 3 or sound card;
> IRQ 6 — floppy disk controller;
> IRQ 7 — parallel port 1. It is used for printers or for any parallel port if a printer is not present.
#### **`cat proc vmalloc`**
#### **`cat proc meminfo`**
> The ‘/proc/meminfo‘ is used by to report the amount of free and used memory (both physical and swap) on the system as well as the shared memory and buffers used by the kernel.
```
MemTotal: 1882064 kB
MemFree: 1376380 kB
MemAvailable: 1535676 kB
Buffers: 2088 kB
Cached: 292324 kB
SwapCached: 0 kB
Active: 152944 kB
Inactive: 252628 kB
Active(anon): 111328 kB
Inactive(anon): 16508 kB
Active(file): 41616 kB
Inactive(file): 236120 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 2097148 kB
SwapFree: 2097148 kB
Dirty: 40 kB
Writeback: 0 kB
AnonPages: 111180 kB
Mapped: 56396 kB
Shmem: 16676 kB
Slab: 54508 kB
SReclaimable: 25456 kB
SUnreclaim: 29052 kB
KernelStack: 2608 kB
PageTables: 5056 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 3038180 kB
Committed_AS: 577664 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 14664 kB
VmallocChunk: 34359717628 kB
HardwareCorrupted: 0 kB
AnonHugePages: 24576 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 69632 kB
DirectMap2M: 2027520 kB
```
* #### Module
* Add Module
* `insmod`
* `modprobe`
* Display the current moad module
* `lsmod`
* Remove the module
* `rmmod`
* Get Information of the module
* `modinfo`
* log level Set Up
19. What's`device tree`
* #### Hardware description file
>Device Tree is a document to tell us about the Hardware's architecture, for example we would know how many of hardware chips in this hardware.
* #### properties and nodes
>where devices are represented by nodes
with their properties.
* #### What's the purpose of it and which Kernel Version start to have ?
### 18. driver 怎麼拿到device tree裡面東西?
> 透過of_node_系列的API
* `of_find_node_by_name`
```clike=
//of_find_node_by_name
struct device_node *np1 = NULL;
printk("decalre a pointer np1 point to the struct of device_node\n");
np1 = of_find_node_by_name(NULL, "uart1");
```
* `of_machine_is_compatible`
```clike=
if (of_machine_is_compatible("fsl,imx8qm"))
imx8qm_get_mac_from_fuse(idx, mac,
&imx8_fuse_mapping[IMX8QM_FUSE]);
else if (of_machine_is_compatible("fsl,imx8qxp"))
imx8qm_get_mac_from_fuse(idx, mac,
&imx8_fuse_mapping[IMX8QXP_FUSE]);
```
### 19. What's the three types of Device Driver:
* Character Device Module
* Block Device Module
* Network Interface Module
### 20. Linux Kernel可以被簡單分為以下幾個區塊:
* Process management
>Kernel負責創造銷毀Process,並且也handling their connection to the outside world (input and output)。與不同的Process溝通(signals、pipe、 interprocess communication primitives)是整個系統的基礎,也是由Kernel掌控。CPU的process排成也是歸類在這,Kernel可以在單CPU或多CPU上跑虛擬的多個process。
* Memory management
> 記憶體是重要資源,並且如何用它也成為效能關鍵。Kernel建了虛擬記憶體空間,並且所有processes都是在上面被控管資源的方式執行。所有kernel使用Memory management都是透過 malloc/free這組函數來與之互動的,複雜一點的函數裡面也是malloc/free。
* Filesystems
>Unix就是基於Filesystems的一個作業系統,幾乎所有東西在Unix裡面都能被當作一個檔案。Kernel會建 structured filesystem on top of unstructured hardware,這個抽象的檔案才會被系統用力的使用。Linux支援多種不同 filesystem類別,可以有不同方法來 organizing data on the physical medium。例如磁碟可以格式化成Linux-standard ext3 filesystem,或是 FAT filesystem等等的。
* Device control
> 幾乎所有 system operation都會最終map到硬體。除了 processor、 memory還有一些其他以外,所有device control operations都由一段 specific to the device being addressed的code來執行,這個code就是device driver。所有 peripheral想在掛在系統都要由kernel給他device driver,包括硬碟、鍵盤、磁碟。這部分就是本書重點。
* Networking
> Networking一定要透過 operating system管理,因為多數network都不是為了單一特定process。在process拿到 packets前, packets都會經過 collected, identified, and dispatched的程序。系統負責透過程式跟 network interfaces來傳packet,然後依據 network activity來控制程式的執行。此外,所有routing and address resolution issues都在kernel中實現。
### 21. Probe()怎麼去實做的
### 23. What's the Linux syscall? ans
* socket
* write
* malloc
### 24. What script would you use to check that a file compiles with Linux Kernel Coding Style
### 25. What's the command to get kernel log?
* `demsg`
* `cat /log/....`
### 26. What is the file used to describe the hardware architecture of ARM platform when compileing the linux kernel?
> dts
### 27. What is the file used to describe the hardware architecture of ARM platform when compileing the linux kernel?
> dtb
### 28. What commmand is used to view systemed logs?
* What's `systemed` logs?
* systemctl
* Any text file will work
* syslogctl
* rsyslog
* journalctl
### 29.Consider the ollowing mount output Which file system is read only?

* securityfs
* devpts
* tmpfs
* systemd-1
* /dev/xvdb
### 30.Which command could you use to back up a disk device without mounting at first?
### 31.What's the name of the document where you would find technical characteristics of a product,machine,component?
### 32.What's the name of the default distribution of yocto?
### 33.What's the name of the configuration file where the machine is genarlly defined?
### 34.What's the correct way to modify an exiting recipe?
### 35. [What's the booting process?](https://hackmd.io/pVjnSuIkTVaibWFUK4RfEw?both)-in Panzer
---
### 36. embedeed linux中tty的架構?
---
### 37. Big Endian && Little Endian
* Adress from low to high
* E.G: `0xFF00AB11`
* **Big Endian**越前面放的越重要
| Address | 0x4000 | 0x4001 |0x4002 |0x4003
| -------- | -------- | -------- | --------| --------|
| **Byte Order** | byte0 | byte 1|byte 2|byte 3
| **Value** | 0xFF | 0x00|0xAB|0x11|
* **Little Endian** ->相反
| Address | 0x4000 | 0x4001 |0x4002 |0x4003 |
| -------- | -------- | -------- | --------| --------|
| **Byte Order** | byte0 | byte 1|byte 2|byte 3
| **Value** | 0x11 | 0xAB|0x00|0xFF|
* #### Chck it with C programming
```clike=
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
union Endian{
char c[64];
uint64_t i;
};
// 1 Byte = 8 bit can be expressed 0xFF.
int main(void){
union Endian Var;
Var.i = (uint64_t)0x11223344;//0x11223344; //(4 + 4 + 4 +4) = 64 bit;
printf("sizeof is %ld\n",sizeof(Var.c[0]));
printf("The adrees of %p and val is %x \n",&(Var.c[0]),Var.c[0]);
printf("The adrees of %p and val is %x \n",&(Var.c[1]),Var.c[1]);
printf("The adrees of %p and val is %x \n",&(Var.c[2]),Var.c[2]);
printf("The adrees of %p and val is %x \n",&(Var.c[3]),Var.c[3]);
if(Var.c[0] == 0x11)
printf("Big Endian\n");
else
printf("Little Endian\n");
return 0;
}
```
### 38. Where's the kernel entry point
* `start_kernel`