mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 07:06:47 +00:00
添加中断 (#370)
* 添加中断 * dhcp更改为全局socketset * 解决异常中断的问题,使得能够使用中断来处理网卡数据 --------- Co-authored-by: longjin <longjin@RinGoTek.cn>
This commit is contained in:
parent
6b4e7a2972
commit
0dd8ff4332
@ -16,7 +16,6 @@ bitflags = "1.3.2"
|
||||
virtio-drivers = { git = "https://git.mirrors.dragonos.org/DragonOS-Community/virtio-drivers.git", rev = "f1d1cbb" }
|
||||
# 一个无锁MPSC队列
|
||||
thingbuf = { version = "0.1.3", default-features = false, features = ["alloc"] }
|
||||
# smoltcp 0.9.1
|
||||
smoltcp = { git = "https://git.mirrors.dragonos.org/DragonOS-Community/smoltcp.git", rev = "9027825", default-features = false, features = ["log", "alloc", "socket-raw", "socket-udp", "socket-tcp", "socket-icmp", "socket-dhcpv4", "socket-dns", "proto-ipv4", "proto-ipv6"]}
|
||||
# num-traits 0.2.15
|
||||
num-traits = { git = "https://git.mirrors.dragonos.org/DragonOS-Community/num-traits.git", rev="1597c1c", default-features = false }
|
||||
|
@ -3,7 +3,7 @@ use crate::driver::pci::pci_irq::TriggerMode;
|
||||
/// @param processor 目标CPU ID号
|
||||
/// @return MSI Message Address
|
||||
pub fn ia64_pci_get_arch_msi_message_address(processor: u16) -> u32 {
|
||||
0xfee00000 as u32 | ((processor as u32) << 12)
|
||||
0xfee00000 | ((processor as u32) << 12)
|
||||
}
|
||||
/// @brief 获得MSI Message Data
|
||||
/// @param vector 分配的中断向量号
|
||||
|
@ -14,7 +14,7 @@
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize("O0")
|
||||
// 导出定义在irq.c中的中段门表
|
||||
extern void (*interrupt_table[24])(void);
|
||||
extern void (*interrupt_table[25])(void);
|
||||
extern uint32_t rs_current_pcb_preempt_count();
|
||||
extern uint32_t rs_current_pcb_pid();
|
||||
extern uint32_t rs_current_pcb_flags();
|
||||
@ -363,7 +363,7 @@ int apic_init()
|
||||
cli();
|
||||
kinfo("Initializing APIC...");
|
||||
// 初始化中断门, 中断使用rsp0防止在软中断时发生嵌套,然后处理器重新加载导致数据被抹掉
|
||||
for (int i = 32; i <= 55; ++i)
|
||||
for (int i = 32; i <= 56; ++i)
|
||||
set_intr_gate(i, 0, interrupt_table[i - 32]);
|
||||
|
||||
// 设置local apic中断门
|
||||
@ -413,7 +413,6 @@ int apic_init()
|
||||
*/
|
||||
void do_IRQ(struct pt_regs *rsp, ul number)
|
||||
{
|
||||
|
||||
if (number < 0x80 && number >= 32) // 以0x80为界限,低于0x80的是外部中断控制器,高于0x80的是Local APIC
|
||||
{
|
||||
// ==========外部中断控制器========
|
||||
|
@ -8,19 +8,15 @@
|
||||
// 现在pci设备的中断由自己进行控制,这些不执行内容的函数是为了适配旧的中断处理机制
|
||||
void pci_irq_enable(ul irq_num)
|
||||
{
|
||||
|
||||
}
|
||||
void pci_irq_disable(ul irq_num)
|
||||
{
|
||||
|
||||
}
|
||||
ul pci_irq_install(ul, void*)
|
||||
{
|
||||
|
||||
}
|
||||
void pci_irq_uninstall(ul irq_num)
|
||||
{
|
||||
|
||||
}
|
||||
/// @brief 与本操作系统的中断机制进行交互,把中断处理函数等注册到中断结构体中(被rust调用)
|
||||
/// @param irq_num 要进行注册的中断号
|
||||
@ -28,27 +24,27 @@ void pci_irq_uninstall(ul irq_num)
|
||||
/// @param parameter 中断处理函数传入参数
|
||||
/// @param irq_name 中断名字
|
||||
/// @param pci_irq_ack 对于中断的回复,为NULL时会使用默认回应
|
||||
uint16_t c_irq_install(ul irq_num,void (*pci_irq_handler)(ul irq_num, ul parameter, struct pt_regs *regs),ul parameter,const char *irq_name,void (*pci_irq_ack)(ul irq_num))
|
||||
uint16_t c_irq_install(ul irq_num, void (*pci_irq_handler)(ul irq_num, ul parameter, struct pt_regs *regs), ul parameter, const char *irq_name, void (*pci_irq_ack)(ul irq_num))
|
||||
{
|
||||
// 由于为I/O APIC分配的中断向量号是从32开始的,因此要减去32才是对应的interrupt_desc的元素
|
||||
irq_desc_t *p = NULL;
|
||||
hardware_intr_controller *pci_interrupt_controller = NULL;
|
||||
if (irq_num >= 32 && irq_num < 0x80)
|
||||
p = &interrupt_desc[irq_num - 32];
|
||||
else if (irq_num >= 150 && irq_num < 200)
|
||||
p = &local_apic_interrupt_desc[irq_num - 150];
|
||||
else
|
||||
{
|
||||
//kerror("irq install for pci irq: invalid irq num: %ld.", irq_num);
|
||||
// kerror("irq install for pci irq: invalid irq num: %ld.", irq_num);
|
||||
return EINVAL;
|
||||
}
|
||||
if(p->irq_name!=NULL)
|
||||
if (p->irq_name != NULL)
|
||||
{
|
||||
return EAGAIN;
|
||||
}
|
||||
|
||||
hardware_intr_controller* pci_interrupt_controller =
|
||||
(hardware_intr_controller*)kmalloc(sizeof(hardware_intr_controller), 0);
|
||||
if (pci_interrupt_controller) {
|
||||
pci_interrupt_controller = kzalloc(sizeof(hardware_intr_controller), 0);
|
||||
if (pci_interrupt_controller)
|
||||
{
|
||||
pci_interrupt_controller->enable = pci_irq_enable;
|
||||
pci_interrupt_controller->disable = pci_irq_disable;
|
||||
pci_interrupt_controller->install = pci_irq_install;
|
||||
@ -56,8 +52,12 @@ uint16_t c_irq_install(ul irq_num,void (*pci_irq_handler)(ul irq_num, ul paramet
|
||||
pci_interrupt_controller->ack = pci_irq_ack;
|
||||
p->controller = pci_interrupt_controller;
|
||||
}
|
||||
else
|
||||
{
|
||||
return EAGAIN;
|
||||
}
|
||||
size_t namelen = strlen(irq_name) + 1;
|
||||
p->irq_name = (char *)kmalloc(namelen, 0);
|
||||
p->irq_name = (char *)kzalloc(namelen, 0);
|
||||
memset(p->irq_name, 0, namelen);
|
||||
strncpy(p->irq_name, irq_name, namelen);
|
||||
p->parameter = parameter;
|
||||
@ -80,12 +80,12 @@ void c_irq_uninstall(ul irq_num)
|
||||
{
|
||||
kerror("irq install for pci irq: invalid irq num: %ld.", irq_num);
|
||||
}
|
||||
if(p->irq_name != NULL)
|
||||
if (p->irq_name != NULL)
|
||||
{
|
||||
kfree(p->irq_name);
|
||||
p->irq_name = NULL;
|
||||
}
|
||||
if(p->controller != NULL)
|
||||
if (p->controller != NULL)
|
||||
{
|
||||
kfree(p->controller);
|
||||
p->controller = NULL;
|
||||
|
@ -12,15 +12,16 @@ use crate::arch::{PciArch, TraitPciArch};
|
||||
use crate::include::bindings::bindings::{
|
||||
c_irq_install, c_irq_uninstall, pt_regs, ul, EAGAIN, EINVAL,
|
||||
};
|
||||
use crate::kdebug;
|
||||
use crate::libs::volatile::{volread, volwrite, Volatile, VolatileReadable, VolatileWritable};
|
||||
|
||||
/// MSIX表的一项
|
||||
#[repr(C)]
|
||||
struct MsixEntry {
|
||||
vector_control: Volatile<u32>,
|
||||
msg_data: Volatile<u32>,
|
||||
msg_upper_addr: Volatile<u32>,
|
||||
msg_addr: Volatile<u32>,
|
||||
msg_upper_addr: Volatile<u32>,
|
||||
msg_data: Volatile<u32>,
|
||||
vector_control: Volatile<u32>,
|
||||
}
|
||||
/// Pending表的一项
|
||||
#[repr(C)]
|
||||
@ -66,17 +67,17 @@ pub enum IrqType {
|
||||
// PCI设备install中断时需要传递的参数
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct IrqMsg {
|
||||
irq_common_message: IrqCommonMsg,
|
||||
irq_specific_message: IrqSpecificMsg,
|
||||
pub irq_common_message: IrqCommonMsg,
|
||||
pub irq_specific_message: IrqSpecificMsg,
|
||||
}
|
||||
// PCI设备install中断时需要传递的共同参数
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct IrqCommonMsg {
|
||||
irq_index: u16, //要install的中断号在PCI设备中的irq_vector的index
|
||||
irq_name: CString, //中断名字
|
||||
irq_parameter: u16, //中断额外参数,可传入中断处理函数
|
||||
irq_hander: unsafe extern "C" fn(irq_num: ul, parameter: ul, regs: *mut pt_regs), // 中断处理函数
|
||||
irq_ack: Option<unsafe extern "C" fn(irq_num: ul)>, // 中断的ack,可为None,若为None则中断处理中会正常通知中断结束,不为None则调用传入的函数进行回复
|
||||
pub irq_index: u16, //要install的中断号在PCI设备中的irq_vector的index
|
||||
pub irq_name: CString, //中断名字
|
||||
pub irq_parameter: u16, //中断额外参数,可传入中断处理函数
|
||||
pub irq_hander: unsafe extern "C" fn(irq_num: ul, parameter: ul, regs: *mut pt_regs), // 中断处理函数
|
||||
pub irq_ack: Option<unsafe extern "C" fn(irq_num: ul)>, // 中断的ack,可为None,若为None则中断处理中会正常通知中断结束,不为None则调用传入的函数进行回复
|
||||
}
|
||||
// PCI设备install中断时需要传递的特有参数,Msi代表MSI与MSIX
|
||||
#[derive(Clone, Debug)]
|
||||
@ -88,7 +89,7 @@ pub enum IrqSpecificMsg {
|
||||
},
|
||||
}
|
||||
impl IrqSpecificMsg {
|
||||
fn msi_default() -> Self {
|
||||
pub fn msi_default() -> Self {
|
||||
IrqSpecificMsg::Msi {
|
||||
processor: 0,
|
||||
trigger_mode: TriggerMode::EdgeTrigger,
|
||||
@ -122,16 +123,16 @@ pub trait PciInterrupt: PciDeviceStructure {
|
||||
if flag.contains(IRQ::PCI_IRQ_MSIX) {
|
||||
if let Some(cap_offset) = self.msix_capability_offset() {
|
||||
let data =
|
||||
PciArch::read_config(&self.common_header().bus_device_function, cap_offset + 4);
|
||||
let irq_max_num = ((data >> 16) & 0x07ff) as u16;
|
||||
PciArch::read_config(&self.common_header().bus_device_function, cap_offset);
|
||||
let irq_max_num = ((data >> 16) & 0x7ff) as u16 + 1;
|
||||
let data =
|
||||
PciArch::read_config(&self.common_header().bus_device_function, cap_offset + 4);
|
||||
let msix_table_bar = (data & 0x01) as u8;
|
||||
let msix_table_offset = data & 0xfffe;
|
||||
let msix_table_bar = (data & 0x07) as u8;
|
||||
let msix_table_offset = data & (!0x07);
|
||||
let data =
|
||||
PciArch::read_config(&self.common_header().bus_device_function, cap_offset + 8);
|
||||
let pending_table_bar = (data & 0x01) as u8;
|
||||
let pending_table_offset = data & 0xfffe;
|
||||
let pending_table_bar = (data & 0x07) as u8;
|
||||
let pending_table_offset = data & (!0x07);
|
||||
*self.irq_type_mut()? = IrqType::Msix {
|
||||
msix_table_bar,
|
||||
msix_table_offset,
|
||||
@ -503,12 +504,13 @@ pub trait PciInterrupt: PciDeviceStructure {
|
||||
.bar()
|
||||
.ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))?;
|
||||
let msix_bar = pcistandardbar.get_bar(msix_table_bar)?;
|
||||
let vaddr = msix_bar
|
||||
let vaddr: crate::mm::VirtAddr = msix_bar
|
||||
.virtual_address()
|
||||
.ok_or(PciError::PciIrqError(PciIrqError::BarGetVaddrFailed))?
|
||||
+ msix_table_offset as usize
|
||||
+ msg.irq_common_message.irq_index as usize * size_of::<MsixEntry>();
|
||||
let msix_entry = NonNull::new(vaddr.data() as *mut MsixEntry).unwrap();
|
||||
kdebug!("msg_data: {:?}, msix_addr: {:?}", msg_data, msg_address);
|
||||
unsafe {
|
||||
volwrite!(msix_entry, vector_control, 0);
|
||||
volwrite!(msix_entry, msg_data, msg_data);
|
||||
|
@ -5,10 +5,15 @@ use crate::driver::pci::pci::{
|
||||
PciStandardDeviceBar, PCI_CAP_ID_VNDR,
|
||||
};
|
||||
|
||||
use crate::driver::pci::pci_irq::{IrqCommonMsg, IrqMsg, IrqSpecificMsg, PciInterrupt, IRQ};
|
||||
use crate::include::bindings::bindings::pt_regs;
|
||||
use crate::kdebug;
|
||||
use crate::libs::volatile::{
|
||||
volread, volwrite, ReadOnly, Volatile, VolatileReadable, VolatileWritable, WriteOnly,
|
||||
};
|
||||
use crate::mm::VirtAddr;
|
||||
use crate::net::net_core::poll_ifaces_try_lock_onetime;
|
||||
use alloc::ffi::CString;
|
||||
use core::{
|
||||
fmt::{self, Display, Formatter},
|
||||
mem::{align_of, size_of},
|
||||
@ -53,6 +58,12 @@ const VIRTIO_PCI_CAP_ISR_CFG: u8 = 3;
|
||||
/// Device specific configuration.
|
||||
const VIRTIO_PCI_CAP_DEVICE_CFG: u8 = 4;
|
||||
|
||||
/// Virtio设备接收中断的设备号
|
||||
const VIRTIO_RECV_VECTOR: u16 = 56;
|
||||
/// Virtio设备接收中断的设备号的表项号
|
||||
const VIRTIO_RECV_VECTOR_INDEX: u16 = 0;
|
||||
// 接收的queue
|
||||
const QUEUE_RECEIVE: u16 = 0;
|
||||
///@brief device id 转换为设备类型
|
||||
///@param pci_device_id,device_id
|
||||
///@return DeviceType 对应的设备类型
|
||||
@ -89,6 +100,11 @@ pub struct PciTransport {
|
||||
config_space: Option<NonNull<[u32]>>,
|
||||
}
|
||||
|
||||
unsafe extern "C" fn virtio_irq_hander(_irq_num: u64, _irq_paramer: u64, _regs: *mut pt_regs) {
|
||||
// kdebug!("12345");
|
||||
poll_ifaces_try_lock_onetime().ok();
|
||||
}
|
||||
|
||||
impl PciTransport {
|
||||
/// Construct a new PCI VirtIO device driver for the given device function on the given PCI
|
||||
/// root controller.
|
||||
@ -111,6 +127,30 @@ impl PciTransport {
|
||||
let mut device_cfg = None;
|
||||
device.bar_ioremap().unwrap()?;
|
||||
device.enable_master();
|
||||
let standard_device = device.as_standard_device_mut().unwrap();
|
||||
// 目前缺少对PCI设备中断号的统一管理,所以这里需要指定一个中断号。不能与其他中断重复
|
||||
let irq_vector = standard_device.irq_vector_mut().unwrap();
|
||||
irq_vector.push(VIRTIO_RECV_VECTOR);
|
||||
standard_device
|
||||
.irq_init(IRQ::PCI_IRQ_MSIX)
|
||||
.expect("IRQ init failed");
|
||||
// 中断相关信息
|
||||
let msg = IrqMsg {
|
||||
irq_common_message: IrqCommonMsg {
|
||||
irq_index: 0,
|
||||
irq_name: CString::new(
|
||||
"Virtio_Recv_
|
||||
IRQ",
|
||||
)
|
||||
.expect("CString::new failed"),
|
||||
irq_parameter: 0,
|
||||
irq_hander: virtio_irq_hander,
|
||||
irq_ack: None,
|
||||
},
|
||||
irq_specific_message: IrqSpecificMsg::msi_default(),
|
||||
};
|
||||
standard_device.irq_install(msg)?;
|
||||
standard_device.irq_enable(true)?;
|
||||
//device_capability为迭代器,遍历其相当于遍历所有的cap空间
|
||||
for capability in device.capabilities().unwrap() {
|
||||
if capability.id != PCI_CAP_ID_VNDR {
|
||||
@ -268,16 +308,19 @@ impl Transport for PciTransport {
|
||||
) {
|
||||
// Safe because the common config pointer is valid and we checked in get_bar_region that it
|
||||
// was aligned.
|
||||
// kdebug!("queue_select={}",queue);
|
||||
// kdebug!("queue_size={}",size as u16);
|
||||
// kdebug!("queue_desc={:#x}",descriptors as u64);
|
||||
// kdebug!("driver_area={:#x}",driver_area);
|
||||
unsafe {
|
||||
volwrite!(self.common_cfg, queue_select, queue);
|
||||
volwrite!(self.common_cfg, queue_size, size as u16);
|
||||
volwrite!(self.common_cfg, queue_desc, descriptors as u64);
|
||||
volwrite!(self.common_cfg, queue_driver, driver_area as u64);
|
||||
volwrite!(self.common_cfg, queue_device, device_area as u64);
|
||||
if queue == QUEUE_RECEIVE {
|
||||
volwrite!(self.common_cfg, queue_msix_vector, VIRTIO_RECV_VECTOR_INDEX);
|
||||
let vector = volread!(self.common_cfg, queue_msix_vector);
|
||||
if vector != VIRTIO_RECV_VECTOR_INDEX {
|
||||
panic!("Vector set failed");
|
||||
}
|
||||
}
|
||||
volwrite!(self.common_cfg, queue_enable, 1);
|
||||
}
|
||||
}
|
||||
|
@ -86,9 +86,10 @@ Build_IRQ(0x34);
|
||||
Build_IRQ(0x35);
|
||||
Build_IRQ(0x36);
|
||||
Build_IRQ(0x37);
|
||||
Build_IRQ(0x38);
|
||||
|
||||
// 初始化中断数组
|
||||
void (*interrupt_table[24])(void) = {
|
||||
void (*interrupt_table[25])(void) = {
|
||||
IRQ0x20interrupt,
|
||||
IRQ0x21interrupt,
|
||||
IRQ0x22interrupt,
|
||||
@ -113,6 +114,7 @@ void (*interrupt_table[24])(void) = {
|
||||
IRQ0x35interrupt,
|
||||
IRQ0x36interrupt,
|
||||
IRQ0x37interrupt,
|
||||
IRQ0x38interrupt,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -16,11 +16,11 @@
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("O0")
|
||||
|
||||
#define IRQ_NUM 24
|
||||
#define IRQ_NUM 25
|
||||
#define SMP_IRQ_NUM 10
|
||||
#define LOCAL_APIC_IRQ_NUM 50
|
||||
|
||||
extern void (*interrupt_table[24])(void);
|
||||
extern void (*interrupt_table[25])(void);
|
||||
extern void do_IRQ(struct pt_regs *regs, ul number);
|
||||
|
||||
|
||||
@ -82,6 +82,7 @@ extern void (*local_apic_interrupt_table[LOCAL_APIC_IRQ_NUM])(void);
|
||||
53 PIRQF
|
||||
54 PIRQG
|
||||
55 PIRQH
|
||||
56 VIRTIO_RECV
|
||||
|
||||
|
||||
0x80 system call
|
||||
|
@ -31,11 +31,12 @@ impl TimerFunction for NetWorkPollFunc {
|
||||
pub fn net_init() -> Result<(), SystemError> {
|
||||
dhcp_query()?;
|
||||
// Init poll timer function
|
||||
let next_time = next_n_ms_timer_jiffies(5);
|
||||
let timer = Timer::new(Box::new(NetWorkPollFunc), next_time);
|
||||
timer.activate();
|
||||
// let next_time = next_n_ms_timer_jiffies(5);
|
||||
// let timer = Timer::new(Box::new(NetWorkPollFunc), next_time);
|
||||
// timer.activate();
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fn dhcp_query() -> Result<(), SystemError> {
|
||||
let binding = NET_DRIVERS.write();
|
||||
|
||||
@ -52,15 +53,14 @@ fn dhcp_query() -> Result<(), SystemError> {
|
||||
// IMPORTANT: This should be removed in production.
|
||||
dhcp_socket.set_max_lease_duration(Some(smoltcp::time::Duration::from_secs(10)));
|
||||
|
||||
let mut sockets = smoltcp::iface::SocketSet::new(vec![]);
|
||||
let dhcp_handle = sockets.add(dhcp_socket);
|
||||
let dhcp_handle = SOCKET_SET.lock().add(dhcp_socket);
|
||||
|
||||
const DHCP_TRY_ROUND: u8 = 10;
|
||||
for i in 0..DHCP_TRY_ROUND {
|
||||
kdebug!("DHCP try round: {}", i);
|
||||
let _flag = net_face.poll(&mut sockets);
|
||||
let event = sockets.get_mut::<dhcpv4::Socket>(dhcp_handle).poll();
|
||||
// kdebug!("event = {event:?} !!!");
|
||||
net_face.poll(&mut SOCKET_SET.lock()).ok();
|
||||
let mut binding = SOCKET_SET.lock();
|
||||
let event = binding.get_mut::<dhcpv4::Socket>(dhcp_handle).poll();
|
||||
|
||||
match event {
|
||||
None => {}
|
||||
@ -161,3 +161,23 @@ pub fn poll_ifaces_try_lock(times: u16) -> Result<(), SystemError> {
|
||||
// 尝试次数用完,返回错误
|
||||
return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
|
||||
}
|
||||
|
||||
/// 对ifaces进行轮询。
|
||||
///
|
||||
/// @return 轮询成功,返回Ok(())
|
||||
/// @return 加锁超时,返回SystemError::EAGAIN_OR_EWOULDBLOCK
|
||||
/// @return 没有网卡,返回SystemError::ENODEV
|
||||
pub fn poll_ifaces_try_lock_onetime() -> Result<(), SystemError> {
|
||||
let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read();
|
||||
if guard.len() == 0 {
|
||||
kwarn!("poll_ifaces: No net driver found!");
|
||||
// 没有网卡,返回错误
|
||||
return Err(SystemError::ENODEV);
|
||||
}
|
||||
let mut sockets = SOCKET_SET.try_lock()?;
|
||||
for (_, iface) in guard.iter() {
|
||||
iface.poll(&mut sockets).ok();
|
||||
}
|
||||
SOCKET_WAITQUEUE.wakeup_all(None);
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -62,8 +62,8 @@ QEMU_DRIVE="id=disk,file=${QEMU_DISK_IMAGE},if=none"
|
||||
|
||||
# ps: 下面这条使用tap的方式,无法dhcp获取到ip,暂时不知道为什么
|
||||
# QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -net nic,netdev=nic0 -netdev tap,id=nic0,model=virtio-net-pci,script=qemu/ifup-nat,downscript=qemu/ifdown-nat -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 "
|
||||
QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -nic user,model=virtio-net-pci,hostfwd=tcp::12580-:12580 -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 "
|
||||
|
||||
#QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -nic user,model=virtio-net-pci,hostfwd=tcp::12580-:12580 -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 "
|
||||
QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -netdev user,id=hostnet0,hostfwd=tcp::12580-:12580 -device virtio-net-pci,vectors=5,netdev=hostnet0,id=net0 -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 "
|
||||
QEMU_ARGUMENT="-d ${QEMU_DISK_IMAGE} -m ${QEMU_MEMORY} -smp ${QEMU_SMP} -boot order=d -monitor ${QEMU_MONITOR} -d ${qemu_trace_std} "
|
||||
|
||||
QEMU_ARGUMENT+="-s -S -cpu ${QEMU_CPU_FEATURES} -rtc ${QEMU_RTC_CLOCK} -serial ${QEMU_SERIAL} -drive ${QEMU_DRIVE} ${QEMU_DEVICES}"
|
||||
|
Loading…
x
Reference in New Issue
Block a user