mirror of
https://github.com/timmypidashev/web.git
synced 2026-04-14 11:03:50 +00:00
Add commands mdx component; continue work on coreboot post
This commit is contained in:
@@ -29,11 +29,13 @@
|
||||
"marked": "^15.0.8",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-icons": "^5.5.0",
|
||||
"react-responsive": "^10.0.1",
|
||||
"reading-time": "^1.5.0",
|
||||
"rehype-pretty-code": "^0.14.1",
|
||||
"rehype-slug": "^6.0.0",
|
||||
"schema-dts": "^1.1.5",
|
||||
"typewriter-effect": "^2.21.0"
|
||||
"typewriter-effect": "^2.21.0",
|
||||
"unist-util-visit": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
15
src/pnpm-lock.yaml
generated
15
src/pnpm-lock.yaml
generated
@@ -44,6 +44,9 @@ importers:
|
||||
react-dom:
|
||||
specifier: ^18.3.1
|
||||
version: 18.3.1(react@18.3.1)
|
||||
react-icons:
|
||||
specifier: ^5.5.0
|
||||
version: 5.5.0(react@18.3.1)
|
||||
react-responsive:
|
||||
specifier: ^10.0.1
|
||||
version: 10.0.1(react@18.3.1)
|
||||
@@ -62,6 +65,9 @@ importers:
|
||||
typewriter-effect:
|
||||
specifier: ^2.21.0
|
||||
version: 2.21.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
unist-util-visit:
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.0
|
||||
devDependencies:
|
||||
'@astrojs/react':
|
||||
specifier: ^4.2.4
|
||||
@@ -1867,6 +1873,11 @@ packages:
|
||||
peerDependencies:
|
||||
react: ^18.3.1
|
||||
|
||||
react-icons@5.5.0:
|
||||
resolution: {integrity: sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==}
|
||||
peerDependencies:
|
||||
react: '*'
|
||||
|
||||
react-is@16.13.1:
|
||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||
|
||||
@@ -4636,6 +4647,10 @@ snapshots:
|
||||
react: 18.3.1
|
||||
scheduler: 0.23.2
|
||||
|
||||
react-icons@5.5.0(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
||||
react-is@16.13.1: {}
|
||||
|
||||
react-refresh@0.17.0: {}
|
||||
|
||||
59
src/src/components/mdx/code-block.tsx
Normal file
59
src/src/components/mdx/code-block.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Check, Copy } from 'lucide-react';
|
||||
|
||||
interface CodeBlockProps {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
'data-language'?: string;
|
||||
'data-theme'?: string;
|
||||
raw?: string;
|
||||
}
|
||||
|
||||
export const CodeBlock: React.FC<CodeBlockProps> = ({
|
||||
children,
|
||||
className,
|
||||
'data-language': language,
|
||||
raw
|
||||
}) => {
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
const handleCopy = () => {
|
||||
if (raw) {
|
||||
navigator.clipboard.writeText(raw);
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="relative group">
|
||||
{language && (
|
||||
<div className="absolute top-0 left-4 -translate-y-1/2">
|
||||
<span className="inline-block px-2 py-1 text-xs font-bold text-foreground/80 bg-[#282828] rounded">
|
||||
{language}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
<button
|
||||
onClick={handleCopy}
|
||||
className="absolute top-0 right-0 -translate-y-[50%] hidden group-hover:flex items-center gap-1 px-2 py-1 text-xs font-medium text-foreground/80 bg-[#282828] rounded hover:text-foreground transition-colors"
|
||||
aria-label="Copy code"
|
||||
>
|
||||
{copied ? (
|
||||
<>
|
||||
<Check size={14} />
|
||||
Copied!
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Copy size={14} />
|
||||
Copy
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
<pre className={className}>
|
||||
<code>{children}</code>
|
||||
</pre>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
188
src/src/components/mdx/command.tsx
Normal file
188
src/src/components/mdx/command.tsx
Normal file
@@ -0,0 +1,188 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Terminal, Copy, Check } from 'lucide-react';
|
||||
// Import all required icons from react-icons
|
||||
import { FaDebian, FaFedora } from 'react-icons/fa6';
|
||||
import { SiGentoo, SiNixos, SiArchlinux } from 'react-icons/si';
|
||||
|
||||
const Commands = ({
|
||||
commandId,
|
||||
description,
|
||||
archCommand,
|
||||
debianCommand,
|
||||
fedoraCommand,
|
||||
gentooCommand,
|
||||
nixCommand
|
||||
}) => {
|
||||
const [activeTab, setActiveTab] = useState('arch');
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
const distros = [
|
||||
{
|
||||
id: 'arch',
|
||||
name: 'Arch',
|
||||
icon: SiArchlinux,
|
||||
command: archCommand || 'echo "No command specified for Arch"'
|
||||
},
|
||||
{
|
||||
id: 'debian',
|
||||
name: 'Debian',
|
||||
icon: FaDebian,
|
||||
command: debianCommand || 'echo "No command specified for Debian"'
|
||||
},
|
||||
{
|
||||
id: 'fedora',
|
||||
name: 'Fedora',
|
||||
icon: FaFedora,
|
||||
command: fedoraCommand || 'echo "No command specified for Fedora"'
|
||||
},
|
||||
{
|
||||
id: 'gentoo',
|
||||
name: 'Gentoo',
|
||||
icon: SiGentoo,
|
||||
command: gentooCommand || 'echo "No command specified for Gentoo"'
|
||||
},
|
||||
{
|
||||
id: 'nix',
|
||||
name: 'NixOS',
|
||||
icon: SiNixos,
|
||||
command: nixCommand || 'echo "No command specified for NixOS"'
|
||||
}
|
||||
];
|
||||
|
||||
const copyToClipboard = (text) => {
|
||||
navigator.clipboard.writeText(text)
|
||||
.then(() => {
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Failed to copy: ', err);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full rounded-md overflow-hidden border border-foreground/20 bg-background my-4">
|
||||
{/* Header with Terminal Icon and Copy Button */}
|
||||
<div className="bg-background border-b border-foreground/20 text-foreground p-2 flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<Terminal size={20} className="mr-2 text-yellow-bright" />
|
||||
<div className="text-sm font-comic-code">
|
||||
{description || "Terminal Command"}
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => copyToClipboard(distros.find(d => d.id === activeTab).command)}
|
||||
className="bg-background hover:bg-foreground/10 text-foreground text-xs px-2 py-1 rounded flex items-center"
|
||||
>
|
||||
{copied ? (
|
||||
<>
|
||||
<Check size={14} className="mr-1 text-green-bright" />
|
||||
<span>Copied</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Copy size={14} className="mr-1 text-foreground/70" />
|
||||
<span>Copy</span>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Tabs */}
|
||||
<div className="flex flex-wrap border-b border-foreground/20 bg-background">
|
||||
{distros.map((distro) => {
|
||||
const IconComponent = distro.icon;
|
||||
|
||||
return (
|
||||
<button
|
||||
key={distro.id}
|
||||
className={`px-3 py-2 text-sm font-medium flex items-center ${
|
||||
activeTab === distro.id
|
||||
? 'bg-background border-b-2 border-blue-bright text-blue-bright'
|
||||
: 'text-foreground/80 hover:text-foreground hover:bg-foreground/5'
|
||||
}`}
|
||||
onClick={() => setActiveTab(distro.id)}
|
||||
>
|
||||
<span className="mr-1 inline-flex items-center">
|
||||
<IconComponent size={16} />
|
||||
</span>
|
||||
{distro.name}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Command Display with Horizontal Scrolling */}
|
||||
<div className="bg-[#282828] text-foreground p-3 overflow-x-auto">
|
||||
<div className="flex items-center font-comic-code text-sm whitespace-nowrap">
|
||||
<span className="text-orange-bright mr-2">$</span>
|
||||
<span className="text-purple-bright">
|
||||
{distros.find(d => d.id === activeTab).command}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Also include a simpler command component for single commands
|
||||
const Command = ({
|
||||
command,
|
||||
description,
|
||||
shell = "bash"
|
||||
}) => {
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
const copyToClipboard = () => {
|
||||
navigator.clipboard.writeText(command)
|
||||
.then(() => {
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Failed to copy: ', err);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full rounded-md overflow-hidden border border-foreground/20 bg-background my-4">
|
||||
{/* Header with Terminal Icon and Copy Button */}
|
||||
<div className="bg-background border-b border-foreground/20 text-foreground p-2 flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<Terminal size={20} className="mr-2 text-yellow-bright" />
|
||||
<div className="text-sm font-comic-code">
|
||||
{description || "Terminal Command"}
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
onClick={copyToClipboard}
|
||||
className="bg-background hover:bg-foreground/10 text-foreground text-xs px-2 py-1 rounded flex items-center"
|
||||
>
|
||||
{copied ? (
|
||||
<>
|
||||
<Check size={14} className="mr-1 text-green-bright" />
|
||||
<span>Copied</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Copy size={14} className="mr-1 text-foreground/70" />
|
||||
<span>Copy</span>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Command Display with Horizontal Scrolling */}
|
||||
<div className="bg-[#282828] text-foreground p-3 overflow-x-auto">
|
||||
<div className="flex items-center font-comic-code text-sm whitespace-nowrap">
|
||||
<span className="text-orange-bright mr-2">$</span>
|
||||
<span className="text-purple-bright">
|
||||
{command}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { Commands, Command };
|
||||
78
src/src/content/blog/thinkpad-t440p-coreboot-guide.mdx
Normal file
78
src/src/content/blog/thinkpad-t440p-coreboot-guide.mdx
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
title: Thinkpad T440p Coreboot Guide
|
||||
description: The definitive guide on corebooting a Thinkpad T440p
|
||||
author: Timothy Pidashev
|
||||
tags: [t440p, coreboot, thinkpad]
|
||||
date: 2025-01-15
|
||||
image: "/blog/thinkpad-t440p-coreboot-guide/thumbnail.png"
|
||||
---
|
||||
|
||||
import { Commands, Command } from "@/components/mdx/command";
|
||||
|
||||
> **Interactive Script Available!**
|
||||
> Want to skip the manual steps in this guide?
|
||||
> I've created an interactive script that can automate the entire process step by step as you follow along.
|
||||
> This script supports Arch, Debian, Fedora, Gentoo, and Nix!
|
||||
|
||||
<Command
|
||||
description="Interactive script"
|
||||
command="curl -fsSL https://timmypidashev.dev/scripts/run.sh | sh -s -- -t coreboot-t440p"
|
||||
client:load
|
||||
/>
|
||||
|
||||
## Getting Started
|
||||
The Thinkpad T440p is a powerful and versatile laptop that can be further enhanced by installing coreboot,
|
||||
an open-source BIOS replacement. This guide will walk you through the process of corebooting your T440p,
|
||||
including flashing the BIOS chip and installing the necessary software.
|
||||
|
||||
## What You'll Need
|
||||
|
||||
Before getting started corebooting your T440p, make sure you have the following:
|
||||
|
||||
- **Thinkpad T440p**: This guide is specifically for the T440p model.
|
||||
- **CH341A Programmer**: This is a USB device used to flash the BIOS chip.
|
||||
- **Screwdriver**: A torx screwdriver is needed to open the laptop.
|
||||
|
||||
## Installing Dependencies
|
||||
|
||||
Install the following programs. These will be needed to compile coreboot and flash the BIOS.
|
||||
|
||||
<Commands
|
||||
description="Install prerequisite packages"
|
||||
archCommand="sudo pacman -S base-devel curl git gcc-ada ncurses zlib nasm sharutils unzip flashrom"
|
||||
debianCommand="sudo apt install build-essential curl git gnat libncurses-dev zlib1g-dev nasm sharutils unzip flashrom"
|
||||
fedoraCommand="sudo dnf install @development-tools curl git gcc-gnat ncurses-devel zlib-devel nasm sharutils unzip flashrom"
|
||||
gentooCommand="sudo emerge --ask sys-devel/base-devel net-misc/curl dev-vcs/git sys-devel/gcc ncurses dev-libs/zlib dev-lang/nasm app-arch/sharutils app-arch/unzip sys-apps/flashrom"
|
||||
nixCommand="nix-env -i stdenv curl git gcc gnat ncurses zlib nasm sharutils unzip flashrom"
|
||||
client:load
|
||||
/>
|
||||
|
||||
## Disassembling the Laptop
|
||||
1. **Power off your laptop**: Make sure your T440p is completely powered off and unplugged from any power source.
|
||||
2. **Remove the battery**: Flip the laptop over and remove the battery by sliding the latch to the unlock position and lifting it out.
|
||||
3. **Unscrew the back panel**: Use a torx screwdriver to remove the screws securing the back panel.
|
||||
|
||||
## Locating the EEPROM Chips
|
||||
|
||||
In order to flash the laptop, you will need to have access to two EEPROM chips located next to the sodimm RAM.
|
||||
|
||||

|
||||
|
||||
## Assembling the SPI Flasher
|
||||
|
||||
Place the SPI flasher ribbon cable into the correct slot and make sure its the 3.3v variant
|
||||
|
||||

|
||||
|
||||
After the flasher is ready, connect it to your machine and ensure its ready to use:
|
||||
|
||||
<Command
|
||||
description="Ensure the CH341A flasher is being detected"
|
||||
command="flashrom --programmer ch341a_spi"
|
||||
/>
|
||||
|
||||
Flashrom should report that programmer initialization was a success.
|
||||
|
||||
## Extracting Original BIOS
|
||||
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
---
|
||||
title: Thinkpad T440p Coreboot Guide
|
||||
description: The definitive guide on corebooting a Thinkpad T440p
|
||||
author: Timothy Pidashev
|
||||
tags: [t440p, coreboot, thinkpad]
|
||||
date: 2025-01-15
|
||||
image: "/blog/thinkpad-t440p-coreboot-guide/thumbnail.png"
|
||||
---
|
||||
|
||||
> **Interactive Script Available!**
|
||||
> Want to skip the manual steps in this guide?
|
||||
> I've created an interactive script that can automate the entire process step by step as you follow along.
|
||||
> Simply run the following command in your terminal to get started:
|
||||
>
|
||||
> ```
|
||||
> curl -fsSL https://timmypidashev.dev/scripts/run.sh | sh -s -- -t coreboot-t440p
|
||||
> ```
|
||||
> NOTE: This script supports Arch, Debian, Fedora, Gentoo, and Nix linux distributions!
|
||||
|
||||
## Getting Started
|
||||
The Thinkpad T440p is a powerful and versatile laptop that can be further enhanced by installing coreboot,
|
||||
an open-source BIOS replacement. This guide will walk you through the process of corebooting your T440p,
|
||||
including flashing the BIOS chip and installing the necessary software.
|
||||
|
||||
## What You'll Need
|
||||
|
||||
Before getting started corebooting your T440p, make sure you have the following:
|
||||
|
||||
- **Thinkpad T440p**: This guide is specifically for the T440p model.
|
||||
- **CH341A Programmer**: This is a USB device used to flash the BIOS chip.
|
||||
- **Screwdriver**: A torx screwdriver is needed to open the laptop.
|
||||
|
||||
## Disassembling the Laptop
|
||||
1. **Power off your laptop**: Make sure your T440p is completely powered off and unplugged from any power source.
|
||||
2. **Remove the battery**: Flip the laptop over and remove the battery by sliding the latch to the unlock position and lifting it out.
|
||||
3. **Unscrew the back panel**: Use a torx screwdriver to remove the screws securing the back panel.
|
||||
|
||||
## Locating the EEPROM Chips
|
||||
Reference in New Issue
Block a user