u/acidoglutammico

Image 1 — Pasta à la Clara
Image 2 — Pasta à la Clara
▲ 17 r/cucina

Pasta à la Clara

^(La prima foto è la ricreazione più fedele possibile della ricetta, la seconda la mia variazione)

Avevo trovato questo video: Pasta à la Clara della cantante Claire Richards che nel 1998 istruiva sul come comporre la sua omonima (meno una i) pietanza.

Mi sono quindi lanciato nel ricreare questa delizia capostipite della cucina inglese a ritmo di 5, 6, 7, 8.

Dato che non vengono dati ne quantità ne tempi di cottura, sono sicuro che la mia non sia un'interpretazione particolarmente accurata.

Ingredienti:

  • Tagliatelle fresche (ho usato degli spaghetti)
  • Cipolla tagliata grossa
  • Aglio tritato
  • Funghi tagliati grossi
  • Prosciutto tagliato a quadratini
  • Zuppa di pomodoro Heinz in scatola (ho usato della passata perché non l'ho trovata)
  • Cheddar grattuggiato

Scalda la padella a fuoco medio con un filo di acqua (clairerichards.net/pasta-a-la-clara-recipe dice di aggiungere olio ma io mi sono tenuto alla ricetta del video dove dice di usare acqua). Far bollire acqua per la pasta e buttarla. Aggiungere l'aglio e dopo che ha incominciato a "soffriggere" aggiungere le cipolle, aspettare "più di 5 minuti" che si ammorbidiscano. Aggiungere i funghi e aspettare che siano un po' cotti. Aggiungere il prosciutto (e come ci fa gentilmente notare Claire, se ci fossero vegetariani possono sostituire il prosciutto con altri alimenti tipo i peperoni, grazie Claire). Salare e pepare. Aggiungere il pomodoro e il formaggio. Quando pronta, scolare la pasta e aggiungerla al condimento.

Sono abbastanza sicuro lei non abbia lasciato cuocere il pomodoro abbastanza e quindi gli era rimasto molto acquoso, quindi l'ho lasciato per 10-15 minuti sul fuoco prima di aggiungere la pasta.

Devo dire che me la aspettavo peggio, facile da preparare e con ingredienti facilmente reperibili. Tuttavia troppo densa e un po' blanda.

Ho quindi cercato di ripensarla in chiave non inglese. Lo scopo era quello di riutilizzare gli ingredienti senza aggiungerne troppi altri, per renderla più commestibile rimanendo sempre nello spirito della ricetta.

Come ingredienti ho sostituito il cheddar con un formaggio di pecora molto salato, rimosso l'aglio e aggiunta della pancetta come base grassa. Ho inoltre bollito un pomodoro e aggiunto alla passata per renderla più solida.

Ho preso della pancetta e tagliata a cubetti l'ho messa in padella con un filo di acqua, quando evaporata l'acqua e sciolto il grasso, ho separato la roba solida con una forchetta e messo una abbondante dose di pepe nella padella con il grasso su fiamma alta. Sfumato con poco vino bianco. Quando evaporato ho aggiunto il prosciutto. Dopo essersi appassiti, ho aggiunto la cipolla, la passata di pomodoro e il pomodoro precedentemente bollito e tagliato. Lasciato sobbollire per 10 minuti o fino a quando non si era asciugato il pomodoro.

In un'altra padella avevo messo i funghi tagliati sottile con un filo di brodo, appena assorbito ci avevo aggiunto un po' di grasso della pancetta e li avevo fatti saltare per renderli croccanti. Poi messi da parte.

Per la pasta ho messo il minimo di acqua in una pentola per far bollire gli spaghetti in modo che rimanesse carica di amidi quando scolata. Scolare gli spaghetti per lasciarli al dente 1 o 2 minuti prima.

Quando asciutto il pomodoro, aggiungere una mestolata di acqua di cottura, aggiungere gli spaghetti, il formaggio, i funghi e la pancetta. A fiamma alta mescolare vigorosamente la pasta e il condimento.

La seconda versione è venuta meglio, il pepe si sente ed è più leggera, tuttavia il prosciutto è comunque un po' strano e i funghi non sono rimasti abbastanza croccanti.

Avete consigli su come farla meglio? Sul sito clairerichards.net/pasta-a-la-clara-recipe indicano come la cantante abbia cambiato la ricetta sostituendo la zuppa di pomodori Heinz con della passata e il formaggio cheddar con del mascarpone, tuttavia non l'ho trovata online (non che mi sia sprecato molto).

u/acidoglutammico — 3 days ago
▲ 3 r/osdev

Trying to write a very small kernel in rust by roughly following phil-opp tutorial but with the most up to date packages and features. So instead of using pic i chose to use x2apic.

this is my kernel main:

fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
    kernel::init(boot_info);

    x86_64::instructions::interrupts::int3();

    serial_println!("Done");
    kernel::hlt_loop()
}

