http://www.programmer-club.com.tw/ShowSameTitleN/embedded/2447.html
ARM唯一有規定的是
Reset: 0x00000000
Undefined instructions: 0x00000004
Software interrupt: 0x000000008
Prefetch abort: 0x0000000C
Data abort: 0x00000010
IRQ: 0x00000018
FIQ: 0x0000001C
如果那一種ARM系列support high vector, 還可以調成從
0xFFFF0000開始
至於你說的flash/sdram 是有相關, 不過都要看implementation, ARM本身是不管
最後的週邊的 (即使SDRAM也是一樣), 這些是使用ARM core的SOC廠商訂定的,
所以...沒有一定的標準, 大致上
會與ARM系列的memory co-processor有點關係,
1. 如果是用protection unit, 會由SOC廠商訂出方法, 例如SAMSUNG 2510是設定
0xF0000000的system register的bit 8來開關remap
2. 如果是以MMU的方式, 由於physical address和virual address是分離的, 所以是
由軟體來設定即可, 例如OMAP850/OMAP2430
至於為何0x00000000-0x0000001F這麼重要, 從前面可以看出, 所以, 在沒設定好前,
interrupt是要在disable的狀態.
你想要瞭解memory mapping, 一定要針對某一顆SOC, 每一顆都不同, 不過請區分清楚
physical memory, remap, virtual memory
在有virtual memory的ARM系列, 不會再多做remap, 或從另一個角度而言, 如何從
virtual memory map到physical memory, 完全是軟體, 或software designer的事.
2016年12月29日 星期四
2016年12月28日 星期三
install Intel ethernet card driver
https://sourceforge.net/projects/e1000/files/igb%20stable/5.3.4.4/
http://blog.supportmonk.com/linux/update-intelr-gigabit-ethernet-network-driver-cent-os-6-5
Download the new driver from the link :http://sourceforge.net/projects/e1000/files/igb%20stable/5.2.9.4/
Unzip and compile the new module
tar -xzvf igb-5.2.9.4.tar.gz
cd igb-5.2.9.4/src
*Make sure server has the correct kernel-devel package corresponding to the installed kernel*
make install
—————————–
this will compile the module and place it at the default location /lib/modules/2.6.32-431.23.3.el6.x86_64/kernel/drivers/net/igb
*make sure you have the backup of the old binary as the above step replace original file*
If make error, maybe "make modules_prepare" helps.
http://blog.supportmonk.com/linux/update-intelr-gigabit-ethernet-network-driver-cent-os-6-5
Download the new driver from the link :http://sourceforge.net/projects/e1000/files/igb%20stable/5.2.9.4/
Unzip and compile the new module
tar -xzvf igb-5.2.9.4.tar.gz
cd igb-5.2.9.4/src
*Make sure server has the correct kernel-devel package corresponding to the installed kernel*
make install
—————————–
this will compile the module and place it at the default location /lib/modules/2.6.32-431.23.3.el6.x86_64/kernel/drivers/net/igb
*make sure you have the backup of the old binary as the above step replace original file*
If make error, maybe "make modules_prepare" helps.
2016年12月16日 星期五
[轉] 加入of_ (device tree操作api) 的platform驱动编写 基于gpio-keys
Linux在启动后,到C入口时,会执行以下操作,加载系统平台上的总线和设备:
start_kernel() --> setup_arch() --> unflatten_device_tree()
在执行完unflatten_device_tree()后,DTS节点信息被解析出来,保存到allnodes链表中,allnodes会在后面被用到。随后,当系统启动到board文件时,会调用.init_machine,高通8974平台对应的是msm8974_init()。接着调用of_platform_populate(....)接口,加载平台总线和平台设备。
Device Tree 中的 I2C client 会透过 I2C host 驱动的 probe()函数中调用
of_i2c_register_devices(&i2c_dev->adapter);被自动展开
of_i2c_register_devices(&i2c_dev->adapter);被自动展开
SPI host 驱动的 probe 函数透过
spi_register_master()注册 master 的时候,会自动展开依附于它的 slave。
spi_register_master()注册 master 的时候,会自动展开依附于它的 slave。
static struct of_device_id gpio_keys_of_match[] = {
{ .compatible = "gpio-keys", },
{ },
};
与dts(platform device)
gpio-keys {
compatible = "gpio-keys";
power {
label = "Power Button";
gpios = <&gpio3 29 1>;
linux,code = <116>; /* KEY_POWER */
gpio-key,wakeup;
};
volume-up {
label = "Volume Up";
gpios = <&gpio1 4 1>;
linux,code = <115>; /* KEY_VOLUMEUP */
};
volume-down {
label = "Volume Down";
gpios = <&gpio1 5 1>;
linux,code = <114>; /* KEY_VOLUMEDOWN */
};
};
里的compatible匹配到。则会调用platform里的probe成员函数compatible = "gpio-keys";
power {
label = "Power Button";
gpios = <&gpio3 29 1>;
linux,code = <116>; /* KEY_POWER */
gpio-key,wakeup;
};
volume-up {
label = "Volume Up";
gpios = <&gpio1 4 1>;
linux,code = <115>; /* KEY_VOLUMEUP */
};
volume-down {
label = "Volume Down";
gpios = <&gpio1 5 1>;
linux,code = <114>; /* KEY_VOLUMEDOWN */
};
};
static int gpio_keys_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev);
{
struct device *dev = &pdev->dev;
const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev);
。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。
}
struct platform_device *pdev指向匹配成功的platform device.通过他我们可以找到对应于dts文件中的设备节点(定位到它就可以获取设备参数列表了)【因为新版内核struct device中包含了成员 struct device_node *of_node; /* associated device tree node */】
代码如下
gpio_keys_get_devtree_pdata(struct device *dev)
{
struct device_node *node, *pp;
struct gpio_keys_platform_data *pdata;
struct gpio_keys_button *button;
int error;
int nbuttons;
int i;
node = dev->of_node;
if (!node) {
error = -ENODEV;
goto err_out;
}
nbuttons = of_get_child_count(node);
if (nbuttons == 0) {
error = -ENODEV;
goto err_out;
}
pdata = kzalloc(sizeof(*pdata) + nbuttons * (sizeof *button),
GFP_KERNEL);
if (!pdata) {
error = -ENOMEM;
goto err_out;
}
pdata->buttons = (struct gpio_keys_button *)(pdata + 1);
pdata->nbuttons = nbuttons;
pdata->rep = !!of_get_property(node, "autorepeat", NULL);
i = 0;
for_each_child_of_node(node, pp) {
int gpio;
enum of_gpio_flags flags;
if (!of_find_property(pp, "gpios", NULL)) {
pdata->nbuttons--;
dev_warn(dev, "Found button without gpios\n");
continue;
}
gpio = of_get_gpio_flags(pp, 0, &flags);
if (gpio < 0) {
error = gpio;
if (error != -EPROBE_DEFER)
dev_err(dev,
"Failed to get gpio flags, error: %d\n",
error);
goto err_free_pdata;
}
button = &pdata->buttons[i++];
button->gpio = gpio;
button->active_low = flags & OF_GPIO_ACTIVE_LOW;
if (of_property_read_u32(pp, "linux,code", &button->code)) {
dev_err(dev, "Button without keycode: 0x%x\n",
button->gpio);
error = -EINVAL;
goto err_free_pdata;
}
button->desc = of_get_property(pp, "label", NULL);
if (of_property_read_u32(pp, "linux,input-type", &button->type))
button->type = EV_KEY;
button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL);
if (of_property_read_u32(pp, "debounce-interval",
&button->debounce_interval))
button->debounce_interval = 5;
}
if (pdata->nbuttons == 0) {
error = -EINVAL;
goto err_free_pdata;
}
{
struct device_node *node, *pp;
struct gpio_keys_platform_data *pdata;
struct gpio_keys_button *button;
int error;
int nbuttons;
int i;
node = dev->of_node;
if (!node) {
error = -ENODEV;
goto err_out;
}
nbuttons = of_get_child_count(node);
if (nbuttons == 0) {
error = -ENODEV;
goto err_out;
}
pdata = kzalloc(sizeof(*pdata) + nbuttons * (sizeof *button),
GFP_KERNEL);
if (!pdata) {
error = -ENOMEM;
goto err_out;
}
pdata->buttons = (struct gpio_keys_button *)(pdata + 1);
pdata->nbuttons = nbuttons;
pdata->rep = !!of_get_property(node, "autorepeat", NULL);
i = 0;
for_each_child_of_node(node, pp) {
int gpio;
enum of_gpio_flags flags;
if (!of_find_property(pp, "gpios", NULL)) {
pdata->nbuttons--;
dev_warn(dev, "Found button without gpios\n");
continue;
}
gpio = of_get_gpio_flags(pp, 0, &flags);
if (gpio < 0) {
error = gpio;
if (error != -EPROBE_DEFER)
dev_err(dev,
"Failed to get gpio flags, error: %d\n",
error);
goto err_free_pdata;
}
button = &pdata->buttons[i++];
button->gpio = gpio;
button->active_low = flags & OF_GPIO_ACTIVE_LOW;
if (of_property_read_u32(pp, "linux,code", &button->code)) {
dev_err(dev, "Button without keycode: 0x%x\n",
button->gpio);
error = -EINVAL;
goto err_free_pdata;
}
button->desc = of_get_property(pp, "label", NULL);
if (of_property_read_u32(pp, "linux,input-type", &button->type))
button->type = EV_KEY;
button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL);
if (of_property_read_u32(pp, "debounce-interval",
&button->debounce_interval))
button->debounce_interval = 5;
}
if (pdata->nbuttons == 0) {
error = -EINVAL;
goto err_free_pdata;
}
Linux pin define tracing, in NV Jeston TX1 for example
線路圖上看到的腳位名稱,例如 GPIO6_TOUCH_INT
編號是B25, 這可以在腳位矩陣圖上找到。
但對於軟體設定時這都不是你想知道的。
你想知道的是使用nv source code時,他們預設把他定義到哪一根I/O(in this case, gpio)
好在dts裡直接使用
查法是這樣的。
檢查~/drivers/pinctrl/pinctrl-tegra210.c
(或pinctrl-[你的滿滿大平台].c)
尋找字串,in this case, TOUCH_INT,來到這行
#define TEGRA_PIN_TOUCH_INT_PX1 _GPIO(185)
那就能靠gpio 去註冊他了
例如
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(X, 1) 0x0>;
編號是B25, 這可以在腳位矩陣圖上找到。
但對於軟體設定時這都不是你想知道的。
你想知道的是使用nv source code時,他們預設把他定義到哪一根I/O(in this case, gpio)
好在dts裡直接使用
查法是這樣的。
檢查~/drivers/pinctrl/pinctrl-tegra210.c
(或pinctrl-[你的滿滿大平台].c)
尋找字串,in this case, TOUCH_INT,來到這行
#define TEGRA_PIN_TOUCH_INT_PX1 _GPIO(185)
那就能靠gpio 去註冊他了
例如
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(X, 1) 0x0>;
訂閱:
文章 (Atom)