kernel::init is:

pub fn init(boot_info: &'static mut BootInfo) {
    vga_buffer::init_vga(
        boot_info.framebuffer.as_mut().expect("Framebuffer not available")
    );
    gdt::init();
    interrupts::init_idt();
    apic::init_apic();

    x86_64::instructions::interrupts::enable();
}

apic contains:

use x86::apic::ApicControl;

pub static IA32_APIC_BASE: u32 = 0x1B;
pub static IA32_APIC_BASE_MSR_ENABLE: u64 = 0x800;
pub static IA32_X2APIC_EOI: u32 = 0x80b;

pub fn init_apic() {
    disable_pic();

    let mut apic = x86::apic::x2apic::X2APIC::new();
    apic.attach();

    unsafe {
        x86::irq::enable();
    }
    crate::serial_println!("finished setting up apic");
}

fn disable_pic() {
    const PIC_1_OFFSET: u8 = 32;
    const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8;

    unsafe {
        let mut pic = crate::pic::ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET);
        pic.initialize_disable();
    };
}

pic holds the structure for the chained pics and the initialize_disable function is:

pub unsafe fn initialize_disable(&mut self) {
    let mut wait_port: Port<u8> = Port::new(0x80);
    let mut wait = || unsafe { wait_port.write(0) };

    macro_rules! write_port {
        ($pic_n:expr, data, $w:expr) => {
            unsafe { self.pics[$pic_n].data.write($w); }
            wait();
        };
        ($pic_n:expr, command, $w:expr) => {
            unsafe { self.pics[$pic_n].command.write($w); }
            wait();
        };
    }

    let saved_masks = unsafe { self.read_masks() };

    write_port!(0, command, CMD_INIT);
    write_port!(1, command, CMD_INIT);

    write_port!(0, data, self.pics[0].offset);
    write_port!(1, data, self.pics[1].offset);

    write_port!(0, data, 4);
    write_port!(1, data, 2);

    write_port!(0, data, MODE_8086);
    write_port!(1, data, MODE_8086);

    write_port!(0, data, 0xFF);
    write_port!(1, data, 0xFF);

    unsafe { self.write_masks(saved_masks[0], saved_masks[1]) }
}

the interrupt descriptor table is properly initialized:

static IDT: Lazy<InterruptDescriptorTable> =
    Lazy::new(
    || {
        let mut idt = InterruptDescriptorTable::new();
        idt.breakpoint.set_handler_fn(breakpoint_handler);
        unsafe {
            idt.double_fault
                .set_handler_fn(double_fault_handler)
                .set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX);
        }
        idt[Into::<u8>::into(InterruptIndex::Timer)]
            .set_handler_fn(timer_interrupt_handler);
        idt
    });

and the interrupt for the breakpoint is:

extern "x86-interrupt" fn breakpoint_handler(
    stack_frame: InterruptStackFrame,
) {
    crate::serial_println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
    println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);

    unsafe {
        x86_64::registers::model_specific::Msr::new(crate::apic::IA32_X2APIC_EOI)
            .write(0);
    }
}

And yet when it hits the interrupt i get on the serial:

finished setting up apic
EXCEPTION: BREAKPOINT
InterruptStackFrame {
    instruction_pointer: VirtAddr(
        0x1000000bb61,
    ),
    code_segment: SegmentSelector {
        index: 1,
        rpl: Ring0,
    },
    cpu_flags: RFlags(
        INTERRUPT_FLAG | 0x2,
    ),
    stack_pointer: VirtAddr(
        0x18000014f98,
    ),
    stack_segment: SegmentSelector {
        index: 2,
        rpl: Ring0,
    },
}
panicked at kernel/src/interrupts.rs:62:5:
EXCEPTION: DOUBLE FAULT
InterruptStackFrame {
    instruction_pointer: VirtAddr(
        0x1000000d06a,
    ),
    code_segment: SegmentSelector {
        index: 1,
        rpl: Ring0,
    },
    cpu_flags: RFlags(
        0x2,
    ),
    stack_pointer: VirtAddr(
        0x18000014f68,
    ),
    stack_segment: SegmentSelector {
        index: 2,
        rpl: Ring0,
    },
}

I dont get why i get a double fault. if the int3 instruction is removed it doesnt crash of course.

Am i creating the interrupts wrong? i have "-cpu qemu64,+x2apic" as qemu arguments so x2apic is supported (checked even with raw_cpuid). Is the double fault because its not resetting the interrupts properly?

Since i have only 1 cpu for now i was expecting for interrupts to get routed to the only cpu. Also where can i read how to properly set up keyboard interrupts with x2apic?

reddit.com
u/acidoglutammico — 2 months ago